来源: 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下界面错乱的解决方法和原理的更多相关文章

  1. android设计的布局在阿拉伯语下界面错乱的解决方法

    (1)正在AndroidManifest.xml声明文件的application元素中,增加” android:supportsRtl=true” (2)建] androidの设计的布局在阿拉伯语下界 ...

  2. 解决VS在高DPI下设计出的Winform程序界面变形问题

    在目前高分屏流行的情况下,windows缩放与布局仍然设置为100%就显得太小(特别是笔记本),通常会调整为125%或150%, VS在缩放与布局设置为非100%的时候,就会自动启动DPI感知模式,以 ...

  3. max-height,min-height在IE下不支持的解决方法

    max-height,min-height在IE下不支持的解决方法 max-width:160px; max-height:160px; _width:expression(this.width &g ...

  4. android keytool 不是内部命令或外部命令在 (win7下不能用的解决方法)

    android 关于MD5指纹中 keytool在win7下不能用的解决方法 只要在cmd中执行如下命令即可:注意C:\Users\Administrator\.android\debug.keyst ...

  5. CentOS7 下linux不能上网解决方法​,centos7 eth0 没有ip,IP突然丢失

    CentOS7 下linux不能上网解决方法​ 在CentOS VMware下安装好linux后,发现有时不能直接联网,特分享下总结出来的经验,希望对新手有用 工具/原料 XP系统 VMware.Wo ...

  6. IE6-7下margin-bottom不兼容解决方法(非原创,视频中看到的)

    在IE低版本下有很多不兼容,现在将看到的   IE6-7下margin-bottom不兼容解决方法   演示一下,方便日后自己查阅. <!DOCTYPE html> <html la ...

  7. VS2017无法进入安装界面问题的解决方法

    VS2017无法进入安装界面问题的解决方法 打开C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe也没有 ...

  8. canvas 1px 出现模糊解决方法及原理

    关于canvas绘制1像素出现模糊的原因及解决方法 canvas是html5中非常强大的功能,但是在绘制的时候如果出现1像素,例如画一条1像素的线可能出现模糊情况. 一.解决方法 网上比较常见的解决方 ...

  9. ubuntu下QT输出程序控制台界面难看的解决方法

    这几天在ubuntu下装了QT5,但输出程序界面后,简直无法入目 于是,随便乱找后,终于找到解决方法 打开选项 在终端那行改下就行

随机推荐

  1. IntelliJ IDEA启动Tomcat后,却无法访问Tomcat主页 等一系列问题

    1.IntelliJ IDEA启动Tomcat后,却无法访问Tomcat主页 转:http://www.myexception.cn/other/1998827.html https://blog.c ...

  2. AspectJ用注解替换xml配置

    AspectJ基于注解的使用 AspectJ简介 AspectJ是一个基于Java语言的AOP框架,一般 其主要用途:自定义开发 一般情况下spring自动生成代理,要配置aop, 首先确定目标类,a ...

  3. Linux基础学习(16)--备份与恢复

    第十六章——备份与恢复 一.备份概述 1.Linux系统需要备份的数据: 2.备份策略: 二.dump和restore命令 1.dump命令: 2.restore命令:

  4. 定义一个内核panic问题

    出现问题时的反汇编为: /usr/src/debug/kernel-4.1.44-.aarch64/net/core/dev.c: 17800xffff800000860724 <__netif ...

  5. ArcGIS中使用异步回调函数查询图层Graphic

    在我们的地图的操作中经常会有一些操作是需要通过画多边形或者画线来查找某一块区域内的特定的Graphics比如我们在做的交警的项目中通过框选来查找某一块区域中的摄像机,某一块区域中的警力.警情.警员等相 ...

  6. 老男孩python学习自修【第二天】字符串用法

    实时处理增量日志最佳实践 主要使用f.seek()和f.tell()实现 字符串处理函数: s.find(substr, start, end) 查找子字符串,找不到则返回-1,找到则返回对应的索引 ...

  7. 三、Docker网络

    一.查看8001端口是否开启处监听状态 netstat -apnl | grep 8001 二.使用brctl show可以看到虚拟机的网络关系 brctl show docker每新建一个conta ...

  8. Linux上面部署java项目

    最近做项目迁移,费了很大周折.总算顺利迁移了.其实一直以为搞不懂单用tomcat是怎么发布项目的.但还是得硬着头皮做. 不过这个是在搭建测试服务器的时候弄的.开始我就直接把程序包丢tomcat里面也能 ...

  9. vue 使用技巧总结 18.11

    前言: 在大概学完 vue 整体框架后,有幸接触到花裤衩大神写的 vue-elementUI-admin 模板框架,把这个模板框架当作 demo,跟着 code 一遍,最大的收获是在以逻辑简单的模板熟 ...

  10. hdu-1686(kmp)

    题意:前面的都是废话...其实直接看输入要求和输出要求就可以了,就是给你两个字符串,问你第一个字符串在第二个字符串中出现几次: 解题思路:kmp... 代码: #include<iostream ...