DLU与像素转换系数不符:MapDialogRect与GetDialogBaseUnits差异
问题原因解析
核心矛盾点在于GetDialogBaseUnits与MapDialogRect依赖的字体基础单位来源不同:
DLU(对话框单位)的官方定义:
水平DLU = 当前对话框字体的平均字符宽度 / 4;垂直DLU = 当前对话框字体的高度 / 8
MapDialogRect函数严格基于当前对话框实际使用的字体参数完成DLU到像素的转换。GetDialogBaseUnits返回的是系统默认对话框字体的基础单位(你的测试中X=8、Y=16对应96DPI下的默认字体参数),但在未启用DPI感知的进程中,系统会对对话框字体做虚拟化调整:
即使你指定了MS Shell Dlg 8x16字体,实际生效的字体平均字符宽度为6、高度为12左右——这是系统为了兼容非DPI感知程序的自动适配行为。对应你的测试数据验证:
- 水平转换:
50 DLU × (6 / 4) = 75 像素 - 垂直转换:
14 DLU × (12 / 8) = 21 像素,加上按钮自带的上下边框(2像素),最终得到23像素的高度,与测试结果完全匹配。
- 水平转换:
补充验证方案:
若你启用进程的DPI感知,系统会停止字体虚拟化,此时对话框使用的MS Shell Dlg 8x16字体参数会与GetDialogBaseUnits返回值一致,MapDialogRect的转换系数将变为2,理论计算与实际结果会完全吻合。
内容的提问来源于stack exchange,提问作者Eugene Muzychenko
相关产品推荐
相关产品推荐

