一、前言

光说不练假把式。
原理说再多,也不如一个例子直观明了。所以本篇文章就来通过一个例子演示一下高DPI适配的流程。

相信看完的你,一定会有所收获!

本文地址:https://www.cnblogs.com/lesliexin/p/14801749.html


二、对比

我们先来看一组对比,分别是未进行高DPI适配与已进行高DPI适配的程序运行截图。

(一),DPI=96(屏幕分辨率:1080P)

1,未进行高DPI适配
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

2,已进行高DPI适配
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

这种情况下,程序未发生缩放,所以两者几乎一样。

(二),DPI=192(屏幕分辨率:4K)

1,未进行高DPI适配
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

2,已进行高DPI适配
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

可以看到,未进行高DPI适配时,控件发生了重叠,而且文本框、下拉框、按钮内容显示也不完整。
但是经过高DPI适配后,界面无论是布局还是内容,都与DPI=96时一致。

三、高DPI适配流程

(一),通知系统“程序已适配高DPI”

因为系统会自动对程序进行高DPI缩放,这个优先级是最高的,所以第一步是在程序启动时通知系统“本程序已自行适配高DPI,不需要再对我进行缩放”。
使用的是Win32Api函数SetProcessDPIAware,因为此函数是Vista之后才有的,所以需要判断下系统版本。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

(二),在程序初始化时进行高适配

对程序的高DPI适配无非两步:一是尺寸的调整,二是位置的调整。
所以就需要在程序初始化时进行处理。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

(三),适配步骤

1,【在VS设计器中进行布局】

(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

2,【获取DPI】

使用Graphics的DpiX/DpiY获取。
现在绝大部分屏幕都是“方形像素”,所以DpiX与DpiY的值是相同的。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

3,【尺寸调整】之获取控件宽度

上一篇文章中,我们知道适配的基准是通过字符串宽度来确定控件宽度
所以,我们可以通过设计器来大致确定下每个控件的宽度=多少个字符。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP
代码:
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

4,【尺寸调整】之间隔

间隔分为控件与窗口边框之间的间隔(简称“间隔1”),和控件与控件之间的间隔(简称“间隔2”)。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP
代码:
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

5,【尺寸调整】之调整控件尺寸

有了上面的尺寸数据后,就可以调整这些控件们的具体尺寸了。
这里面需要说明的一个控件是按钮,因为按钮的宽和高都不会自动调整,所以除了按钮的宽度外,还需要设置按钮的高度。
我们通过设计器,可以看到,按钮的高度大概是Label高度的1.5倍,所以我们就可以根据Label的高来计算按钮的高度。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP
代码:
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

6,【尺寸调整】之所有控件所占用的宽度

在调整好控件的尺寸后,所有控件占用的宽度也会发生变化。以本程序为例,最宽处为:间隔1+文本框宽度+间隔2+下拉框宽度+间隔1。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

7,【尺寸调整】之所有控件所占用的高度

在调整好控件的尺寸后,所有控件占用的高度也会发生变化。以本程序为例,最高处为:间隔1+Label高度+间隔2+文本框高度+间隔2+按钮高度+间隔1
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

8,【尺寸调整】之窗口边框厚度

在调整完控件的尺寸后,对应窗口的尺寸也需要重新调整,所以我们还需要知道窗口边框的厚度。
其中,左、右、下边框的厚度是一样的。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

9,【尺寸调整】之窗口尺寸调整

有了以上数据,就可以调整窗口的尺寸了。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP

10,【位置调整】

当改变完控件的尺寸后,控件的位置也需要重新进行调整,不然会发生控件错位、重叠等情况。
在调整位置时,一般以左上角的控件为准进行调整,本例便以左上角的Label为基准进行调整。
(原创)高DPI适配经验系列:(四)高DPI适配示例-LMLPHP


四,总结

高DPI的适配,技术难度并不高,更多的是耐心与细心。
因为在进行尺寸与位置的调整时,需要进行大量的重复性计算,很考验耐心。
除了这些之外,如果程序中使用了【图标】、【图片】等元素,也需要进行相就的选择和替换。
以我个人经验,适配时都是分为十个级别(参看(原创)高DPI适配经验系列:(二)按DPI范围适配),所以每组图标和图片都需要准备十份,这更是一份考验耐心与细心的活。

至此,本系列完结,如果后续还有与高DPI相关的经验,仍会继续更新。

因为都是一些我个人的经验,所以难免有所纰漏,欢迎大家评论指正。

05-25 15:10