42 votes

Enumération des moniteurs sur un ordinateur

J'ai trouvé 7 façons différentes d'énumérer les moniteurs connectés à l'ordinateur. Mais toutes les solutions donnent des résultats différents (nombre de moniteurs et informations sur chaque moniteur).

Ces solutions sont :

  1. En utilisant le célèbre EnumDisplayDevices

  2. Utilisation de EnumDisplayMonitors

  3. Utilisation de la Instrumentation de gestion Windows (WMI) :
    Avec la requête suivante : SELECT * FROM WmiMonitorID dans le root\\WMI espace de noms.

  4. En utilisant à nouveau le WMI :
    Avec la nouvelle requête : SELECT * FROM Win32_DesktopMonitor dans le root\\CIMV2 espace de noms.

  5. Utilisation de la API de configuration :
    En appelant d'abord SetupDiGetClassDevs pour récupérer l'ensemble des informations sur le dispositif, puis, en itérant avec SetupDiEnumDeviceInfo

  6. Utilisation de la Infrastructure graphique DirectX (DXGI)
    Avec le premier IDXGIFactory::EnumAdapters alors IDXGIAdapter::EnumOutput

  7. Utilisation de la API de connexion et de configuration des écrans (CCD) :
    QueryDisplayConfig(QDC_ALL_PATHS, &numPathArrayElements, pathInfoArray, &numModeInfoArrayElements, modeInfoArray, nullptr);

J'ai essayé de comprendre précisément la différence entre toutes ces méthodes avec la référence MSDN, en vain.

Observations

D'après ce que j'ai observé :

  • El WmiMonitorID y API de configuration Les requêtes renvoient la liste des écrans connectés (pas nécessairement actifs).
  • La requête *Win32_DesktopMonitor WMI* retourne mauvais Résultat (au moins inattendu) (seulement 1 moniteur énuméré même si inactif et bureau sur un autre moniteur).
  • EnumDisplayDevices renvoie la liste des dispositifs actifs (sauf lorsqu'un seul moniteur est actif avec un autre moniteur connecté)
  • EnumDisplayMonitors y DXGI Les requêtes retournent la liste des moniteurs actifs.
  • CCD semble être la méthode la plus fiable (donne tous les chemins possibles entre les cibles et les sources).

Questions

Quel résultat dois-je réellement attendre en utilisant chacune de ces méthodes (liste des écrans connectés, liste des écrans installés, liste des écrans actifs) ? Que se passe-t-il si j'utilise des écrans miroirs ou des écrans étendus ? Que se passe-t-il si l'ordinateur possède plusieurs cartes graphiques sans sorties multiples ?

Bonus : Certaines méthodes ( DXGI , EnumDisplayDevices , CCD ) utilisent une sorte de hiérarchie avec Adaptateur -*Moniteur*. Mais cela ne donne pas les mêmes liens entre les adaptateurs et les moniteurs. Alors, quelle est la définition d'un adaptateur pour DXGI ? pour CCD ? pour EnumDisplayDevices ?

10voto

amrith Points 652

Je ne connais pas toutes ces API, mais je me souviens de certaines d'entre elles (mauvais souvenirs). Voici donc ce dont je me souviens et ce que j'ai trouvé en fouillant dans MSDN et en jouant avec wbemtest, dont je suis surpris de me souvenir. Je reconnais que cette réponse n'est probablement pas TOUTES que vous espériez.

Pour les illustrations ci-dessous (et toutes ces illustrations sont faites sur mon ordinateur portable Dell Latitude sur lequel je vous écris et j'ai logiquement deux moniteurs connectés à celui-ci via la station d'accueil). Mais, l'ordinateur portable est fermé et l'écran de l'ordinateur portable n'est donc pas visible.

Si je vais dans les propriétés d'affichage, je ne vois qu'un seul écran.

enter image description here

Connecté à CIMv2

select * from Win32_DesktopMonitor;

renvoie deux instances.

enter image description here

DesktopMonitor1 est l'affichage externe (GenericPNPDisplay) et DesktopMonitor1 est le moniteur (écran) par défaut.

Connecté à la racine \WMI

select * from WMIMonitorID;

ne me donne qu'une seule instance et cette instance est le moniteur externe (je le sais car le nom du fabricant est HP). (HWP26CE est l'identifiant pour le HP w2408, cf. aquí )

enter image description here

Ensuite, il y a une différence entre les adaptateurs d'affichage et les moniteurs. EnumDisplayDevices vous montre les adaptateurs et EnumDisplayMonitors vous montre les moniteurs. Le premier est principalement destiné à énumérer les adaptateurs mais le second vous permet de fournir un rectangle d'écrêtage et de déterminer sur quels moniteurs ce rectangle d'écrêtage se trouve. Cela devient utile lorsque vous avez plusieurs moniteurs actifs et que quelqu'un décide de faire quelque chose qui provoque un dessin qui va chevaucher plusieurs moniteurs. Vous pouvez spécifier un rappel à EnumDisplayMonitors et ce rappel sera invoqué avec certains paramètres (si ma mémoire est bonne, l'un des paramètres était un sous-ensemble du rectangle d'écrêtage spécifié qui se trouve sur le moniteur spécifié).

Je me souviens vaguement SetupDiEnumDeviceInfo et je pense que cela vous donne HDEVINFO pour chaque interface et par conséquent, cela ne vous donnerait (je crois) qu'une seule entrée sur ma configuration parce que je n'ai qu'un seul adaptateur. Ensuite, il faudrait faire quelque chose pour aller chercher le fichier SP_DEVINFO_DATA .

Je n'ai jamais utilisé DirectX et l'autre API, alors je vais me taire à leur sujet. J'espère que quelqu'un d'autre pourra parler de ces deux-là et que vous obtiendrez une réponse complète !

1voto

Kurt Pattyn Points 1650

Au cas où cela serait pertinent dans votre cas, lorsque vous utilisez Qt 5.x, vous pouvez utiliser la fonction QGuiApplication::screens() méthode ( http://qt-project.org/doc/qt-5.1/qtgui/qguiapplication.html#screens ) pour énumérer tous les affichages.

Ou si ce n'est pas pertinent, vous pouvez toujours jeter un coup d'œil à leur code source, comment ils énumèrent les écrans et obtiennent toutes les propriétés pertinentes (également concernant la mise en miroir, les bureaux étendus, et ainsi de suite).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X