VBA Access调用GetDeviceCaps获取DPI与标称PPI不符问题咨询
差异产生原因
你观察到的数值差异核心原因是物理PPI和系统逻辑DPI是两个完全不同的概念,具体差异来源如下:
- 厂商标注的157.35是显示器硬件固有参数,指物理屏幕上每英寸能显示的像素数量,由面板的物理尺寸和出厂固定分辨率决定,不会随系统设置变化。
- 你调用
GetDeviceCaps返回的144是Windows系统层面的逻辑DPI,和硬件参数无关:Windows默认基准逻辑DPI为96,你拿到的144正好是96*150%的计算结果,说明你当前系统的显示缩放比例设置为150%,这个逻辑DPI是系统为了让高分辨率屏幕下的界面、文字不会过小而设置的虚拟缩放参数,所有没有开启高DPI感知的程序调用GetDeviceCaps都会拿到这个虚拟化后的数值,不会返回真实硬件PPI。 - 你使用的VBA默认运行在Office宿主程序中,默认没有开启系统级高DPI感知,所以无法通过这个API拿到硬件相关的真实参数。
你使用的VBA代码格式化后如下:
Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As Long) As Long Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal Index As Long) As Long Public Function returnDPI() Dim hDC As Long hDC = GetDC(0) ' 88对应LOGPIXELSX,水平逻辑DPI MsgBox GetDeviceCaps(hDC, 88) ' 90对应LOGPIXELSY,垂直逻辑DPI MsgBox GetDeviceCaps(hDC, 90) End Function
正确计算显示器PPI的方法
物理PPI有标准的计算公式,不需要调用系统API即可算出准确值:
公式逻辑
PPI = 屏幕对角线上的像素数量 / 屏幕对角线物理英寸长度
也就是:PPI = √(水平分辨率² + 垂直分辨率²) / 屏幕标称对角线英寸数
代入你的参数计算
你给出的显示器参数是4K分辨率3840x2160,对角线28英寸,代入计算:
√(3840² + 2160²) ÷ 28 ≈ 4405.8 ÷ 28 ≈ 157.35,和厂商标注的数值完全一致,这个就是你显示器的真实物理PPI。
如果你要通过代码获取真实PPI,需要使用支持高DPI感知的API(比如GetDpiForMonitor),同时要先给VBA宿主程序开启高DPI感知才能拿到正确数值。
内容的提问来源于stack exchange,提问作者George Smith
相关产品推荐
相关产品推荐

