c++ - usar - conectar 2 monitores a una placa de video
EnumeraciĆ³n de monitores en una computadora (2)
En caso de que sea relevante en su caso, cuando use Qt 5.x, puede usar el QGuiApplication::screens()
( http://qt-project.org/doc/qt-5.1/qtgui/qguiapplication.html#screens ) para enumerar todas las pantallas.
O, si no es relevante, siempre puede echar un vistazo a su código fuente, cómo enumeran las pantallas y obtienen todas las propiedades relevantes (también con respecto a la creación de reflejos, escritorios extendidos, etc.).
He encontrado 7 formas diferentes de enumerar los monitores conectados a la computadora. Pero todas las soluciones dan resultados diferentes (cantidad de monitores e información en cada monitor).
Estas soluciones son:
Usando los famosos
EnumDisplayDevices
Usando
EnumDisplayMonitors
Uso de Windows Management Instrumentation (WMI) :
Con la siguiente consulta:SELECT * FROM WmiMonitorID
en el espacio de nombresroot//WMI
.Nuevamente usando el WMI :
Con la nueva consulta:SELECT * FROM Win32_DesktopMonitor
en el espacio de nombresroot//CIMV2
.Usando la API de configuración :
Llamando primero aSetupDiGetClassDevs
para recuperar el conjunto de información del dispositivo, iterando conSetupDiEnumDeviceInfo
Uso de la infraestructura de gráficos de DirectX (DXGI)
Con el primerIDXGIFactory::EnumAdapters
, entoncesIDXGIAdapter::EnumOutput
Uso de las API de Conectar y configurar pantallas (CCD) :
QueryDisplayConfig
(QDC_ALL_PATHS, &numPathArrayElements, pathInfoArray, &numModeInfoArrayElements, modeInfoArray, nullptr);
Intenté entender con precisión la diferencia entre todos estos métodos con la referencia de MSDN, en vano.
Observaciones
Por lo que he observado:
- Las consultas WmiMonitorID y Setup API devuelven la lista de pantallas conectadas (no necesariamente activas).
- La consulta Win32_DesktopMonitor WMI devuelve un resultado incorrecto (al menos inesperado) (solo 1 monitor enumerado incluso cuando está inactivo y el escritorio en otro monitor).
- EnumDisplayDevices devuelve la lista de dispositivos activos (excepto cuando solo 1 monitor está activo con otro monitor conectado)
- Las consultas EnumDisplayMonitors y DXGI devuelven la lista de monitores activos.
- CCD parece ser el método más confiable (da todos los caminos posibles entre los objetivos y las fuentes).
Preguntas
¿Qué resultado debería esperar realmente al usar cada uno de estos métodos (lista de pantallas conectadas, lista de pantallas instaladas, lista de pantallas activas)? ¿Qué pasa si uso pantallas duplicadas o pantallas extendidas? ¿Qué sucede si la computadora tiene múltiples tarjetas gráficas sin múltiples salidas?
Bonificación: algunos métodos ( DXGI , EnumDisplayDevices , CCD ) usan un tipo de jerarquía con Adapter - Monitor . Pero no da los mismos enlaces entre adaptadores y monitores. Entonces, ¿cuál es la definición de un adaptador para DXGI ? para CCD ? para EnumDisplayDevices ?
No conozco todas estas API, pero sí recuerdo algunas (malos recuerdos), así que esto es lo que puedo recordar y encontrar al hurgar en MSDN y jugar con wbemtest, que me sorprende incluso recordar. Reconozco que esta respuesta probablemente no es TODO lo que esperabas.
Para las ilustraciones a continuación (y todas estas ilustraciones están en mi portátil Dell Latitude, te estoy escribiendo esto y lógicamente tengo dos monitores conectados a él a través de la estación de acoplamiento). Pero, la computadora portátil está cerrada y, por lo tanto, la pantalla de la computadora portátil no está visible.
Si entro en propiedades de visualización, solo veo una pantalla.
Conectado a CIMv2
select * from Win32_DesktopMonitor;
devuelve dos instancias.
DesktopMonitor1 es la pantalla externa (GenericPNPDisplay) y DesktopMonitor1 es el monitor predeterminado (pantalla).
Conectado a la raíz / WMI
select * from WMIMonitorID;
me da solo una instancia y esa instancia es el monitor externo (lo sé porque el nombre del fabricante es HP). (HWP26CE es el identificador para HP w2408, ver here )
Entonces, hay una diferencia entre los adaptadores de pantalla y monitores. EnumDisplayDevices
muestra sus adaptadores y EnumDisplayMonitors
muestra los monitores. El primero es principalmente para enumerar los adaptadores, pero este último le permite proporcionar un rectángulo de recorte y determinar qué monitores coincide con ese rectángulo de recorte. Esto se vuelve útil cuando tienes varios monitores activos y alguien decide hacer algo que causa un empate que se monta en múltiples monitores. Se puede especificar una devolución de llamada a EnumDisplayMonitors
y esa devolución de llamada se invocará con algunos parámetros (si la memoria me sirve correctamente, uno de los parámetros fue un subconjunto del rectángulo de recorte especificado que aterriza en el monitor especificado).
Recuerdo vagamente SetupDiEnumDeviceInfo
y creo que le da el HDEVINFO
para cada interfaz y, por lo tanto, creo que le daré solo una entrada en mi configuración porque solo tengo un adaptador. Entonces tendrías que hacer algo para obtener el SP_DEVINFO_DATA
.
Nunca he usado DirectX y la otra API, así que me callaré sobre esos dos. ¡Ojalá alguien más pueda acercarse a esos dos y puede obtener una respuesta completa!