高DPI显示器越来越普及,软件自然也要适应这个变化,最近实习的时候也遇到了一个关于DPI缩放的问题。因为内部框架的一个控件有BUG,会导致内容的显示出问题,后来实在没办法改成了用Windows Native API来自己定义字体,但是这一写就出问题了,本来在内部开发机100%放缩下好好的,一跑到我自己的WIN10,在2K屏放上缩放125%就字体就显示不正常了(字体变得过大)。

Window Vista以后的系统可以直接来个SetProcessDpiAwareness来控制程序的DPI问题,但是这个函数不是很好用,还是没有办法精确控制缩放,而且这个函数只有在Windows 8.1以上的系统才能用(SetProcessDPIAware也行,不过也必须是Windows Vista以上的系统),万一我们的程序需要在XP上运行呢?这就需要用另外一个办法了。

其实这个办法也很简单,就是用GetDeviceCaps来获取当前环境句柄的DPI就可以了,然后和默认的DPI(96)做运算,获得我们真正想要的DPI

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps); auto curDPIX = GetDeviceCaps(hdc, LOGPIXELSX);
auto curDPIY = GetDeviceCaps(hdc, LOGPIXELSY); std::wstring str(L"Hello World"); LOGFONT lf;
HGDIOBJ hObject;
ZeroMemory(&lf, sizeof(LOGFONT));
f.lfCharSet = GB2312_CHARSET;
lf.lfWidth = MulDiv(, , curDPIX);
lf.lfHeight = MulDiv(, , curDPIY);
lf.lfPitchAndFamily = VARIABLE_PITCH;
swprintf_s(lf.lfFaceName, _countof(lf.lfFaceName), L"微软雅黑"); hObject = SelectObject(hdc, CreateFontIndirect(&lf));
TextOut(hdc, , , str.data(), str.length());
DeleteObject(SelectObject(hdc, hObject)); lf.lfWidth = ;
lf.lfHeight = ; hObject = SelectObject(hdc, CreateFontIndirect(&lf));
TextOut(hdc, , , str.data(), str.length());
DeleteObject(SelectObject(hdc, hObject)); EndPaint(hwnd, &ps);
return ;
}

这里演示的是在屏幕上输出Hello Wolrd,现在假设我们的字体被放大了,但是假设我们其他控件没有被放大,那么字在控件里面就会显示不正常,这个时候就要缩小字的尺寸,要想和100%的时候类似,就需要MulDiv(尺寸, 96, curDPI);一下,字体被缩小了同理

这下我们可以看到,第二行是在120%放大下被放大的高度为55,宽度为22的字体,字体偏大,我们通过上面的方法,把字体缩小回正常的尺寸

掉坑日志:Windows Native API与DPI缩放的更多相关文章

  1. 用Windows Native API枚举所有句柄及查找文件句柄对应文件名的方法

    枚举所有句柄的方法 由于windows并没有给出枚举所有句柄所用到的API,和进程所拥有的句柄相关的只有GetProcessHandleCount这个函数,然而这个函数只能获取到和进程相关的句柄数,不 ...

  2. Windows Native API

    http://en.wikipedia.org/wiki/Native_API Windows 的原生 API 函数通常在系统启动时(这里其他 Windows 组件还不可用).kernel32.dll ...

  3. Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32)

    本文将介绍 Windows 系统中高 DPI 开发的基础知识.由于涉及到坐标转换,这种转换经常发生在计算的不知不觉中:所以无论你使用哪种 Windows 下的 UI 框架进行开发,你都需要了解这些内容 ...

  4. Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

    文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...

  5. 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类

    [源码下载] 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 多重继承 虚基类 示例1 ...

  6. 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)

    [源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...

  7. 不可或缺 Windows Native (11) - C++: hello c++, C++ 与 C语言的区别小介

    [源码下载] 不可或缺 Windows Native (11) - C++: hello c++, C++ 与 C语言的区别小介 作者:webabcd 介绍不可或缺 Windows Native 之 ...

  8. node-webkit教程(9)native api 之Tray(托盘)

    node-webkit教程(9)native api 之Tray(托盘) 文/玄魂 目录 node-webkit教程(9)native api 之Tray(托盘) 前言 9.1  Tray简介 9.2 ...

  9. 不可或缺 Windows Native (9) - C 语言: 动态分配内存,链表,位域

    [源码下载] 不可或缺 Windows Native (9) - C 语言: 动态分配内存,链表,位域 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 动态分配内存 链 ...

随机推荐

  1. hdu1754(线段树单点替换&区间最值模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意:中文题诶- 思路:线段树单点替换&区间最大值查询模板 代码: #include & ...

  2. 5G时代的智慧物流~圆通副总裁相峰

        图片来自“百度百科”   本文是圆通速递CEO.国家工程实验室主任相峰先生在2019全球物流技术大会的演讲,在演讲中,相峰先生主要阐述了自己对5G的看法以及5G在物流领域的应用.   以下是演 ...

  3. Spring Cloud Hystrix理解与实践(一):搭建简单监控集群

    前言 在分布式架构中,所谓的断路器模式是指当某个服务发生故障之后,通过断路器的故障监控,向调用方返回一个错误响应,这样就不会使得线程因调用故障服务被长时间占用不释放,避免故障的继续蔓延.Spring ...

  4. CentOS6.7上安装nginx1.8.0

    主题: CentOS6.7上安装nginx1.8.0 环境准备: 1.gcc-c++ 示例:yum install gcc-c++ 安装:gcc-c++ gcc-c++编译工具 2.PCRE(Perl ...

  5. 3、CreateJS介绍-SoundJS

    需要在html5文件中引入的CreateJS库文件是soundjs-0.5.2.min.js HTML5文件如下: <!DOCTYPE html> <html lang=" ...

  6. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  7. storm maven-shade-plugin

      storm-core pom <plugin> <groupId>org.apache.maven.plugins</groupId> <artifact ...

  8. Jenkins权威指南

    https://jenkins.io/doc/   ---官网 https://www.cnblogs.com/leefreeman/p/4226978.html

  9. GUI的最终选择 Tkinter(六):Canvas组件

    Canvas组件,是一个可以让你任性的组件,一个可以让你随心所欲地绘制界面的组件.Canvas是一个通用的组件,它通常用于显示和编辑图形,可以用它来绘制直线,圆形,多边形,甚至是绘制其他组件. 在Ca ...

  10. AspNet Zero Core

    解决AspNet Zero Core 5.0.1无法运行的问题   最近在研究AspNet Zero Core 5.0.1时发现VS点击调试后就自动退出了,从ABP QQ群里得知作者加入了licens ...