I have found 7 different ways to enumerate the monitors attached to the computer. But all solutions give different results (number of the monitors and information on each monitor).
These solutions are:
Using the famous
EnumDisplayDevices
Using
EnumDisplayMonitors
Using the Windows Management Instrumentation (WMI):
With the following query:SELECT * FROM WmiMonitorID
in theroot\\WMI
namespace.Again using the WMI:
With the new query:SELECT * FROM Win32_DesktopMonitor
in theroot\\CIMV2
namespace.Using the Setup API:
By first callingSetupDiGetClassDevs
to retrieve the device information set then, iterating withSetupDiEnumDeviceInfo
Using the DirectX Graphics Infrastructure (DXGI)
With firstIDXGIFactory::EnumAdapters
, thenIDXGIAdapter::EnumOutput
Using the Connecting and Configuring Displays (CCD) APIs:
QueryDisplayConfig
(QDC_ALL_PATHS, &numPathArrayElements, pathInfoArray, &numModeInfoArrayElements, modeInfoArray, nullptr);
I've tried to understand precisely the difference between all theses methods with the MSDN reference, in vain.
Observations
From what I've observed:
- The WmiMonitorID and Setup API queries return the list of connected (not necessarily active) displays.
- The Win32_DesktopMonitor WMI query returns wrong (at least unexpected) result (only 1 monitor enumerated even when inactive and desktop on another monitor).
- EnumDisplayDevices returns the list of active devices (except when only 1 monitor is active with other monitor connected)
- EnumDisplayMonitors and DXGI queries return the list of active monitors.
- CCD seems to be the most reliable method (gives all possible paths between targets and sources).
Questions
What result should I really expect when using each of these methods (list of connected displays, list of installed displays, list of active displays)? What if I use Mirrored displays or Extended displays? What if the computer has multiple graphics cards without multiple outputs?
Bonus: Some methods (DXGI, EnumDisplayDevices, CCD) use a kind of hierarchy with Adapter-Monitor. But doesn't give the same links between Adapters and Monitors. So, what is the définition of an adapter for DXGI? for CCD? for EnumDisplayDevices?
GetSystemMetrics(SM_CMONITORS)
counts only visible display monitors. This is different from EnumDisplayMonitors, which enumerates both visible display monitors and invisible pseudo-monitors that are associated with mirroring drivers. An invisible pseudo-monitor is associated with a pseudo-device used to mirror application drawing for remoting or other purposes. – Chamaeleon