Bildschirmanordnung herausfinden

  • #1
S

StaticIp

Guest
Hallo zusammen,
ich habe mal eine (für mich) wichtige Frage:
Wie finde ich (programmatisch) unter Windows heraus, wie die Bildschirme angeordnet sind?

Beispiel:
Ich habe einen PC mit 8 Monitoren dran (bei uns üblich)
Unter Anzeige>Monitor (oder ähnlich) sehe ich ja, welcher Monitor wo platziert ist.
Unsere 8 Monitore sind nämlich nicht alle nebeneinander, sondern nur 4 Stück und die anderen 4 sind darüber. Das kann ich ja in der Systemsteuerung schön anordnen, damit alles passt. Und mit Identifizieren kann ich ja herausfinden, welcher Monitor welcher ist!

Soweit so gut. Nun möchte ich aber diese Informationen über ein Programm (z.B. Delphi oder LabView oder.....) irgendwie herauslesen können, so dass ich diese Informationen weiterverarbeiten kann.

Vielleicht steht sowas ja irgendwo in der Registry oder per Rundll??

Ich wäre um jeden Tipp froh! Denn gewisse Grafikkartenhersteller (und das Windows) können ja dies herauslesen und darstellen!

Besten Dank für Eure Bemühungen!
StaticIP

[br][blue]*PCDpan_fee: Verschoben aus "Windows XP"*[/blue]
 
  • #2
StaticIp schrieb:
Nun möchte ich aber diese Informationen über ein Programm (z.B. Delphi oder LabView oder.....) irgendwie herauslesen können, so dass ich diese Informationen weiterverarbeiten kann.
da es hier um Programmiersprachen geht, verschieb' ich mal deinen Thread.

pan_fee
 
  • #3
PCDpan_fee schrieb:
da es hier um Programmiersprachen geht, verschieb' ich mal deinen Thread.

Yep, danke schön!
Mir ist gerade noch was eingefallen:
Wenn ich ja die Bildschirme unter der Systemsteuerung an die richtige Position ziehe, sehe ich immer noch die Koordinaten, unter welchen der Bildschirm nun stehen würde...... Also muss im System doch die Koordinaten bekannt sein.....?
Aber wie kann ich die auslesen?

Grüsse
StaticIp
 
  • #4
(Ich bin mir jetzt nicht mehr ganz sicher, ob Du es so gemeint hast.)

Über GetSystemMetrics (*) kannst Du globale Informationen wie Anzahl der Monitore, virtuelle Desktopgröße etc. abfragen. Was Detailinformationen angeht, suche mal nach

EnumDisplayDevices (*)
EnumDisplaySettings (*)
EnumDisplayMonitors (*)
GetMonitorInfo (*)

EnumDisplayMonitors liefert per Callback Basisdaten der Monitore (u.a. jeweils ein Handle).
Mit dem Handle kann über GetMonitorInfo der Anteil (rectMonitor und rectWorkArea) am virtuellen Desktop
und der jeweilige Device-Name (wenn man die Struktur MONITORINFOEX benutzt, nicht bei MONITORINFO) abgefragt werden. Wenn man die einzelnen Bereiche sowie die Gesamtgröße kennt, lassen sich die Positionen ja berechnen.
Wenn man weitere Infos möchte, kann man EnumDisplayDevices mit den Devicenamen aufrufen,
dann müsste man z.B. die Monitornamen erhalten.

Inwieweit Flags der Struktur DISPLAY_DEVICE bei EnumDisplayDevices zu beachten sind, wenn man so vorgeht, weiß ich jetzt nicht.
Ich schätze, dass man sie ignorieren kann, da man ja nach den aktiven Monitoren fragt. Wenn man sich dagegen alle Display-Devices per EnumDisplayDevices holt, ist es natürlich sinnvoll, die Flags auszuwerten, speziell DISPLAY_DEVICE_MIRRORING_DRIVER und DISPLAY_DEVICE_ATTACHED_TO_DESKTOP, da man in diesem Fall ja aktive und reale Devices, nicht Netmeeting, Remote-Desktop-Devices etc. sehen will. Aber wie gesagt, das dürfte hier ohnehin keine Rolle spielen, wenn man über EnumDisplayMonitors geht.

(*) WinAPI, in der user.dll. Sollte mit den üblichen Verdächtigen wie C, C++ etc. und auch C#, VB.NET per P/Invoke sowie Delphi möglich sein.
 
  • #5
Dings schrieb:
(Ich bin mir jetzt nicht mehr ganz sicher, ob Du es so gemeint hast.)

Über GetSystemMetrics (*) kannst Du globale Informationen wie Anzahl der Monitore, virtuelle Desktopgröße etc. abfragen. Was Detailinformationen angeht, suche mal nach

EnumDisplayDevices (*)
EnumDisplaySettings (*)
EnumDisplayMonitors (*)
GetMonitorInfo (*)

Hey, vielen Dank!
Ich habe gerade einen kleinen Test gemacht mit den Anzahl Monitoren. Es scheint zu funktionieren!
Allerdings musste ich die user32.dll verwenden (Windows Vista) und nicht die Funktion EnumDisplayMonitors, sondern SM_CMONITORS, welche nur die tatsächlichen sichtbaren (und auch nicht virtuellen) Bildschirme ausgibt!

Besten Dank!

Nun muss ich nur noch die anderen Funktionen geeignet finden......

