高DPI下界面错乱的解决方法和原理
来源: http://bbs.csdn.net/topics/370177760
我在win32 + c写的界面中解决办法,就是把字体的字号给固定了,这样做的结果就是,不管dpi是否有改变,界面中控件的文字的字号不变,就不会出现文字换行的情况。
但像菜单文字的字号就变大了,combobox(右三角),checkbox(选择框)变大一点点,显的有点不协调。
但至少不影响使用。
下面是判断当前系统的dpi,然后重置字体的字号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//高DPI下界面错乱的解决方法 HWND hwnd_desktop = GetDesktopWindow(); HDC hdc = GetWindowDC(hwnd_desktop); int dpi = GetDeviceCaps(hdc, LOGPIXELSX); //printf("hwnd_desktop:%ld, dpi:%d\n", hwnd_desktop, dpi); ReleaseDC(hwnd_desktop, hdc); int dpi_diff = dpi - 96; //开发平台默认的dpi: 96 if (dpi_diff > 0) { float zoom = dpi_diff * 1.041666 / 100 + 1; lgf.lfWidth = lgf.lfWidth / zoom; lgf.lfHeight = lgf.lfHeight / zoom; //printf("width:%ld, height:%ld\n", lgf.lfWidth, lgf.lfHeight); } |
一般很少或者不开发产品的朋友可能不会发现。你可以在标准96DPI(一般情况下都是)下,新建一个窗体,载入一个小图片,窗体大小调整为刚好能容纳下图片。生成EXE文件。修改DPI值为120(即125%缩放,XP下桌面-属性-高级里面找,WIN7>屏幕分辨率->放大或缩小其他项目->中等)。系统会要求注销,注销后再进入系统运行EXE程序。马上会看到恶心的结果:窗体被扩大,而图片大小依旧,造成多出来的窗体部分空白。丑陋。如果在加上几个其他空间,丑陋效果更明显:
【普及个知识:】
屏幕坐标计量单位,分为逻辑和物理坐标(单位),物理坐标为像素点、厘米等;逻辑坐标为缇、DPI等DPI是指单位面积内像素的多少。例如,在96默认DPI下1英寸屏幕有96点像素,如果在120DPI下1英寸有120个像素点。缇是VB6中默认的计量单位,96DPI下15缇等于1像素,120DPI下12缇等于1像素。因此,就造成了不同DPI下窗体控件大小会随着DPI值增加而放大,原本设计时就比较大的窗体在高DPI下甚至会超出屏幕边界,还有其他更多问题。
我在 DPI:120下,测试用vb写的界面,发现会窗口和控件会自动放大尺寸,展示效果没有受到DPI的影响,估计与使用的逻辑坐标(单位)有关。
【解决思路】
断断续续想了很久,经过研究,终于发现导致界面错乱的所有原理原因和解决办法。
1.原理原因:界面错乱的关键在于DPI变化后,系统会将程序可视化界面和控件按比例放大。那么使用逻辑坐标(计量单位)就变得不可靠,因为他们都是通过物理单位换算而成,均会受到DPI变化影响,特别是VB6计量单位--缇。完全就是于DPI有着直接的换算关系(96DPI下15缇等于1像素,120DPI下12缇等于1像素)。那么什么单位才可靠呢?答案是--像素、厘米、毫米!锁住界面大小不让缩放的最终就是要锁定三个东西:高度像素值、宽度像素值、控件所位于窗体内的坐标像素值
2.以上这三者被锁定固定大小,界面就将“稳定”不再受到系统DPI干扰。那么:缇(逻辑单位)--像素(物理单位)--DPI(逻辑单位) 这三者间又是怎么换算的?公式还是:96DPI下15缇等于1像素,120DPI下12缇等于1像素;DPI每增加1,就放大1.041666倍。(1440/DPI值=X,X缇=1像素;1.041666是1.014666666666667的约值,如何计算活动省略,知道即可)
3.不仅仅界面和控件放大了,连字体都给放大了!96DPI下的9磅(默认)字体,同比120DPI下的9磅字体小了很多很多。要固定到96DPI 9磅字体的大小,就要使用到这上面这句“DPI每增加1,就放大1.041666倍”。判断当前客户机DPI,减去标准的96,所得值乘以1.041666,所得值为倍数,单位(%)。如120DPI-96=24,24X1.041666%约等于25%,再加上1就是125%。即120DPI比96DPI放大了125%
【总结】
96DPI下获得窗体、控件高度宽度和坐标(left,top)的缇数。除以15便是其物理单位---像素值。之后到客户机上,立即获得其DPI值,获得值为X,将1440除以X获得一个值。这时,窗体、控件高度宽度坐标(LEFT,TOP)缇数就应该为:(原缇数/15)*(1440/现DPI值);(解释:)这样所得到的就是设计时窗体、控件高宽和所在坐标的物理值(像素),之后再根据客户机DPI将这个物理值计算成合适的新缇数。
2014-08-11
高DPI下界面错乱的解决方法和原理的更多相关文章
- android设计的布局在阿拉伯语下界面错乱的解决方法
(1)正在AndroidManifest.xml声明文件的application元素中,增加” android:supportsRtl=true” (2)建] androidの设计的布局在阿拉伯语下界 ...
- 解决VS在高DPI下设计出的Winform程序界面变形问题
在目前高分屏流行的情况下,windows缩放与布局仍然设置为100%就显得太小(特别是笔记本),通常会调整为125%或150%, VS在缩放与布局设置为非100%的时候,就会自动启动DPI感知模式,以 ...
- max-height,min-height在IE下不支持的解决方法
max-height,min-height在IE下不支持的解决方法 max-width:160px; max-height:160px; _width:expression(this.width &g ...
- android keytool 不是内部命令或外部命令在 (win7下不能用的解决方法)
android 关于MD5指纹中 keytool在win7下不能用的解决方法 只要在cmd中执行如下命令即可:注意C:\Users\Administrator\.android\debug.keyst ...
- CentOS7 下linux不能上网解决方法,centos7 eth0 没有ip,IP突然丢失
CentOS7 下linux不能上网解决方法 在CentOS VMware下安装好linux后,发现有时不能直接联网,特分享下总结出来的经验,希望对新手有用 工具/原料 XP系统 VMware.Wo ...
- IE6-7下margin-bottom不兼容解决方法(非原创,视频中看到的)
在IE低版本下有很多不兼容,现在将看到的 IE6-7下margin-bottom不兼容解决方法 演示一下,方便日后自己查阅. <!DOCTYPE html> <html la ...
- VS2017无法进入安装界面问题的解决方法
VS2017无法进入安装界面问题的解决方法 打开C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe也没有 ...
- canvas 1px 出现模糊解决方法及原理
关于canvas绘制1像素出现模糊的原因及解决方法 canvas是html5中非常强大的功能,但是在绘制的时候如果出现1像素,例如画一条1像素的线可能出现模糊情况. 一.解决方法 网上比较常见的解决方 ...
- ubuntu下QT输出程序控制台界面难看的解决方法
这几天在ubuntu下装了QT5,但输出程序界面后,简直无法入目 于是,随便乱找后,终于找到解决方法 打开选项 在终端那行改下就行
随机推荐
- Partition算法以及其应用详解下(Golang实现)
接前文,除了广泛使用在快速排序中.Partition算法还可以很容易的实现在无序序列中使用O(n)的时间复杂度查找kth(第k大(小)的数). 同样根据二分的思想,每完成一次Partition我们可以 ...
- xadmin快速搭建后台管理系统
一.xadmin的特点: 1.基于Bootstrap3:Xadmin使用Bootstrap3.0框架精心打造.基于Bootstrap3,Xadmin天生就支持在多种屏幕上无缝浏览,并完全支持Boots ...
- python3文字转语音
#安装库(必须先安装pywin32) pip3 install pyttsx3 简单测试 import pyttsx3 engine = pyttsx3.init() text='name' engi ...
- JAVA不可变类(immutable)机制与String的不可变性--非常好.
JAVA不可变类(immutable)机制与String的不可变性 https://www.cnblogs.com/jaylon/p/5721571.html
- eclipse添加tomcat服务器
在网上找资料好辛苦,还不对,自己试了好久,终于成功了 还是一如既往的分享 右键 弄好以后发现如此简单| _ |
- this view is not constrainted......
this view is not constrainted 解决方案: <EditText android:id="@+id/editText" android:layout ...
- Codeforces Round #518 (Div. 2) B. LCM gcd+唯一分解定律
题意:给出b 求lcm(a,b)/a 在b从1-1e18有多少个不同得结果 思路lcm*gcd=a*b 转换成 b/gcd(a,b) 也就是看gcd(a,b)有多少个值 可以把b 由唯一分解 ...
- Django+Xadmin打造在线教育系统(七)
全局导航&个人中心&全局搜索 配置全局导航 让index页面也继承base页面,注意首页有个单独的__index.js__ base页面的导航栏也进行配置 <nav> &l ...
- Marriage Match III HDU - 3277(二分权值 + 拆点 建边)
题意: 只不过是hdu3081多加了k种选择 想一下,最多能玩x轮,是不是就是每个女生能最多选x个男生 现在题中的每个女生比3081多了k中选择 那就把女生拆点 i i‘ i --> i ...
- swagger2 如何匹配多个controller
方法一:使用多个controller的共同拥有的父类,即精确到两个controller的上一级 @Bean public Docket createRestApi() { return new Doc ...