如何检查我的窗口是否被隐藏/可见

How to check if my window gets hidden/visible?

本文关键字:是否 隐藏 可见 窗口 我的 何检查 检查      更新时间:2023-10-16

如果我在Windows7中按下"显示桌面"按钮,我的程序仍然会认为它没有最小化,如果我在程序聚焦时按下WIN+D,只有这样我的程序才会捕捉到这个最小化命令。如何检查我的程序是否可见?

这是我的主要循环:

while(!done){
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
        if(msg.message == WM_QUIT){
            done = TRUE;
        }else{
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }else if(active){
        render();
    }
}

第3版:这样好吗?看起来它在工作:

case WM_WINDOWPOSCHANGED:
{
        flags = ((PWINDOWPOS)lParam)->flags;
        if((flags & 0x8000) && (flags & SWP_NOCOPYBITS) && (flags & SWP_FRAMECHANGED)){
            active = !(flags & SWP_NOACTIVATE);
        }
        if((flags & 0x1000) && (flags & 0x0800) && (flags & SWP_NOMOVE) && (flags & SWP_NOSIZE)){
            active = 1;
        }
}
case WM_ACTIVATE:
{
    active = !HIWORD(wParam);
    return 0;
}

WM_ACTIVATE在另一个窗口变为活动时发送。当你说显示桌面时,没有其他窗口处于活动状态,所以从技术上讲,即使你的应用程序已最小化,它仍然处于活动状态。

您可能想要观看WM_WINDOWPOSCHANGED。您可以查看标志来查看它是什么类型的位置事件,也可以在窗口位置发生变化时检查IsIconic和IsWindowVisible。

根据您想要做的事情,有各种潜在的功能可以为您提供所需的信息:

  • GetForegroundWindow():获取用户当前正在使用的窗口。如果你只想在用户使用你的应用程序而不是另一个应用程序时绘制东西,你可以使用这个
  • GetActiveWindow():返回调用线程中的活动窗口,这可能不是您想要的。如果您希望根据自己的应用程序中处于活动状态的窗口启用/禁用绘图,这可能会很有用
  • GetFocus():返回调用线程中具有当前键盘焦点的窗口。可能不是您想要的,请改用GetForegorundWindow()
  • IsWindowVisible():返回窗口的显示/隐藏标志是否设置为可见。这实际上并不能告诉你窗口在屏幕上是否真的可见
  • GetTopWindow():告诉z顺序中最高的窗口,但不知道它是否真的有焦点/前景。你的窗口可能是聚焦/激活/前景的,但没有最高的z阶(我认为无论如何)

然而,从你的评论中,你似乎真的想看看屏幕上是否至少有一个像素可以看到你的窗口。为此,我可能会使用这个SO问题中提到的技术,使用名称奇怪的GetRandomRgn(),尽管更简单的检查可能是使用GetClipBox()并检查NULLREGION的返回代码。

对于Windows 8/10,还有另一个独立于IsWindowVisible的窗口可见性标志。检查DwmGetWindowAttribute和DWMWA_CLOAKED属性。

此外,窗口可以是半透明的,GetLayeredWindowAttributes可以告诉您窗口的alpha级别

IsWindowVisible告诉您的窗口是否可见。GetTopWindow告诉它是否是Z顺序中最上面的一个。

尝试WM_ACTIVATEAPP。

如果来自任何其他应用程序的窗口正在获得焦点,wParam将为false。这包括按下"显示桌面"按钮。