【问题标题】:How to detect if SetForegroundWindow changes screen resolution?如何检测 SetForegroundWindow 是否更改屏幕分辨率?
【发布时间】:2017-08-18 14:09:23
【问题描述】:

我正在用 C# 编写 Alt+Tab 替换,但在全屏应用程序中遇到了问题。

有没有办法检测SetForegroundWindow(hWnd) 调用是否会改变屏幕分辨率?或者等效地,如果hWnd 是全屏应用程序?我想等到分辨率更改完成,或者如果没有更改,请立即进行。

屏幕分辨率更改是异步完成的,函数调用在它发生之前就返回了,所以我的代码过早运行,并将我的应用程序绘制到全屏应用程序的表面上,尺寸错误,然后在分辨率更改后,它看起来特别丑。

如果有人感兴趣,我的申请来源是https://bitbucket.org/FrigoCoder/frigotab/src

为了澄清,我更感兴趣的是事先知道分辨率是否发生变化,而不是稍后检测它。我已经知道了一个半解决方案,我在GetDesktopWindow() 或其他窗口上调用SetForegroundWindow() 并观看SystemEvents.DisplaySettingsChangingDisplaySettingsChanged。但是,如果发生分辨率更改,这只会给我一个延迟的异步通知,并且不会告诉我是否没有。

【问题讨论】:

  • 您正在尝试解决错误的问题。只需在一个地方处理分辨率更改,一切都会好起来的。当分辨率改变时,只需重新绘制您的 UI。无需任何黑客攻击。

标签: c# winapi resolution alt-tab setforegroundwindow


【解决方案1】:

我设法解决了这个问题。我没有尝试检测全屏应用程序,而是简单地将停用消息发送到前台应用程序,这会触发早期分辨率更改:

SendMessage(GetForegroundWindow(), WM_ACTIVATEAPP, false, GetCurrentThreadId());

在应用程序切换期间也会发送完全相同的消息,因此我基本上在它实际发生之前模拟一个消息。我还没有遇到任何副作用。

但请注意,这可以解决 DWM 问题。 Windows 7 会自动禁用 DWM 合成以进行兼容性启动,或者当它检测到对主显示表面的直接访问时。它不允许您重新启用,而且我没有看到解决此问题的简单方法。值得庆幸的是,这个问题最终会消失,因为 DWM 组合始终在 Windows 8 和更高版本中启用。

【讨论】:

    【解决方案2】:

    也许 Winforms 事件 SizeChanged 可以帮助你。

    您可以将此事件用作其余代码的某种延续。如果事件由于没有调整大小而没有触发,您可以有一个辅助延续,它将在指定的超时后运行。它并不完美,但可以满足您的需求。

    【讨论】:

    • 我认为 OP 想知道分辨率是否改变,他实际执行 alt+tab
    • 为我的问题添加了更多细节。基本上是的,我想事先知道以获得最佳效果。我已经有一种以后检测分辨率变化的原始方法,但没有立即给我答案,如果没有分辨率变化,根本不给我答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2011-01-15
    相关资源
    最近更新 更多