WindowsDPI适配 学习笔记

时间:2024-04-08 16:05:32

Google上看到大多数人设置DPI缩放的时候,用的是 SetProcessDPIAware 这个函数,但是,MSDN上说:

SetProcessDPIAware is available for use in the operating systems
specified in the Requirements section. It may be altered or
unavailable in subsequent versions. Instead, use
SetProcessDpiAwareness.

所以我最终没有用 SetProcessDPIAware ,我决定,跟上次配置 libcurl with openssl 一样,跟着官方文档走,自己动手,丰衣足食!

语言就用易语言吧,界面好写(没人会吐槽我吧hhh我易语言已经炉火纯青了)

函数原型抽象成易语言的,就是 int SetProcessDpiAwareness(int value)
WindowsDPI适配 学习笔记

新建一个子程序,名叫SetDpiAwareness,里面就一句话:

SetProcessDpiAwareness (#PROCESS_PER_MONITOR_DPI_AWARE)
WindowsDPI适配 学习笔记
SetProcessDpiAwareness 这个函数的作用是告诉系统,这个程序要用哪一种DPI缩放模式:

PROCESS_DPI_UNAWARE DPI unaware. This app does not scale for DPI
changes and is always assumed to have a scale factor of 100% (96 DPI).
It will be automatically scaled by the system on any other DPI
setting.

PROCESS_SYSTEM_DPI_AWARE System DPI aware. This app does not scale for
DPI changes. It will query for the DPI once and use that value for the
lifetime of the app. If the DPI changes, the app will not adjust to
the new DPI value. It will be automatically scaled up or down by the
system when the DPI changes from the system value.

PROCESS_PER_MONITOR_DPI_AWARE Per monitor DPI aware. This app checks
for the DPI when it is created and adjusts the scale factor whenever
the DPI changes. These applications are not automatically scaled by
the system.

我在这里使用了 PROCESS_PER_MONITOR_DPI_AWARE

好了,设置好缩放模式,运行一下程序,发现现在窗口尺寸贼jb小

为什么呢?

因为你设置 PROCESS_PER_MONITOR_DPI_AWARE 之后,

These applications are not automatically scaled by the system.

操作系统不会自动帮你 scale 了!

所以我们接下来要自己进行 scale 的操作

.
.

思路是大致是:

获取当前显示器DPI -> 窗口尺寸 × DPI -> 渲染窗口

问题来了,怎么获取当前显示器的DPI??

有人用 GetDpiForMonitor ,有人用 GetDeviceCaps

我最后选择使用 GetDpiForMonitor (因为我感觉GetDeviceCaps不好用)

查了一下 MSDN 上的函数原型,写出易语言中的原型
WindowsDPI适配 学习笔记

(需要注意的一点是,GetDpiForMonitor 这个函数虽然好用,但是需要操作系统为 Windows8.1或 WindowsServer 2012R2 及更高版本才能支持,而 GetDeviceCaps 只要保证操作系统是Windows 2000及更高版本就好了。)

然后我发现第一个 hmonitor 参数我不能瞎jb传一个值给它,所以我稍微 Google 了一下,发现了 MonitorFromWindow 函数。
WindowsDPI适配 学习笔记

剩下的操作就非常简单了,新建一个子程序,叫 GetScale,返回值为int
WindowsDPI适配 学习笔记

调试一下,发现成功输出当前显示器的DPI,获取DPI的这步操作就圆满完成了。

接下来,要缩放窗口和控件了,我是这样写的:
WindowsDPI适配 学习笔记

好了,简单适配 DPI 的操作到这就要结束了,刚刚接触 DPI 适配,难免有些疏漏,还请评论区中指出!

效果图:

WindowsDPI适配 学习笔记
WindowsDPI适配 学习笔记

WindowsDPI适配 学习笔记
WindowsDPI适配 学习笔记