在Windows中检测全屏模式

Detecting full screen mode in Windows

本文关键字:模式 检测 Windows      更新时间:2023-10-16

我需要检测某些应用程序当前是否在全屏模式下运行。如果是,那么我必须停止申请。那么,我该如何检测呢?p. Win32 c++

其他所有答案都相当粗俗。

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 Store应用程序正在运行。")
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
}

Hooch和ens的答案实际上不适用于多监视器系统。这是因为

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

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

下面是基于ens的回答的Java JNA实现:

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个元素相互比较。