Windows用EnumDisplaySettings传ENUM_CURRENT_SETTINGS获取当前显示器dmDisplayFrequency值(Hz),需先用EnumDisplayDevices获取有效设备名并初始化DEVMODE.dmSize;Linux可用xrandr或/sys/class/drm/解析;macOS调CGDisplayCopyDisplayMode+CGDisplayModeGetRefreshRate;所有平台均无实时推送,仅反映静态显示模式。

Windows下用EnumDisplaySettings获取当前显示器刷新率
Windows没有提供“实时监听刷新率变化”的API,所谓“实时”实际是指查询当前生效的显示设置。最直接的方式是调用EnumDisplaySettings,传入ENUM_CURRENT_SETTINGS标志获取当前活动显示模式。
常见错误是传错设备名:必须用EnumDisplayDevices先枚举出真实设备名(如"\.DISPLAY1"),不能硬写"\\.\DISPLAY1"或"DISPLAY1"——前者反斜杠转义易错,后者会失败。
- 调用前确保
DEVMODE.dmSize = sizeof(DEVMODE)已正确初始化,否则返回FALSE -
dmDisplayFrequency字段即为垂直刷新率(单位Hz),但仅当dmFields & DM_DISPLAYFREQUENCY为真时才有效 - 多显示器场景下,需对每个
DISPLAYx设备单独调用,主屏不一定是DISPLAY1
Linux下读取/sys/class/drm/*/modes或用xrandr解析
Linux没有统一内核接口暴露刷新率,主流做法分两类:查sysfs(适用于KMS驱动)或调用X11的xrandr命令(兼容性更好但依赖X server)。
查/sys/class/drm/card0-DP-1/modes这类路径时,文件内容形如"1920x1080@60"或"1920x1080R"(R表示逐行扫描,默认60Hz),注意@后数字才是刷新率;若无@则需查/sys/class/drm/card0-DP-1/edid解析EDID数据——这步极容易跳过导致误判为60Hz。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 使用
xrandr --verbose输出中找Monitor:块下的Preferred mode:行,再匹配对应60.00*+类时间戳字段 - Wayland环境下
xrandr不可用,需改用swaymsg -t get_outputs(Sway)或hyprctl monitors(Hyprland) - 权限问题:sysfs路径通常无需root,但某些嵌入式drm节点可能被udev规则限制读取
macOS需用CGDisplayModeGetRefreshRate配合CGMainDisplayID
macOS的刷新率不是固定值——尤其在Pro Display XDR或支持自适应同步的MacBook Pro上,系统可能动态切换(如从60Hz切到120Hz)。CGDisplayModeGetRefreshRate返回的是当前激活模式的标称值,不代表下一帧就一定按此频率渲染。
关键陷阱在于:必须用CGDisplayCopyDisplayMode(CGMainDisplayID())先获取当前模式对象,再传给CGDisplayModeGetRefreshRate。直接传NULL或旧缓存的CGDisplayModeRef会导致返回0或过期值。
- 刷新率可能带小数(如
59.97),别用int截断 - 外接显示器热插拔后,需监听
CGDisplayRegisterReconfigurationCallback事件并重新查询,否则仍返回旧值 - macOS 12+对M1/M2芯片启用“自动高刷新率”时,
CGDisplayModeGetRefreshRate返回的是上限值(如120),实际帧率由Metal或Core Animation调度决定
跨平台封装要注意刷新率“有效范围”而非单一数值
不同系统对“当前刷新率”的定义差异极大:Windows返回显卡驱动提交的模式值,Linux返回硬件EDID能力集中的当前选中项,macOS返回Display Mode的标称值——三者都不等于GPU实际提交帧的间隔。
如果你要做帧同步或VSync控制,单纯读这个值意义有限。真正需要的是SwapBuffers后的glXWaitVideoSyncSGI(Linux)、WGL_EXT_swap_control_tear(Windows)或CADisplayLink(macOS)这类机制。
- 不要缓存该值超过1秒,尤其在用户可能手动调整分辨率/缩放/刷新率的桌面环境中
- 笔记本合盖再打开、远程桌面连接断开重连等场景,显示模式可能重置,需重新探测
- 某些游戏全屏独占模式下,系统API可能返回0或错误值,此时应降级到渲染循环实测帧间隔

















