getdpiforwindow是windows 10 1607+获取窗口实际dpi的推荐方式,返回值需除以96.0得缩放比例;须启用true/pm dpi-aware manifest,且在wm_create后调用;跨屏时返回主显示器dpi,非平均值。

Windows上用GetDpiForWindow获取当前窗口的DPI缩放比例
Windows 10 1607+ 支持 per-monitor DPI,GetDpiForWindow 是最直接、推荐的方式。它返回的是每英寸点数(DPI),不是百分比,需换算:缩放比例 = DPI / 96.0(因为 96 DPI 对应 100%)。
- 必须启用 DPI-aware manifest(否则系统会以兼容模式运行,
GetDpiForWindow可能始终返回 96) - 窗口句柄
hWnd必须有效且已创建;在WM_CREATE或之后调用,不能在WinMain初始化前用 - 若窗口跨多屏且各屏缩放不同,该函数返回的是该窗口所在主显示器的 DPI —— 不是平均值,也不是“逻辑 DPI”,而是实际渲染所用的 DPI
- 示例:
int dpi = GetDpiForWindow(hWnd);<br>double scale = dpi / 96.0; // 如 144 → 1.5(即 150%)
旧系统 fallback:用GetDeviceCaps + LOGPIXELSX
Windows 8.1 或未启用 per-monitor DPI-aware 的程序,只能拿到主显示器的全局 DPI,用 GetDC(nullptr) 获取屏幕 DC 后调用 GetDeviceCaps。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 返回值同上,也是 DPI 值,仍需除以 96.0 得缩放比
-
GetDC(nullptr)返回的是主显示器的 DC,无法反映副屏缩放差异 - 容易误判:如果用户设置了 125% 缩放但程序未声明 DPI-aware,系统会做虚拟缩放(DPI virtualization),此时
GetDeviceCaps仍返回 96,而界面却被拉伸 —— 这不是真 DPI,是欺骗性值 - 务必检查 manifest 是否包含:
<application xmlns="urn:schemas-microsoft-com:asm.v3"><br><windowssettings><br><dpiaware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiaware><br></windowssettings><br></application>
Qt 或其他 GUI 框架里别自己调 Win32 API
Qt 5.14+、wxWidgets、Dear ImGui 等现代框架内部已封装 DPI 获取逻辑,直接用框架接口更安全可靠。
- Qt 中用
QScreen::devicePixelRatio()(注意:这是物理像素/逻辑像素比,通常 ≈ 缩放比 × 1.0,但 Windows 上基本等价于DPI/96) - Qt 还提供
QGuiApplication::primaryScreen()->logicalDotsPerInchX(),返回逻辑 DPI,可直接用于字体/布局计算 - 手动混合 Win32 和 Qt 调用易出错:比如 Qt 窗口可能启用了
Qt::AA_EnableHighDpiScaling,但你用GetDpiForWindow拿到的是原始 DPI,二者语义不一致 - 跨平台代码尤其要避免硬写
GetDpiForWindow—— macOS/Linux 完全不支持
常见错误:把 GetScaleFactorForMonitor 当成窗口 DPI
GetScaleFactorForMonitor 返回的是整数缩放因子(如 SCALE_125_PERCENT),不是 DPI 值,也不绑定到窗口,只对应某台显示器句柄(HMONITOR)。
- 它和
GetDpiForWindow不等价:前者是系统级策略枚举值,后者是实际生效的渲染 DPI - 需要先调用
MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST)拿到HMONITOR,再传给GetScaleFactorForMonitor - 返回值需映射:
SCALE_100_PERCENT→1.0,SCALE_125_PERCENT→1.25,SCALE_150_PERCENT→1.5 等 —— 但注意:Windows 允许自定义 DPI(如 132),此时该函数返回SCALE_100_PERCENT,而GetDpiForWindow才是真实值 - 除非你明确只需要系统预设档位(如做 UI 缩放档位切换按钮),否则优先用
GetDpiForWindow
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










