支持 Windows 10 最新 PerMonitorV2 特性的 WPF 多屏高 DPI 应用开发
Windows 10 自 1703 开始引入第二代的多屏 DPI 机制(PerMonitor V2),而 WPF 框架可以支持此第二代的多屏 DPI 机制。
本文将介绍 WPF 框架利用第二代多屏 DPI 机制进行高 DPI 适配的方法。同时,也介绍低版本的 WPF 或者低版本的操作系统下如何做兼容。
本文内容
- 添加应用程序清单文件
- 如果你没有 app.config,如何添加?
- 如果你没有 app.manifest,如何添加?
- 了解 WPF 清单文件中的 DPI 感知设置
- DpiAware
- DpiAwareness
- 使 WPF 程序支持 Per-Monitor V2 级 DPI 感知
- WPF 程序在特殊清单设置下的效果
- 低版本 .NET Framework 和 低版本 Windows 下的 WPF DPI 缩放
- 参考资料
SetProcessDpiAwareness 或 SetProcessDPIAware 函数,那么就会按照调用此函数的效果来感知 DPI。
true
字符串
- 当前进程设置为系统级 DPI 感知(System DPI Awareness)。
false
字符串
- 在 Windows Vista / 7 / 8 中,与什么都不填的效果是一样的。
- 在 Windows 8.1 / 10 中,当前进程设置为不感知 DPI(Unaware),就算你调用了 SetProcessDpiAwareness 和 SetProcessDPIAware 也是没有用的。
true/pm
字符串
- 在 Windows Vista / 7 / 8 中,当前进程设置为系统级 DPI 感知(System DPI Awareness)。
- 在 Windows 8.1 / 10 中,当前进程设置为屏幕级 DPI 感知(Per-Monitor DPI Awareness)。
per monitor
字符串
- 在 Windows Vista / 7 / 8 中,与什么都不填的效果是一样的。
- 在 Windows 8.1 / 10 中,当前进程设置为屏幕级 DPI 感知(Per-Monitor DPI Awareness)。
- 在 Windows Vista / 7 / 8 中,与什么都不填的效果是一样的。
- 在 Windows 8.1 / 10 中,当前进程设置为不感知 DPI(Unaware),就算你调用了 SetProcessDpiAwareness 和 SetProcessDPIAware 也是没有用的。
说明一下,SetProcessDpiAwareness 是新 API,要求的最低系统版本是 Windows 8.1,调用这个才能指定为 Per-Monitor 的 DPI 感知。而 SetProcessDPIAware 是 Vista 开始引入的老 API,没有参数可以传。
SetProcessDpiAwareness 或 SetProcessDPIAware 函数,那么就会按照调用此函数的效果来感知 DPI。
system
- 当前进程设置为系统级 DPI 感知(System DPI Awareness)。
permonitor
- 当前进程设置为屏幕级 DPI 感知(Per-Monitor DPI Awareness)。
permonitorv2
- 当前进程设置为第二代屏幕级 DPI 感知(Per-Monitor V2 DPI Awareness)。
- 仅在 Windows 10 (1703) 及以上版本才可被识别
unaware
- 当前进程设置为不感知 DPI(Unaware),就算你调用了 SetProcessDpiAwareness 和 SetProcessDPIAware 也是没有用的。
Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32) - walterlv
额外的,如果你的 .NET Framework 版本在 .NET Framework 4.6.2 以下,但操作系统在 Windows 10 及以上,你还需要修改 App.config 文件(在
节点)。
<runtime>
runtime>
注意:
- 这个值要设为
false
。(微软官方吐槽:Yes, set it to false. Double negative FTW!) AppContextSwitchOverrides
不能被设置两次,如果一已经设置了其他值,需要用分号分隔多个值。
特别说明,当面向 .NET Framework 4.6.2 以下版本编译,但运行于 Windows 10 (1607) 和以上版本时,只需要添加 Switch.System.Windows.DoNotScaleForDpiChanges=false
即可让 WPF 程序处理 Dpi Change 消息,此时 WPF 程序就像高版本的 .NET Framework 中一样能够正常处理多屏下的 DPI 缩放。
以上,划重点 你并不需要编译为高版本的 .NET Framework 即可获得 Per-Monitor 的 DPI 缩放支持。