Перечисление мониторов на компьютере

Я нашел 7 разных способов перечисления мониторов, подключенных к компьютеру. Но все решения дают разные результаты (количество мониторов и информация на каждом мониторе).

Эти решения:

  1. Используя знаменитый EnumDisplayDevices

  2. С помощью EnumDisplayMonitors

  3. С использованием Инструментарий управления Windows (WMI):
    С помощью следующего запроса: SELECT * FROM WmiMonitorID в root\\WMI Пространство имен.

  4. Снова используя WMI:
    С новым запросом: SELECT * FROM Win32_DesktopMonitor в root\\CIMV2 Пространство имен.

  5. С использованием API настройки:
    По первому звонку SetupDiGetClassDevs чтобы получить информацию об устройстве, установленную затем, итерации с SetupDiEnumDeviceInfo

  6. С использованием Графическая инфраструктура DirectX (DXGI)
    С первого IDXGIFactory::EnumAdapters, затем IDXGIAdapter::EnumOutput

  7. С использованием API-интерфейсы подключения и настройки дисплеев (CCD):
    QueryDisplayConfig(QDC_ALL_PATHS, &numPathArrayElements, pathInfoArray, &numModeInfoArrayElements, modeInfoArray, nullptr);

Я тщетно пытался понять разницу между всеми этими методами со ссылкой на MSDN.

наблюдения

Из того, что я заметил:

  • WmiMonitorID а также API настройки запросы возвращают список подключенных (не обязательно активных) дисплеев.
  • Win32_DesktopMonitor WMI запрос возвращает неправильно (по крайней мере, неожиданный) результат (перечислен только 1 монитор, даже если он неактивен и рабочий стол на другом мониторе).
  • EnumDisplayDevices возвращает список активных устройств (кроме случаев, когда активен только 1 монитор с подключенным другим монитором)
  • EnumDisplayMonitors а также DXGI запросы возвращают список активных мониторов.
  • CCD кажется наиболее надежным методом (дает все возможные пути между целями и источниками).

Вопросы

Какого результата мне следует ожидать при использовании каждого из этих методов (список подключенных дисплеев, список установленных дисплеев, список активных дисплеев)? Что если я использую зеркальные или расширенные дисплеи? Что делать, если на компьютере установлено несколько видеокарт без нескольких выходов?

Бонус: некоторые методы (DXGI, EnumDisplayDevices, CCD) использовать своего рода иерархию с адаптермонитор. Но не дает одинаковых связей между адаптерами и мониторами. Итак, каково определение адаптера для DXGI? за CCD? за EnumDisplayDevices?

42

Решение

Я не знаю всех этих 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, поэтому я замолчу на эти два вопроса. Надеюсь, кто-то еще может рассказать о них двоим, и вы можете получить полный ответ!

10

Другие решения

Если это уместно в вашем случае, при использовании Qt 5.x вы можете использовать QGuiApplication::screens() метод (http://qt-project.org/doc/qt-5.1/qtgui/qguiapplication.html#screens) перечислить все показы.

Или, если это не актуально, вы всегда можете взглянуть на их исходный код, как они перечисляют дисплеи и получают все соответствующие свойства (в том числе в отношении зеркалирования, расширенных рабочих столов и т. Д.).

1

По вопросам рекламы [email protected]