win32(全屏)无边框窗口重叠任务栏

时间:2013-03-06 17:30:45

标签: c++ windows winapi windows-8

我正在尝试创建一个无边界窗口,可能会全屏覆盖任务栏(不使用ChangeDisplaySettings(&settings, CDS_FULLSCREEN);),我无法弄清楚如何做到这一点。我已经尝试了几乎所有可能的CreateWindowEx样式组合,但没有成功。

它的目的是使用opengl / directx在窗口无边界应用程序中渲染,同时允许在后台继续渲染时进行alt-tabbing。这是通过许多游戏完成的,例如wow和dota2(windowed fullscreen选项)以及诸如windows7任务管理器之类的应用程序(在vm中用两个截图来证明这个想法)(windows8没有这种行为) )。

任务经理没有集中注意力:

任务经理专注:

这是我用来轻松测试我的一些想法的一些最小代码,但没有一个真正完成它。它只创建一个大小为screenwidth-20和screenheight-20的无边框窗口。

#include <windows.h>

static bool quit = false;

static LRESULT CALLBACK message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
    switch(umsg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        case WM_CLOSE:
            quit = true;
        break;
    }

    return DefWindowProc(hwnd, umsg, wparam, lparam);
}

int main()
{
    WNDCLASSEX wc;
    HMODULE hInstance;
    HWND hwnd;
    MSG msg;

    ZeroMemory(&msg, sizeof(MSG));
    hInstance = GetModuleHandle(NULL);

    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc      = message_handler;
    wc.cbClsExtra       = 0;
    wc.cbWndExtra       = 0;
    wc.hInstance        = hInstance;
    wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);
    wc.hIconSm          = wc.hIcon;
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground    = (HBRUSH)COLOR_WINDOWFRAME;
    wc.lpszMenuName     = NULL;
    wc.lpszClassName    = "test";
    wc.cbSize           = (unsigned int)sizeof(WNDCLASSEX);

    RegisterClassEx(&wc);

    hwnd = CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 10, 10, (int)GetSystemMetrics(SM_CXSCREEN)-20, (int)GetSystemMetrics(SM_CYSCREEN)-20, NULL, NULL, hInstance, NULL);
    //hwnd = CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 0, 0, (int)GetSystemMetrics(SM_CXSCREEN), (int)GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, SW_SHOW);
    SetForegroundWindow(hwnd);
    SetFocus(hwnd);

    while (!quit)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return 0;
}

使用

CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 0, 0, (int)GetSystemMetrics(SM_CXSCREEN), (int)GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

与任务栏重叠,但当opengl渲染时它有一些奇怪的行为(闪烁/闪烁屏幕,例如当视频模式改变时。某些库的某个on this forum会遇到相同的效果制作跨平台窗口用于渲染和其他东西。有人也发布了那个线程a video (careful, loud music),它显示了我正在努力实现的目标。

我已经下载了这个开源库,并试图找出正在做的事情,但我找不到任何关于它创建窗口的方式有什么特别之处。

在Windows8上使用g++ (Built by MinGW-builds project) 4.8.0 20121225 (experimental)

2 个答案:

答案 0 :(得分:9)

Raymond Chen explained how to switch in and out of full screen mode只需使用SetWindowLong(Ptr)更改窗口样式,使用SetWindowPlacement调整窗口大小,然后SetWindowPos确保重绘框架。

任务栏检测窗口何时尝试全屏并自动退出。

答案 1 :(得分:3)

使用SetWindowPos function将窗口设置为TOPMOST。当您收到一条消息称您丢失了焦点时,请将其置于非最顶层,以便显示您切换到的其他窗口。