Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32)
本文将介绍 Windows 系统中高 DPI 开发的基础知识。由于涉及到坐标转换,这种转换经常发生在计算的不知不觉中;所以无论你使用哪种 Windows 下的 UI 框架进行开发,你都需要了解这些内容,以免不断踩坑。
本文内容
- 各种不同的 Windows 桌面 UI 框架
- 对普通用户而言的 DPI 级别
- 对 Windows 应用而言的 DPI 感知级别(Dpi Awareness)
- 不同 UI 框架对 DPI 的支持情况
- UWP
- WPF
- Windows Forms
- 其他 UI 框架
- 混合 DPI 感知级别
- DPI 相关的 Windows API 的迁移
- 参考资料
CreateDialog)
在 Windows 10 19H1 中(对现在来说还是预览版),可以直接在任务管理器中查看到进程的 DPI Awareness:
▲ 在任务管理器中查看 DPI Awareness
方法是在任务管理器中 Details 的标题栏右键,选择列,然后找到 DPI Awareness。
可以看到,目前仅文件资源管理器是 Per-Monitor V2 的。
SetThreadDpiAwarenessContext 函数可以让创建的这个窗口具有单独的 DPI 感知级别。前一次是为了让窗口在创建时有一个对此线程的新的 DPI 感知级别,而后一次调用是恢复此线程的 DPI 感知级别。
关于混合 DPI 感知级别的其他内容,可以阅读官网:Mixed-Mode DPI Scaling and DPI-aware APIs - Microsoft Docs。
微软的 Office 系列就是典型的使用了混合 DPI 感知级别的应用。在以下实验中,我组成了一个 96 DPI 的主屏和 144 DPI 的副屏,先在 96 DPI 的屏幕上截一张图,再将窗口移动到 144 DPI 的屏幕中再截一张图。
Microsoft PowerPoint 使用的是系统 DPI 感知级别:
▲ 96 DPI 下的主界面
▲ 144 DPI 下的主界面
你可以通过点开图片查看原图来比较这两幅图在原图尺寸下的模糊程度。
Microsoft PowerPoint 的演示页面使用的是屏幕 DPI 感知级别:
▲ 96 DPI 下的演示页面
▲ 144 DPI 下的演示页面
可以看到,演示页面在多屏 DPI 下是没有产生缩放的模糊,即采用了屏幕 DPI 感知级别。
而以上的主界面和演示页面属于同一个进程。
▲ 只有一个 PowerPoint 进程