GetSystemMetrics仅能获取主显示器逻辑分辨率,不支持多屏和高DPI感知;应结合MonitorFromWindow/GetMonitorInfo获取当前窗口所在屏尺寸,或使用GetSystemMetricsForDpi配合DPI值实现高DPI适配。

GetSystemMetrics 是 Windows API 中获取系统度量值的函数,要获取屏幕分辨率,它确实能用,但只适用于主显示器,且不支持多屏、高 DPI 缩放等现代场景。如果你在写跨显示器应用或需要 DPI 感知,别只靠它。
怎么用 GetSystemMetrics 获取主屏宽高
它通过不同 SM_* 常量返回各类系统指标。主屏分辨率对应两个常量:
-
SM_CXSCREEN:返回主显示器水平像素数(宽度) -
SM_CYSCREEN:返回主显示器垂直像素数(高度)
示例代码:
#include#include int main() { int width = GetSystemMetrics(SM_CXSCREEN); int height = GetSystemMetrics(SM_CYSCREEN); std::cout << "Width: " << width << ", Height: " << height << "\n"; return 0; }
注意:GetSystemMetrics 返回的是逻辑像素(受系统缩放影响),不是物理像素。比如 150% 缩放时,它返回的是缩放后的值(如 1920×1080 屏幕可能返回 1280×720)。
立即学习“C++免费学习笔记(深入)”;
为什么 GetSystemMetrics 在多显示器下不准
它始终只返回“主显示器”的尺寸,和当前窗口所在屏无关。即使你把窗口拖到副屏,GetSystemMetrics(SM_CXSCREEN) 还是主屏的宽度。
- 查副屏尺寸?它做不到
- 查所有屏幕?它不提供枚举接口
- 查当前窗口所在屏?得换函数,比如
MonitorFromWindow+GetMonitorInfo
如果目标是“获取当前窗口所在显示器的分辨率”,必须组合使用:
HMONITOR hmon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO mi = { sizeof(mi) };
GetMonitorInfo(hmon, &mi);
int width = mi.rcMonitor.right - mi.rcMonitor.left;
int height = mi.rcMonitor.bottom - mi.rcMonitor.top;
高 DPI 场景下更推荐 GetDpiForSystem + GetSystemMetricsForDpi
Windows 10 1703+ 提供了 DPI 感知的替代方案。如果你的应用声明为 PerMonitorV2 高 DPI 感知,GetSystemMetrics 会失效(返回缩放前的值或错误结果)。
- 先调用
GetDpiForSystem()或GetDpiForWindow(hwnd)获取当前 DPI 缩放比例 - 再用
GetSystemMetricsForDpi(SM_CXSCREEN, dpi)获取该 DPI 下的逻辑尺寸 - 若需物理像素,用
GetPhysicalPixelSizeForDpi(dpi)(需额外计算)
否则,在 125% / 150% 缩放下,GetSystemMetrics 返回的值和实际绘图区域对不上,UI 元素容易模糊或错位。
真正麻烦的地方不在怎么调用,而在于你是否清楚自己要的是“主屏逻辑尺寸”“当前屏物理尺寸”还是“窗口所在屏的 DPI 感知尺寸”——选错函数,后面所有坐标计算、缩放适配都会偏移。