PS: Hab's übrigens schnell in LabView probiert. Geht für einen Versuch sehr schnell und man kann das Ergebnis gut beobachten. Später soll es dann mit Delphi programmiert werden, aber das kann ich leider nicht. Das macht dann der Kollege. Aber ich kann ihm nun vielleicht in LabView eine eigene DLL programmieren, welche er dann wiederum nutzen kann, welche nur die gewünschten Funktionen enthält und mit (für uns) besseren Aufrufnamen!

Grüsse
StaticIP
 
  • #6
Staticip schrieb:
Allerdings musste ich die user32.dll verwenden

Ja, sorry, es sollte user32.dll heißen; ich weiß nicht, wie ich auf user.dll gekommen bin.
 
  • #7
Hmm, so ich bin nun einiges schlauer geworden und habe bei M$ etwas in der MSDN Library gestöbert. Hat noch gute Dinge drin! :1

Allerdings konnte ich bis jetzt etwas nicht herausfinden: Wie frage ich explizit den z.B. 2. Monitor ab, welche Auflösung der hat?
Bei der ganzen Beschreiberei bin ich da nicht drausgekommen :-\ Bzw. habs einfach gar nicht gefunden.

Hat da jemand eine Ahnung?
Ich weiss, Dings hat diesbezüglich auch was geschrieben mit MONITORINFOEX und rectMONITOR und rectWORKAREA. Aber ich habs leider nicht hinbekommen..... Vielleicht kann mir das jemand etwas ausführlicher darstellen? :-\

Danke!
StaticIP


[br][br]Erstellt am: 18.05.08 um 15:35:20
[br]
Staticip schrieb:
Aber ich habs leider nicht hinbekommen..... Vielleicht kann mir das jemand etwas ausführlicher darstellen? :-\

Vielleicht sollte ich diesbezüglich noch schreiben, dass ich in LabView nur DLL's aufrufen kann. Dazu muss ich den Prozedurnamen (oder wie das dort heisst) wissen und auch, was für Parameter ich übergeben muss, um was für einen Wert zurückzuerhalten.

Also ich muss z.B. wissen, dass ich die user32.dll aufrufen muss. Darin der Aufruf GetSystemMetrics. Dann muss ich einen nummerischen Integer Typ übergeben. (z.B. 80 für SM_CMONITORS; steht alles bei M$ auf der MSDN Library Seite) Dann bekomme ich einen Integer Typ mit der Anzahl der Monitore zurück..... Aber eben, das mit der Auflösung des 2. Bildschirmes oder die Positionen der Screens habe ich nicht herausgebracht. :-\

Danke für Eure Hilfe!
StaticIP
 
  • #8
Dazu musst Du EnumDisplayMonitors aufrufen. Leider setzt das voraus, mit Callbacks arbeiten zu können, und ich weiß nicht, ob LabView das kann. Wenn Du alle Monitore abrufen möchtest, kannst Du EnumDisplayMonitors mit den Parametern (NULL, NULL, Callback, NULL) aufrufen.->Callback' ist eine Funktion - besser gesagt: ein Zeiger auf eine Funktion -, welche von EnumDisplayMonitors für jeden Monitor aufgerufen wird. Wenn also 8 Monitore vorhanden sind, wird Deine Funktion->Callback' 8x hintereinander aufgerufen, jeweils mit einem Handle des entsprechenden Monitors. Damit kannst Du dann über GetMonitorInfo (http://msdn.microsoft.com/en-us/library/ms534599(VS.85).aspx) weitere Informationen abrufen (die Funktion nimmt ein Monitor-Handle entgegen und füllt eine MONITORINFOEX-Struktur).

Ermitteln des Layouts:

Allerdings in C++ und mit den MFC, aber das Grundprinzip ist ja immer gleich.

Vielleicht hilft Dir das hier auch weiter bezüglich dieser Funktionen und auch der Koordinaten:
 
  • #9
Hallo Dings,

danke für Deine Geduld. Allerdings bin ich einfach nicht genug intelligent, um das zum laufen zu bringen. Vorallem die Vorstellung des Callbacks und des Zeigers wollen bei mir nicht so recht klappen.

Ich habe nun zwar der Funktion EnumDisplayMonitors die Werte 0, 0, 0, 0 übergeben und ich bekomme eine 1 zurück. D.h. es war erfolgreich. Aber was mache ich nun mit dem?
Wenn ich dieses Ergebnis wieder in GetMonitorInfo einspeise erhalte ich nichts.....
Ich komme eben leider nicht wirklich von der Programmierung :'(

Und in LabView gibt es so etwas wie Callback, allerdings kann ich dort Typen für .NET und Active X registrieren, was mich auch nicht wirklich weiterbringt...

Der Funktionsprototyp in LabView sieht folgendermassen aus:
long EnumDisplayMonitors(long hdc, long *lprcClip, long *lpfnEnum, long dwData);
Und wie gesagt, übergebe ich an hdc, lprcClip und auch an dwData jeweils eine 0. An lpfnEnum übergebe ich auch eine 0, weil ich nicht weiss, was bzw. woher ich einen Zeiger übergeben soll...

Sorry, aber wahrscheinlich ist das zu kompliziert um zu erklären, da wir aus zwei völlig unterschiedlichen Software-Welten kommen.....

Vielleicht weiss jemand etwas anderes? Oder kann es für einen völligen Laien erklären?

Dankeschön!
Grüsse
StaticIP
 
Thema:

Bildschirmanordnung herausfinden

ANGEBOTE & SPONSOREN

Statistik des Forums

Themen
113.840
Beiträge
707.963
Mitglieder
51.494
Neuestes Mitglied
Flensburg45
Oben