在Windows中检测全屏模式
Detecting full screen mode in Windows
我需要检测某些应用程序当前是否在全屏模式下运行。如果是,那么我必须停止申请。那么,我该如何检测呢?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个元素相互比较。
相关文章:
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 使用CMake检测支持的C++标准
- 为什么在保护模式下继承升级不起作用
- 当套接字连接断开时检测C/C++Unix
- 如何在全屏模式下(在OpenGL中)使背景透明
- C/C++预处理器是否可以检测一些编译器选项
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- WMI检测进程创建事件-c++
- 如何检测窗口当前是否正在运行模式对话框?
- 检测与SFINAE的协同依赖功能的模式
- 如何检测Windows服务中的睡眠模式唤醒
- 在读/写/附加模式下打开QFile后,我能检测到它是否存在吗
- 在发布模式下检测到缓冲区溢出 - linux
- 为引用计数的智能指针检测内存泄漏的设计模式
- 使用本地二进制模式进行对象跟踪:更改检测ROI的大小
- 检测视窗 8 中的分屏模式
- 在成功运行10小时后,在发布模式下从windows应用程序中获得异常,如何检测出问题
- 用于混合模式项目的内存泄漏检测:托管、非托管和本机
- 在Windows中检测全屏模式
- 如何在图像处理中提取模式识别算法中的特定特征以进行对象检测