枚举计算机上的监视器

Céd*_*non 42 c++ windows gdi dxgi

我找到了7种不同的方法来枚举连接到计算机的显示器.但是所有解决方案都会给出不同的结果(监视器的数量和每个监视器上的信息).

这些解决方案是:

  1. 使用着名的 EnumDisplayDevices

  2. 运用 EnumDisplayMonitors

  3. 使用Windows Management Instrumentation(WMI):
    使用以下查询:SELECT * FROM WmiMonitorIDroot\\WMI命名空间中.

  4. 再次使用WMI:
    使用新查询:SELECT * FROM Win32_DesktopMonitorroot\\CIMV2命名空间中.

  5. 使用Setup API:
    首先调用SetupDiGetClassDevs以检索设备信息集,然后迭代SetupDiEnumDeviceInfo

  6. 使用的DirectX图形基础结构(DXGI)
    随着第一IDXGIFactory::EnumAdapters,然后IDXGIAdapter::EnumOutput

  7. 使用连接和配置显示(CCD)API:
    QueryDisplayConfig(QDC_ALL_PATHS, &numPathArrayElements, pathInfoArray, &numModeInfoArrayElements, modeInfoArray, nullptr);

我试图准确理解所有这些方法与MSDN参考之间的区别,徒劳无功.

意见

从我观察到的:

  • WmiMonitorID安装程序API查询返回连接(不一定活性)显示器的列表.
  • Win32_DesktopMonitor WMI查询返回错误(至少意想不到的)结果(仅1个显示器枚举即使不活动时,和桌面另一台显示器上).
  • EnumDisplayDevices返回活动设备列表(除非只有1个监视器处于活动状态且其他监视器已连接)
  • EnumDisplayMonitorsDXGI查询返回活动监视器列表.
  • CCD似乎是最可靠的方法(在目标和源之间提供所有可能的路径).

问题

使用这些方法时(连接显示列表,已安装显示列表,活动显示列表),我真正期望得到什么结果?如果我使用镜像显示器或扩展显示器怎么办?如果计算机有多个没有多个输出的图形卡怎么办?

额外奖励:某些方法(DXGI,EnumDisplayDevices,CCD)使用适配器 - 监视器的一种层次结构.但是在Adapters和Monitors之间没有给出相同的链接.那么,DXGI适配器的定义是什么?对于CCD?对于EnumDisplayDevices

amr*_*ith 10

我不知道所有这些API,但我确实记得其中一些(糟糕的回忆)所以这里是我能记住的东西,并在MSDN中探索并玩wbemtest,我很惊讶我甚至还记得.我承认,这个答案可能不是所有你所期望的.

对于下面的插图(所有这些插图都在我的戴尔Latitude笔记本电脑上,我正在打字给你,我逻辑上有两台显示器通过扩展坞连接到它).但是,笔记本电脑已关闭,因此笔记本电脑屏幕不可见.

如果我进入显示属性,我只看到一个屏幕.

在此输入图像描述

连接到CIMv2

select * from Win32_DesktopMonitor;
Run Code Online (Sandbox Code Playgroud)

返回两个实例.

在此输入图像描述

DesktopMonitor1是外部显示器(GenericPNPDisplay),DesktopMonitor1是默认监视器(屏幕).

连接到root\WMI

select * from WMIMonitorID;
Run Code Online (Sandbox Code Playgroud)

只给我一个实例,该实例是外部监视器(我知道这是因为制造商名称是HP).(HWP26CE是HP w2408的标识符,请参见此处)

在此输入图像描述

然后,显示适配器和显示器之间存在差异.EnumDisplayDevices显示适配器并向EnumDisplayMonitors您显示监视器.前者主要是枚举适配器,但后者允许您提供剪切矩​​形并确定剪切矩形碰巧落在哪些监视器上.当您有多个活动监视器并且有人决定执行某些操作会导致跨越多个监视器的绘制时,这将变得非常有用.你可以指定一个回调EnumDisplayMonitors函数,并且将使用一些参数调用回调(如果内存正确地为我提供了参数,则其中一个参数是指定剪切矩形的一个子集,它位于指定的监视器上).

我依旧记得SetupDiEnumDeviceInfo并且我认为它为您提供了HDEVINFO每个接口,因此它(我相信)只给我一个条目,因为我只有一个适配器.然后你必须做点什么才能得到SP_DEVINFO_DATA.

我从来没有使用过DirectX和其他API,所以我会关闭这两个.希望其他人可以了解这两个,你可能得到一个完整的答案!