在 Windows 10 上处理 DPI(文本大小)的运行时更改
Handle runtime change of DPI (text size) on Windows 10
在 Windows10 上,系统不再需要重新启动 (logoff/logon) 来更改 DPI(文本大小)。
我的应用程序还没有准备好进行这样的运行时更改。
系统如何通知应用程序 DPI 正在更改?我应该处理什么消息?
我正在使用 C++ Builder,所以我正在寻找一个纯 WinAPI 解决方案,没有 WinForms。
作为@TLama 和@DalijaPrasnikar commented, the message to handle is WM_DPICHANGED
。
#define WM_DPICHANGED 0x02E0
该消息自 Windows 8.1 起可用,当 window 移动到具有不同 DPI 的另一台显示器时,它被发送到 window。
在 Windows 10 上,从 API 的角度来看,DPI 的运行时更改与将 window 移动到具有不同 DPI 的不同显示器相同(当然除了在这种情况下 window 保持在同一台显示器上)。
甚至要接收消息(即使在 Windows 10 上运行时 DPI 更改),应用程序需要声明对每个监视器 DPI 的支持。首选方法是通过将 dpiAwareness
设置为 PerMonitorV2
(以及附加的 PerMonitor
值并将 dpiAware
设置为 True/PM
以向后兼容旧版本来 declare the support in an application manifest Windows 10 个构建和 Windows 8.1):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
...
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
当应用程序声明每个显示器的 DPI 支持时,系统不会在 DPI 运行时更改时按像素缩放其 windows。然后由应用程序本地扩展其 windows。
从 C++ Builder 10.3 开始,您可以使用这些表单事件:
- OnAfterMonitorDpiChanged
- OnBeforeMonitorDpiChanged
当然你还需要在项目设置的application manifest中将DPI Awareness设置为PerMonitorV2
在 Windows10 上,系统不再需要重新启动 (logoff/logon) 来更改 DPI(文本大小)。
我的应用程序还没有准备好进行这样的运行时更改。
系统如何通知应用程序 DPI 正在更改?我应该处理什么消息?
我正在使用 C++ Builder,所以我正在寻找一个纯 WinAPI 解决方案,没有 WinForms。
作为@TLama 和@DalijaPrasnikar commented, the message to handle is WM_DPICHANGED
。
#define WM_DPICHANGED 0x02E0
该消息自 Windows 8.1 起可用,当 window 移动到具有不同 DPI 的另一台显示器时,它被发送到 window。
在 Windows 10 上,从 API 的角度来看,DPI 的运行时更改与将 window 移动到具有不同 DPI 的不同显示器相同(当然除了在这种情况下 window 保持在同一台显示器上)。
甚至要接收消息(即使在 Windows 10 上运行时 DPI 更改),应用程序需要声明对每个监视器 DPI 的支持。首选方法是通过将 dpiAwareness
设置为 PerMonitorV2
(以及附加的 PerMonitor
值并将 dpiAware
设置为 True/PM
以向后兼容旧版本来 declare the support in an application manifest Windows 10 个构建和 Windows 8.1):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
...
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
当应用程序声明每个显示器的 DPI 支持时,系统不会在 DPI 运行时更改时按像素缩放其 windows。然后由应用程序本地扩展其 windows。
从 C++ Builder 10.3 开始,您可以使用这些表单事件:
- OnAfterMonitorDpiChanged
- OnBeforeMonitorDpiChanged
当然你还需要在项目设置的application manifest中将DPI Awareness设置为PerMonitorV2