如何检测当前屏幕分辨率?

Pro*_*ica 36 c c++ api winapi resolution

如何从Winapi(在C或C++中)检测当前的屏幕分辨率?

一些背景:

我想开始一个新的OpenGL全屏窗口,但希望它以桌面已经设置的相同水平和垂直大小打开.(现在当每个人都使用LCD屏幕时,我认为这是获得屏幕原始分辨率的最佳方式.)

我并不急需知道桌面颜色深度,虽然这将是一个很好的奖励.

And*_*ers 67

  • 主监视器的大小:GetSystemMetrics SM_CXSCREEN/SM_CYSCREEN(也可以使用GetDeviceCaps)
  • 所有监视器的大小(组合):GetSystemMetrics SM_CX/YVIRTUALSCREEN
  • 主监视器上的工作区大小(不包括任务栏和其他停靠栏的屏幕):SystemParametersInfo SPI_GETWORKAREA
  • 特定监视器的大小(工作区和"屏幕"):GetMonitorInfo

编辑:重要的是要记住监视器并不总是在0x0处"开始",所以只知道大小不足以定位窗口.您可以使用MonitorFromWindow查找窗口所在的监视器,然后调用GetMonitorInfo

如果你想要使用低级路由或更改分辨率,你需要使用EnumDisplayDevices,EnumDisplaySettings和ChangeDisplaySettings(这是获得刷新率AFAIK的唯一方法,但GetDeviceCaps会告诉你颜色深度)

  • 我刚刚测试过,GetDeviceCaps 确实可以在 multimon 设置中工作,VERT/HORZRES 和 VREFRESH 似乎都可以工作,但我只能让 CreateDC 接受“\\.\DISPLAY2”样式字符串,而不是“\\.\DISPLAY2\ Monitor0”,所以我不确定如果一个适配器有多个显示器会做什么,所以如果您从 EnumDisplayDevices 获取显示器列表,请坚持使用 EnumDisplaySettings... (3认同)

小智 6

当系统使用DPI虚拟化(Vista及更高版本)时,使用GetSystemMetrics或GetWindowRect将无法获得真正的屏幕分辨率(您将获得虚拟分辨率),除非您创建了DPI Aware Application.

因此,这里的最佳选择(简单和向后兼容)是将EnumDisplaySettings与ENUM_CURRENT_SETTINGS 一起使用.


Pon*_*oni 5

它是带有以下参数的GetSystemMetrics:
SM_CXSCREEN <width
SM_CYSCREEN <height

正如它所说(SM_CXSCREEN):

主显示器屏幕的宽度,以像素为单位.这是通过调用GetDeviceCaps获得的相同值,如下所示:GetDeviceCaps(hdcPrimaryMonitor,HORZRES).