getsystemmetrics最直接获取windows主屏逻辑分辨率,sdl2跨平台更可靠,enumdisplaymonitors适合多屏精确控制,linux需区分x11/wayland并避免xrandr解析。

Windows平台用GetSystemMetrics最直接
在Windows上,GetSystemMetrics是获取屏幕分辨率最轻量、最稳定的方式,不需要引入额外库或创建窗口。它返回的是主显示器的逻辑像素尺寸(受DPI缩放影响),适用于大多数传统桌面应用。
常见错误是误用SM_CXSCREEN和SM_CYSCREEN以外的值,比如用SM_CXVIRTUALSCREEN却没检查多屏状态;或者忽略高DPI缩放导致实际显示区域比返回值小。
-
GetSystemMetrics(SM_CXSCREEN)返回主屏宽度(逻辑像素) -
GetSystemMetrics(SM_CYSCREEN)返回主屏高度(逻辑像素) - 若需物理像素(绕过DPI缩放),应先调用
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2),再用GetMonitorInfo+GetDpiForMonitor - 注意:该函数不支持UWP或沙盒环境,会返回0
跨平台想用SDL2就别碰原生API
如果项目已依赖SDL2,直接用SDL_GetDesktopDisplayMode比自己写平台分支更可靠——它自动处理Windows/Linux/macOS的差异,包括多显示器、缩放、旋转等边界情况。
容易踩的坑是调用前忘记SDL_Init(SDL_INIT_VIDEO),或传入非法displayIndex(如-1或超出SDL_GetNumVideoDisplays())。返回的SDL_DisplayMode结构体中,w/h字段是当前桌面模式的物理分辨率,不受进程DPI设置影响。
- 获取主屏:用
SDL_GetDesktopDisplayMode(0, &mode) - 获取当前活动屏:结合
SDL_GetWindowDisplayIndex(window)动态查 - macOS下可能返回缩放后的值(如Retina屏上报2560×1600但实际渲染为5120×3200),需配合
SDL_GetWindowSize比对
EnumDisplayMonitors适合多屏精确控制
当需要遍历所有显示器、获取每个屏的原生分辨率、工作区(排除任务栏)、缩放比例时,EnumDisplayMonitors + 回调函数是Windows下的标准做法。它比GetSystemMetrics更底层,也更繁琐。
典型误用是只调用一次就认为拿到全部信息,其实必须通过回调逐个收集;或者把MONITORINFOEX里的rcMonitor直接当分辨率用,忽略了rcWork才是可用工作区(任务栏、Dock等已扣除)。
- 回调中用
GetDpiForMonitor可得每屏独立DPI值 -
rcMonitor.left/top非零表示该屏不在原点,多屏布局时必须考虑偏移 - 要获取物理分辨率而非逻辑值,需用
rcMonitor尺寸 × DPI缩放系数,不能硬编码乘2
Linux下别信xrandr命令输出
在X11环境中,xrandr --current终端输出看似方便,但无法被C++程序直接安全解析(输出格式易变、多行混杂、含单位符号),且不反映Wayland会话的真实状态。真正可行的是用X11库直接查XRRGetScreenResources。
新手常以为XDefaultScreen和XWidth/HeightOfScreen就是分辨率,其实它们返回的是默认屏幕的“大小”,可能被xrandr缩放覆盖;而Wayland下这些X11调用根本不可用,必须走xdg-output协议或wlroots接口。
- X11下应优先用
XRRGetScreenResources+XRRGetOutputInfo查当前激活的mode - Wayland无统一API,主流方案是通过
eglQueryDeviceStringEXT或监听xdg_output事件(需wlroots或libwayland-client) - 没有图形上下文时(如服务端程序),
getenv("WAYLAND_DISPLAY")为空不等于X11一定可用,得getenv("DISPLAY")并尝试XOpenDisplay
多屏+高DPI+混合渲染后端(X11/Wayland)会让“屏幕分辨率”变成一个上下文相关的概念,不是查一个数就能解决的。最稳妥的做法是:明确你真正需要的是逻辑尺寸、物理像素、还是窗口适配基准,再选对应API,而不是找一个“通用函数”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











