如何检测外部进程是否处于游戏常用的exclusive fullscreen mode?
检测外部进程独占全屏模式的方法
嘿,这个问题确实戳中了很多人容易混淆的点——独占全屏(exclusive fullscreen)和无边框窗口化全屏完全是两套机制,检测起来得绕开普通窗口的判断逻辑,从系统底层的显示控制入手。我结合Windows平台(绝大多数游戏的主战场)的实战经验,给你几个靠谱的方向:
核心思路:抓住独占全屏的本质
独占全屏模式下,游戏会直接接管显卡的显示输出,绕开Windows桌面窗口管理器(DWM)的渲染框架。所以我们的检测逻辑要围绕“DWM是否被绕过”“显示输出是否被独占”这两个核心点展开。
1. 结合窗口状态与DWM属性判断
- 第一步,先获取目标进程的主窗口句柄(可以通过
CreateToolhelp32Snapshot枚举进程,再用EnumWindows匹配进程ID得到窗口句柄)。 - 调用
GetWindowPlacement获取窗口的显示状态,如果showCmd是SW_SHOWMAXIMIZED,这是基础条件,但还不够。 - 关键一步:用
DwmGetWindowAttribute函数查询窗口的DWMWA_CLOAKED属性。如果返回值包含DWM_CLOAKED_SHELL或DWM_CLOAKED_INVISIBLE,说明该窗口被DWM隐藏了——这是独占全屏的典型特征,因为此时DWM会暂时停止工作,让游戏直接控制显示。
2. 检测显示模式的独占性变化
- 独占全屏游戏通常会切换显卡的显示分辨率、刷新率,退出时再恢复。你可以用
EnumDisplaySettings获取当前显示模式,对比目标进程启动前后的参数变化。 - 更精准的方法是调用
QueryDisplayConfig获取当前显示配置,检查是否有进程独占了显示输出。另外,OpenDisplay配合GetDisplayModeList也能帮你判断当前是否处于独占模式(独占模式下,可用的显示模式列表会被限制为游戏指定的参数)。
3. 利用Windows游戏专属API
- 对于现代游戏,Windows提供了
IGameMonitor接口(属于Xbox Game Bar的底层组件),可以直接查询进程是否处于独占全屏状态。不过这个接口需要你链接gameux.dll,并处理COM对象的初始化逻辑,适合需要更官方支持的场景。
避坑提醒
- 检测程序需要以管理员身份运行,否则可能无法读取其他进程的窗口信息和系统显示配置。
- 老游戏可能使用DirectDraw的独占模式,这时候需要结合
DirectDrawCreateEx创建显示表面,再通过IDirectDrawSurface::GetCaps检查是否处于独占状态。 - 别把普通的最大化窗口误判成独占全屏!一定要结合DWM状态或显示模式变化做综合判断,避免误报。
内容的提问来源于stack exchange,提问作者user6516781
相关产品推荐
相关产品推荐

