windows下需用enumdisplaysettings配合有效显示器名获取当前刷新率,dmdisplayfrequency字段即hz值;linux用xrandr解析当前激活模式;macos调用cgdisplaymodegetrefreshrate;所有平台均无实时推送机制,仅反映静态显示模式。

Windows 下用 EnumDisplaySettings 获取当前显示器刷新率
Windows 没有“全局实时刷新率”概念,刷新率是每个显示器在特定显示模式下的属性,必须先确定目标显示器(通常是主屏或当前活动屏),再枚举其当前生效的显示设置。最直接的方式是调用 EnumDisplaySettings,传入 ENUM_CURRENT_SETTINGS 标志。
常见错误是传错设备名:lpszDevice 参数不能为 nullptr 或空字符串,必须是有效显示器名称(如 "\\.\DISPLAY1");获取设备名推荐用 EnumDisplayDevices 遍历,或直接用 TEXT("") 表示默认/主显示器(但行为依赖系统配置,不推荐用于多屏场景)。
- 使用前确保链接
user32.lib -
DEVMODE.dmDisplayFrequency字段即为垂直刷新率(单位 Hz),若为 0 表示未指定或驱动未报告,此时应 fallback 到GetDeviceCaps的VREFRESH(精度较低,且 Win10+ 已不推荐) - 该值不是“实时变化”的——它反映的是当前生效的显示模式,系统切换分辨率或缩放时才更新,应用层无法监听刷新率动态变更事件
Linux X11 下通过 xrandr 解析输出并提取 refresh 值
X11 没有统一 API 返回“当前刷新率”,xrandr 是事实标准工具,其输出可被解析。C++ 程序可通过 popen("xrandr --current", "r") 获取当前状态,然后按行匹配当前激活输出(含 "*" 标记的模式行)及其括号内标注的 +refresh 或隐含值。
注意:同一输出可能有多个支持模式,--current 只显示当前生效的那个;若某行形如 1920x1080 60.00*+,星号表示当前激活,数字即刷新率;若带 + 且无显式 refresh,则需查前一行类似 1920x1080 60.00*+ 59.94 50.00 的完整列表——第一个带 * 的数值才是当前值。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 依赖
xrandr命令存在且可执行,无 GUI 环境(如 headless server)下不可用 - Wayland 下
xrandr通常失效,需走xdg-output协议或 compositor 特定接口(如 KDE 的org.kde.KWin.OutputManagement),无通用方案 - 刷新率可能含小数(如
59.94),建议用strtod解析而非整型截断
macOS 用 CGDisplayModeGetRefreshRate 获取主屏当前模式刷新率
macOS 提供 Core Graphics 接口,CGMainDisplayID() 获取主屏 ID,再用 CGDisplayCopyAllDisplayModes 枚举所有支持模式,遍历比对当前激活模式(CGDisplayCopyDisplayMode)后调用 CGDisplayModeGetRefreshRate。
关键点在于:macOS 的“当前模式”不等于“最高支持刷新率”,例如 Pro Display XDR 在 10-bit HDR 下可能运行在 60Hz,而 SDR 模式支持 120Hz —— 必须取实际生效的 CGDisplayModeRef,不能假设列表首项或最高值。
- 需要链接
CoreGraphics.framework - 返回值为
CGFloat,典型值如60.0、120.0,若返回 0.0 表示不可用(如某些虚拟显示器或旧硬件) - 该值在显示器热插拔或系统偏好设置更改后不会自动更新,应用需自行监听
CGDisplayRegisterReconfigurationCallback并重新查询
跨平台封装要注意的硬伤:没有“实时”这回事
所有平台都不存在操作系统级的“实时刷新率推送机制”。所谓“实时”,实际是“当前显示模式的静态参数”,它只在显示设置变更(用户改分辨率、HDR 开关、DPMS 唤醒等)时才变。试图轮询获取“毫秒级变化”毫无意义,因为硬件和驱动层根本不提供这种粒度的数据。
更现实的问题是:多显示器场景下,各屏刷新率可能不同(如笔记本屏 60Hz + 外接 144Hz 显示器),而多数游戏/渲染引擎只关心主屏或渲染目标所在的屏。强行统一取值会导致 vsync 行为异常或画面撕裂。
- 不要缓存一次结果长期复用——至少在窗口重获焦点、显示配置变更回调中刷新
- 避免在渲染循环中频繁调用(尤其 Windows 的
EnumDisplaySettings涉及 GDI 锁,可能卡顿) - 对精度要求高的场景(如专业视频同步),应结合
CVDisplayLink(macOS)、DXGI_SWAP_CHAIN_DESC1.RefreshRate(Windows DirectComposition)、或 Vulkan 的VK_GOOGLE_surface_refresh_rate扩展,而非仅依赖系统报告值
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










