什么DPI? 全称是dots per inch (DPI), 也就是每英寸的点数,在显示器上就是每英寸的像素个数,Window上一般默认是96 dpi 作为100% 的缩放比率, 但是要注意的是该值未必是真正的显示器物理值, 只是Windows里我们的一个参考标准。
下面我们思考为什么DPI设置高了之后, 我们看到的字体会变大? 因为系统字体是是以固定大小(宋体10号字,物理尺寸为(10/72)英寸)设计的, 当我们DPI设置高了之后 ,说明该字体要占有更多的像素, 在屏幕分辨率不变的前提下, 看起来也就大了。所以如果我们设置高DPI,通常也意味着我们的显示器是高分辨率, 里面的字体看起来太小了, 我们需要提高DPI来把内容放大。
关于DPI参数的设置:
第一种Unaware, 该种方式是告诉系统, 我的程序不支持DPI aware, 请通过DWM虚拟化帮我们实现。 该方式通过GetWindowRect取到的坐标都是经过DWM缩放后的, 无论对方窗口是不是支持DWM虚拟化。
第二种方式是System DPI aware, 该方式下告诉系统, 我的程序会在启动的显示器上自己支持DPI aware, 所以不需要对我进行DWM 虚拟化。 但是当我的程序被拖动到其他DPI不一样的显示器时, 请对我们先进行system DWM虚拟化缩放。
第三种方式是Per Monitor DPI aware, 该方式是告诉系统, 请永远不要对我进行DWM虚拟化,我会自己针对不同的Monitor的DPi缩放比率进行缩放。 这种方式需要自己完成对高DPI的支持。
chrome 是设置的Per Monitor DPI aware 猜测其UI应该自己内部实现了对高DPI的支持,基于CEF的开发 建议设置System DPI aware 来完成对高DPI的支持。
获取本机DPI时可以使用下面例子来获取,这个在设置Per Monitor DPI aware 模式下才能取到正确的DPI,在System DPI aware下第一次可以获取到准确的DPI值,如果没有注销,则每次获取的为第一次的值啦,不是真正的DPI值。不推荐使用GetDeviceCaps这个哦。
UINT g_xDPI = 0;
UINT g_yDPI = 0;
int nDpi = GetDpiForMonitor(MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTONEAREST),MDT_EFFECTIVE_DPI, (UINT*)&g_xDPI, (UINT*)&g_yDPI);