在Windows中检测全屏模式

17

我需要检测某个应用程序是否正在全屏模式下运行。如果是,则我必须停止我的应用程序。那么,如何检测呢? p.s. Win32 C++

5个回答

21

所有其他答案都相当繁琐。

Windows Vista、Windows 7及更高版本支持SHQueryUserNotificationState()

QUERY_USER_NOTIFICATION_STATE pquns;
SHQueryUserNotificationState(&pquns);

从这个“通知状态”,可以推断出全屏状态。基本上,当有一个应用在全屏模式下运行时,Windows会报告一个“繁忙”的通知状态。

  • QUNS_NOT_PRESENT - 不是全屏(机器锁定/屏幕保护程序/用户切换等情况)
  • QUNS_BUSY – 全屏(F11全屏,以及我尝试过的所有视频游戏都使用此选项)
  • QUNS_RUNNING_D3D_FULL_SCREEN – 全屏(Direct3D应用程序正在以独占模式运行,即全屏)
  • QUNS_PRESENTATION_MODE – 全屏(用于显示演示文稿的特殊模式,全屏显示)
  • QUNS_ACCEPTS_NOTIFICATIONS – 不是全屏
  • QUNS_QUIET_TIME – 不是全屏
  • QUNS_APP – 可能是全屏(不确定:“在Windows 8中引入。正在运行Windows商店应用程序。”

1
实际上,这应该是被接受的答案。 - Ming Tong
这是正确的答案,也是最快捷的方法。对于windowHandle检查用户是否可以自动隐藏任务栏。此函数提供全屏信息的完整状态。 - Doger

11
hWnd = GetForegroundWindow();
RECT appBounds;
RECT rc;
GetWindowRect(GetDesktopWindow(), &rc);

然后检查那个窗口不是桌面或者 shell。 简单的 if 语句。

if(hWnd =! GetDesktopWindow() && hWnd != GetShellWindow())
{
    GetWindowRect(hWnd, &appBounds);
    // Now you just have to compare rc to appBounds
}

这是未经测试的编写。


7
Hooch和ens的答案实际上不适用于多监视器系统。这是因为通过GetWindowRect或GetClientRect返回的桌面窗口矩形始终等于主监视器的矩形,以与现有应用程序兼容。参考https://learn.microsoft.com/en-us/windows/desktop/gdi/multiple-monitor-system-metrics
以上意味着,如果窗口在非系统主监视器上全屏显示,则相对于虚拟屏幕的坐标与桌面窗口的坐标完全不同。
我使用以下函数解决了这个问题:
bool isFullscreen(HWND windowHandle)
{
    MONITORINFO monitorInfo = { 0 };
    monitorInfo.cbSize = sizeof(MONITORINFO);
    GetMonitorInfo(MonitorFromWindow(windowHandle, MONITOR_DEFAULTTOPRIMARY), &monitorInfo);

    RECT windowRect;
    GetWindowRect(windowHandle, &windowRect);

    return windowRect.left == monitorInfo.rcMonitor.left
        && windowRect.right == monitorInfo.rcMonitor.right
        && windowRect.top == monitorInfo.rcMonitor.top
        && windowRect.bottom == monitorInfo.rcMonitor.bottom;
}

5

完整实现Hooch的答案:

bool isFullscreen(HWND window)
{
    RECT a, b;
    GetWindowRect(window, &a);
    GetWindowRect(GetDesktopWindow(), &b);
    return (a.left   == b.left  &&
            a.top    == b.top   &&
            a.right  == b.right &&
            a.bottom == b.bottom);
}

0

这里还有一个基于ens的答案实现的JavaJNA:

public static boolean isFullScreen()
{
    WinDef.HWND foregroundWindow = GetForegroundWindow();
    WinDef.RECT foregroundRectangle = new WinDef.RECT();
    WinDef.RECT desktopWindowRectangle = new WinDef.RECT();
    User32.INSTANCE.GetWindowRect(foregroundWindow, foregroundRectangle);
    WinDef.HWND desktopWindow = User32.INSTANCE.GetDesktopWindow();
    User32.INSTANCE.GetWindowRect(desktopWindow, desktopWindowRectangle);
    return foregroundRectangle.toString().equals(desktopWindowRectangle.toString());
}

请注意底部的toString()比较是一个小技巧,可以避免相互比较4个元素。

WinDef.HWND foregroundWindow = User32.INSTANCE.GetForegroundWindow(); 对于 JNA 5.5 - UzumakiL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接