7

我正在尝试创建一个无边框窗口,它可能在全屏(不使用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在其上渲染时它有一些奇怪的行为(闪烁/闪烁屏幕,例如当视频模式改变时。这个论坛上的某个人遇到了相同的效果,该库的某种库可以为跨平台窗口制作渲染和其他东西。有人还在该线程中发布了一个视频(小心,响亮的音乐),它准确地显示了我想要实现的目标)。

我已经下载了那个开源库并试图弄清楚它在做什么,但我找不到任何关于它创建窗口的方式的特别之处。

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

4

2 回答 2

9

Raymond Chen解释了如何切换全屏模式,而不是简单地通过使用SetWindowLong(Ptr)更改窗口样式,使用SetWindowPlacement调整窗口大小,并使用SetWindowPos确保框架重绘。

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

于 2013-03-06T18:32:25.350 回答
4

使用该SetWindowPos功能设置您的窗口TOPMOST。当您收到一条消息说您失去焦点时,请再次将其设为非最顶部,以便您切换到的另一个窗口可以出现。

于 2013-03-06T17:49:58.377 回答