Я нашел 7 разных способов перечисления мониторов, подключенных к компьютеру. Но все решения дают разные результаты (количество мониторов и информация на каждом мониторе).
Эти решения:
Используя знаменитый EnumDisplayDevices
С помощью EnumDisplayMonitors
С использованием Инструментарий управления Windows (WMI):
С помощью следующего запроса: SELECT * FROM WmiMonitorID
в root\\WMI
Пространство имен.
Снова используя WMI:
С новым запросом: SELECT * FROM Win32_DesktopMonitor
в root\\CIMV2
Пространство имен.
С использованием API настройки:
По первому звонку SetupDiGetClassDevs
чтобы получить информацию об устройстве, установленную затем, итерации с SetupDiEnumDeviceInfo
С использованием Графическая инфраструктура DirectX (DXGI)
С первого IDXGIFactory::EnumAdapters
, затем IDXGIAdapter::EnumOutput
С использованием API-интерфейсы подключения и настройки дисплеев (CCD):
QueryDisplayConfig
(QDC_ALL_PATHS, &numPathArrayElements, pathInfoArray, &numModeInfoArrayElements, modeInfoArray, nullptr);
Я тщетно пытался понять разницу между всеми этими методами со ссылкой на MSDN.
Из того, что я заметил:
Какого результата мне следует ожидать при использовании каждого из этих методов (список подключенных дисплеев, список установленных дисплеев, список активных дисплеев)? Что если я использую зеркальные или расширенные дисплеи? Что делать, если на компьютере установлено несколько видеокарт без нескольких выходов?
Бонус: некоторые методы (DXGI, EnumDisplayDevices, CCD) использовать своего рода иерархию с адаптер—монитор. Но не дает одинаковых связей между адаптерами и мониторами. Итак, каково определение адаптера для DXGI? за CCD? за EnumDisplayDevices?
Я не знаю всех этих API, но я помню некоторые из них (плохие воспоминания), поэтому вот что я могу вспомнить и найти, покопавшись в MSDN и поиграв с wbemtest, который я удивлен, я даже помню. Я признаю, что этот ответ, вероятно, не ВСЕ на что ты надеялся.
Для иллюстраций ниже (и все эти иллюстрации на моем ноутбуке Dell Latitude, я набираю это для вас, и у меня есть два монитора, подключенные к нему через док-станцию). Но ноутбук закрыт, поэтому экран ноутбука не виден.
Если я вхожу в свойства дисплея, я вижу только один экран.
Подключен к CIMv2
select * from Win32_DesktopMonitor;
возвращает два экземпляра.
DesktopMonitor1 — это внешний дисплей (GenericPNPDisplay), а DesktopMonitor1 — монитор (экран) по умолчанию.
Подключен к корню \ WMI
select * from WMIMonitorID;
дает мне только один экземпляр, и этот экземпляр является внешним монитором (я знаю это, потому что имя производителя — HP). (HWP26CE — это идентификатор HP w2408, см. Вот)
Кроме того, существует разница между адаптерами дисплея и мониторами. EnumDisplayDevices
показывает вам адаптеры и EnumDisplayMonitors
показывает вам мониторы. Первый предназначен, прежде всего, для перечисления адаптеров, но последний позволяет вам предоставить прямоугольник отсечения и определить, на какие мониторы попадает этот прямоугольник отсечения. Это становится полезным, когда у вас есть несколько активных мониторов, и кто-то решает сделать что-то, что вызывает ничью, которая будет перекрывать несколько мониторов. Вы можете указать обратный вызов EnumDisplayMonitors
и этот обратный вызов будет вызываться с некоторыми параметрами (если память мне не изменяет, один из параметров был подмножеством указанного прямоугольника отсечения, который попадает на указанный монитор).
Я смутно помню SetupDiEnumDeviceInfo
и я думаю, что это дает вам HDEVINFO
для каждого интерфейса и, следовательно, (я считаю) даст вам только одну запись в моей конфигурации, потому что у меня есть только один адаптер. Тогда вам придется что-то сделать, чтобы получить SP_DEVINFO_DATA
,
Я никогда не использовал DirectX и другие API, поэтому я замолчу на эти два вопроса. Надеюсь, кто-то еще может рассказать о них двоим, и вы можете получить полный ответ!
Если это уместно в вашем случае, при использовании Qt 5.x вы можете использовать QGuiApplication::screens()
метод (http://qt-project.org/doc/qt-5.1/qtgui/qguiapplication.html#screens) перечислить все показы.
Или, если это не актуально, вы всегда можете взглянуть на их исходный код, как они перечисляют дисплеи и получают все соответствующие свойства (в том числе в отношении зеркалирования, расширенных рабочих столов и т. Д.).