我找到了 7 种不同的方法来枚举连接到计算机的监视器。但是所有解决方案都会给出不同的结果(监视器的数量和每个监视器上的信息)。
这些解决方案是:
使用著名的
EnumDisplayDevices
使用Windows Management Instrumentation (WMI):
使用以下查询:SELECT * FROM WmiMonitorID
在root\\WMI
命名空间中。再次使用WMI :
使用新查询:SELECT * FROM Win32_DesktopMonitor
在root\\CIMV2
命名空间中。使用Setup API:
首先调用SetupDiGetClassDevs
检索设备信息集,然后迭代SetupDiEnumDeviceInfo
使用DirectX 图形基础结构 (DXGI)
与 firstIDXGIFactory::EnumAdapters
,然后IDXGIAdapter::EnumOutput
使用连接和配置显示器 (CCD) API:
QueryDisplayConfig
(QDC_ALL_PATHS, &numPathArrayElements, pathInfoArray, &numModeInfoArrayElements, modeInfoArray, nullptr);
我试图准确地理解所有这些方法与 MSDN 参考之间的区别,但徒劳无功。
观察
据我观察:
- WmiMonitorID和Setup API查询返回已连接(不一定是活动的)显示器的列表。
- Win32_DesktopMonitor WMI查询返回错误(至少是意外)结果(即使在非活动状态下仅枚举了 1 个监视器,并且桌面位于另一台监视器上)。
- EnumDisplayDevices返回活动设备列表(除非只有 1 台显示器处于活动状态且连接了其他显示器)
- EnumDisplayMonitors和DXGI查询返回活动监视器的列表。
- CCD似乎是最可靠的方法(提供目标和源之间的所有可能路径)。
问题
使用这些方法(已连接显示器列表、已安装显示器列表、活动显示器列表)时,我真正期望得到什么结果?如果我使用镜像显示器或扩展显示器怎么办?如果计算机有多个显卡而没有多个输出怎么办?
奖励:一些方法(DXGI、EnumDisplayDevices、CCD)使用一种带有Adapter - Monitor的层次结构。但没有给出适配器和监视器之间的相同链接。那么, DXGI适配器的定义是什么?对于CCD?对于EnumDisplayDevices?