【问题标题】:win32 (fullscreen) borderless window overlapping taskbarwin32(全屏)无边框窗口重叠任务栏
【发布时间】:2013-03-06 17:30:44
【问题描述】:

我正在尝试创建一个无边框窗口,该窗口可能在全屏模式下与任务栏重叠(不使用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)

【问题讨论】:

  • 我看到你试图编辑我的答案,我很感激你试图做的事情。显示最终有效的常用方法是将其编辑到您的问题中。
  • @MarkRansom 我明白了,感谢您让我知道。当我做所有这些时,新的答案突然出现了,在我决定使用哪一个之前,我会先尝试一下SetWindowPlacement 的想法。
  • 如果您觉得需要更改您选择的答案,我不会亲自处理。

标签: c++ windows winapi windows-8


【解决方案1】:

Raymond Chen explained how to switch in and out of full screen mode 很简单,用SetWindowLong(Ptr) 改变窗口样式,用SetWindowPlacement 调整窗口大小,用SetWindowPos 确保框架重绘。

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

【讨论】:

  • 关于任务栏行为的有趣部分,我认为您需要在最上面才能掌握它。
【解决方案2】:

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

【讨论】:

  • 马克,你能评论一下哪条消息会说它失去了焦点吗?谢谢! (我刚刚遇到了同样的问题。)
  • @bodacydo 试试WM_KILLFOCUS.
猜你喜欢
  • 2011-11-08
  • 1970-01-01
  • 2011-01-23
  • 2012-03-15
  • 1970-01-01
  • 2012-09-30
  • 2021-12-27
  • 1970-01-01
相关资源
最近更新 更多