Windows上GetDeviceCaps获取的物理尺寸不准确,因依赖驱动上报的“声称值”;可靠方式是通过WMI查询WmiMonitorBasicDisplayInfo类获取EDID中的MaxHorizontalImageSize和MaxVerticalImageSize(单位cm),Fallback为GetDeviceCaps(HORZSIZE/VERTSIZE)。

Windows平台用GetDeviceCaps获取物理尺寸不准确?
直接调用GetDeviceCaps查LOGPIXELSX/LOGPIXELSY和HORZSIZE/VERTSIZE,得到的往往是驱动上报的“声称值”,不是真实物理尺寸。很多显示器(尤其外接或高DPI屏)会把HORZSIZE填成254(即10英寸),哪怕实际是27英寸。这不是API错,而是Windows不校准硬件,只信驱动给的数据。
真正可靠的方式是结合EDID信息——它由显示器在连接时主动提供,含制造商、型号、物理尺寸(以cm为单位)等字段。但Windows默认不暴露EDID给普通应用,需用WMI或DDC/CI协议读取。
用WMI查WmiMonitorBasicDisplayInfo类最稳妥
这是目前Windows上对普通程序最可行的方案:无需管理员权限,不依赖显卡驱动细节,且多数现代显示器EDID中MaxHorizontalImageSize和MaxVerticalImageSize字段是真实填写的(单位:cm)。
- 确保项目链接
comsuppw.lib并初始化COM:CoinitializeEx(nullptr, COINIT_APARTMENTTHREADED) - 查询WMI命名空间
root\wmi,执行WQL:SELECT MaxHorizontalImageSize,MaxVerticalImageSize FROM WmiMonitorBasicDisplayInfo - 结果为空?说明当前显示器未提供EDID尺寸(常见于老旧LCD或某些USB-C转接器),此时只能退回到
GetDeviceCaps(HORZSIZE)作为fallback - 注意:返回的是厘米,需除以2.54转英寸;两个字段可能为0,需判空
Linux下读取/sys/class/drm/*/modes和EDID文件
X11或Wayland本身不提供统一接口,但内核通过DRM子系统暴露了EDID原始数据。路径通常是/sys/class/drm/card0-eDP-1/edid(具体设备名需枚举)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 读取EDID二进制数据后,解析第72–73字节(水平尺寸,单位cm)和74–75字节(垂直尺寸,单位cm)
- 若该文件不存在或权限不足(需root),可尝试从X11的
xrandr --verbose输出中提取Physical size行——但该值同样来自驱动,可靠性低于EDID - 不要依赖
xdpyinfo里的dimensions:字段,那是逻辑像素尺寸,不是物理值
macOS必须用CGDisplayScreenSize,别碰IOFramebuffer
macOS有明确公开API:CGDisplayScreenSize(CGDirectDisplayID display)直接返回CGSize(单位:mm)。这是Apple官方保证准确的接口,基于IOKit从显示器固件读取。
- 传入主屏用
CGMainDisplayID(),多屏则需遍历CGGetActiveDisplayList - 不要试图用
IOFramebuffer或IODisplayConnect手动解析EDID——这些是私有API,iOS/macOS版本变动频繁,极易崩溃 - 注意:返回值是毫米,需除以25.4得英寸;若返回
{0,0},说明当前Display ID无效或已断开
EDID里的尺寸字段虽理论上可靠,但仍有厂商乱填。实际项目里建议做两级fallback:先WMI/EDID,再GetDeviceCaps或xrandr,最后记日志提醒用户手动校准。真实物理尺寸这事,连Windows自己都没法100%保证。

















