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

时间:2011-06-07 15:24:34

标签: c++ visual-studio-2008 winapi opengl

如果我按下Windows7中的“显示桌面”按钮,我的程序仍会认为它没有最小化,如果我在我的程序聚焦时按WIN+D,那么我的程序才会捕获此最小化命令。如何检查100%确定我的程序是否可见?

这是我的主循环:

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;
}

5 个答案:

答案 0 :(得分:4)

当另一个窗口变为活动状态时发送WM_ACTIVATE。当您说show desktop时,没有其他窗口变为活动状态,因此从技术上讲,即使已将应用程序最小化,您的应用仍处于活动状态。

您可能想要关注WM_WINDOWPOSCHANGED。您可以查看标记以查看它的位置事件类型,也可以在窗口位置发生变化时检查IsIconicIsWindowVisible

答案 1 :(得分:2)

根据您的具体操作,有多种潜在的功能可以为您提供所需的信息:

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

但是,从您的评论中,您似乎确实想要查看屏幕上是否至少有一个窗口像素可见。为此我可能会使用this SO question中提到的技术使用奇怪命名的GetRandomRgn(),尽管更简单的检查可能是使用GetClipBox()并检查NULLREGION的返回码。 / p>

答案 2 :(得分:0)

IsWindowVisible会告诉您窗口是否可见。 GetTopWindow告诉你它是否是Z顺序中最重要的一个。

答案 3 :(得分:0)

尝试WM_ACTIVATEAPP。

如果来自任何其他应用的窗口正在获得焦点,则

wParam将为false。这包括按“显示桌面”按钮。

答案 4 :(得分:0)

在Windows 8/10中,还有一个窗口可见性标志,与IsWindowVisible分开。检查DwmGetWindowAttribute和DWMWA_CLOAKED属性。

此外,窗口可以是半透明的,并且GetLayeredWindowAttributes可以告诉您窗口的alpha级别是什么。