如何在不处理DPI的运行时更改时重置应用程序的兼容模式?

时间:2015-07-29 16:00:11

标签: delphi winapi c++builder dpi windows-10

这是Handle runtime change of DPI (text size) on Windows 10

的后续问题

Windows 10允许运行时更改DPI,而无需重新启动(登录/注销)系统。当DPI更改,并且系统检测到应用程序无法处理运行时DPI更改时,它会逐像素地缩放应用程序窗口。与以前版本的Windows中的兼容性行为类似。除了在这种情况下,系统甚至可以缩小,而不仅仅是向上。

奇怪的是,应用程序重启不会有帮助。系统似乎记得应用程序没有正确响应缩放的变化,并且仍然像以前一样(应用程序认为缩放没有改变,系统按像素缩放窗口)。只有系统登录/注销才能帮助重置为正确的缩放。

有没有办法以编程方式重置兼容模式,允许用户只重启应用程序,而不是整个系统? (这是完全支持运行时DPI更改的第一步)

我正在使用C ++ Builder,所以我正在寻找纯WinAPI解决方案,而不是WinForms。

1 个答案:

答案 0 :(得分:2)

原来,问题不是由于应用程序没有响应DPI更改而引起的。如果应用程序在DPI发生变化时运行,它实际上并不重要。

根本原因是在Windows会话期间更改DPI时,只有每个监视器DPI发生更改(即使在单个监视器系统上)。系统(传统)DPI未更新。

因此,当您运行应用程序时,它不会声明每个监视器DPI感知,并且依赖于系统DPI,它就像DPI没有更改一样运行。但是系统将其窗口按像素顺序缩放到新的DPI。

仅在注销/登录后,系统DPI与显示器DPI对齐。

通过将SELECT ti.tester_name, MAX(ti.last_checked) FROM New_OTPMS.TBL_TESTER_ONLINE_INFO ti INNER JOIN TBL_TESTER_LIST tl ON ti.tester_name = tl.tester_name WHERE ti.board_name = 'DC30' AND tl.tester_type = 'UFLEX' GROUP BY ti.tester_name ORDER BY ti.tester_name 设置为dpiAwareness(以及其他PerMonitorV2值并将PerMonitor设置为dpiAware以获得向后兼容性,解决方案是declare the support in an application manifest使用较旧的Windows 10版本和Windows 8.1):

True/PM

必须重新实现应用程序窗口缩放以使用新的GetDpiForMonitor WinAPI函数而不是旧版GetDeviceCaps(DC, LOGPIXELSX/LOGPIXELSY)