![]() |
Monitornamen wie in Systemsteuerung auslesen
Liste der Anhänge anzeigen (Anzahl: 1)
Hi.
Ich hab mir zu dem Thema Multimonitor und wie man Infos der angeschlossenen Monitor erhält, jetzt schon einiges durchgesehen. Jedoch hab ich nach etwas bestimmten gesucht. Und zwar : Ist es möglich die Namen der Displays zu bekommen so wie sie in der Systemsteuerung stehen? (Siehe Anhang) Also nicht nur Name des Adapters oder "PnP Monitor"? Ich möchte in den Optionen meiner Adventure Engine eine Auswahl des zu benutzenden Monitors einbauen. Die Displays einfach zu nummerieren würde natürlich gehen, nur stimmt hier auch nicht die Reihenfolge mit der Systemsteuerung überein (dort ist mein Hauptmonitor als 2 eingetragen, in der Monitorliste unter Delphi aber als erstes) Der Spieler müsste also ausprobieren welcher Monitor welcher ist. Was unschön ist. Dank im vorraus. |
AW: Monitornamen wie in Systemsteuerung auslesen
Du kannst über die EDID Informationen an den Monitornamen kommen. Diese Infos stehen in der Registry. Damit bekommst Du aber nur die Namen so, wie es Windows erkennt. Soll heißen, dass wenn in der Systemsteuerung PnP-Monitor steht gibt es den Wert auch nur über die EDID Informationen aus der Registry.
|
AW: Monitornamen wie in Systemsteuerung auslesen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich arbeite hier auch mit Multimonitor-Systemen. Ich habe für den Fall von Screenshots, die gemacht werden sollen, es so gelöst, dass im Dialog kurzerhand die aktuellen Inhalte der Screens angezeigt werden und zusätzlich noch ein Hinweis angezeigt wird, auf welchem Monitor das Formular gerade liegt. So ist eigentlich auch relativ klar, welcher Monitor welcher ist und kann ihn relativ sicher auswählen (siehe anliegenden Screenshot). Wenn man vielleicht 2 gleiche Monitore hat, wäre zudem die Auswahl über den Namen schwierig...
Ich war faul und lasse da einfach nur die Monitore in der Reihenfolge des Monitor-Arrays anzeigen, man könnte die natürlich noch anhand der Koordinaten entsprechend örtlich richtig anzeigen lassen. |
AW: Monitornamen wie in Systemsteuerung auslesen
Aufruf:
Systemsteuerung\Alle Systemsteuerungselemente\Anzeige\Bildschirmauflösu ng
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var FN: String; begin FN:= 'Shell32.dll,Control_RunDLL desk.cpl'; ShellExecute(0,nil,PChar('Rundll32.exe'),PChar(FN),'',SW_SHOWNORMAL); end; |
AW: Monitornamen wie in Systemsteuerung auslesen
Liste der Anhänge anzeigen (Anzahl: 1)
mit der Funktion EnumDisplayDevices() bekommst Du alle Werte, welche Du benötigst.
|
AW: Monitornamen wie in Systemsteuerung auslesen
EnumDisplayDevices führt bei mir nur bis zu den Standardnamen, wie "Pnp-Monitor" usw.
Ich muss letzten Endes doch über die EDID-Auswertung gehen, um an den "Klarnamen" des Monitors zu kommen. Für solche Aufgaben habe ich mir eine Unit gemacht. Wenn die wer will, kann er sie gerne kriegen... (WinXP, Win7, Delphi5/6) |
AW: Monitornamen wie in Systemsteuerung auslesen
Zitat:
Zeig' einmal ein Beispielaufruf. |
AW: Monitornamen wie in Systemsteuerung auslesen
Ausschnitt aus meiner Unit:
Delphi-Quellcode:
Nutzung im Programm (z. B.):
Unit MonitorInfo;
interface uses Windows; //CCHDEVICENAME ist in Windows.pas definiert type HMONITOR = type Integer; {$EXTERNALSYM HMONITOR} function GetMonitorEDID(MonitorHandle: HMONITOR): String; //die folgenden Funktionen nutzen dann die EDID) function ExtractMonitorName(var edid: String): String; function ExtractMonitorSerNumb(var edid: String): String; function ExtractMonitorAddedText(var edid: String): String; //function ExtractMonitorEisaId(var edid: String): String; //function ExtractMonitorNumSerNumb(var edid: String): String; //function ExtractMonitorManufacturingWeek(var edid: String): String; //function ExtractNativeResolution(var edid: String): String; //function ExtractMonitorRangeLimits(var edid: String): String; //function ExtractMaxWidthHeightCm(var edid: String): String; //function MonitorCheckSumCheck(var edid: String): Boolean; ///... implementation uses SysUtils, Classes, Registry, Dialogs; type TMonitorInfoEx = packed record Size: DWORD; rcMonitor: TRect; rcWork: TRect; dwFlags: DWORD; szDevice: array[0..CCHDEVICENAME-1] of AnsiChar; end; function GetMonitorInfo(hMonitor: HMONITOR; var MonitorInfo: TMonitorInfoEx): Boolean; stdcall; external 'User32.dll' name 'GetMonitorInfoA'; type TDisplayDevice = packed record Size: DWORD; DeviceName: array[0 .. CCHDEVICENAME-1] of AnsiChar; DeviceString: array[0 .. 127] of AnsiChar; StateFlags: DWORD; DeviceID: array[0..127] of AnsiChar; DeviceKey: array[0..127] of AnsiChar; end; function EnumDisplayDevices(ADeviceName: PChar; ADeviceIndex: DWORD; Var ADisplayDevice: TDisplayDevice; AFlags: DWORD): Boolean; stdcall; external 'User32.dll' Name 'EnumDisplayDevicesA'; function GetMonitorName(MonitorHandle: HMONITOR): String; var MoniInfo: TMonitorInfoEx; begin Result := ''; MoniInfo.Size := SizeOf(MoniInfo); //Wichtig! if not GetMonitorInfo(MonitorHandle, MoniInfo) then raise Exception.Create('GetMonitorInfo?') //*************** else Result := MoniInfo.szDevice end; function GetMonitorEDID(MonitorHandle: HMONITOR): String; var DisplayInfo: TDisplayDevice; s: String; i, n: Integer; reg: TRegistry; keyList: TStringList; begin s := GetMonitorName(MonitorHandle); if Length(s) > 0 then try DisplayInfo.Size := SizeOf(DisplayInfo); if not EnumDisplayDevices(PChar(s), 0, DisplayInfo, 0) then raise Exception.Create('EnumDisplayDevices?'); // ==> finally s := DisplayInfo.DeviceID; n := Pos('MONITOR\', s); if n <> 1 then raise Exception.Create('DeviceID?'); // ==> finally Delete(s, 1, Length('MONITOR\')); n := Pos('\{', s); if n = 0 then raise Exception.Create('DeviceID?'); // ==> finally Delete(s, n, Length(s)); s := 'SYSTEM\CurrentControlSet\Enum\DISPLAY\' + s; reg := TRegistry.Create; reg.RootKey := HKEY_LOCAL_MACHINE; keyList := TStringList.Create; keyList.Clear; try if not reg.OpenKeyReadOnly(s) then raise Exception.Create('DeviceID?'); reg.GetKeyNames(keylist); reg.CloseKey; n := 0; for i := 0 to KeyList.Count-1 do begin if reg.OpenKeyReadOnly(s + '\' + keyList[i] + '\Control') then begin s := s + '\' + keyList[i] + '\Device Parameters'; reg.CloseKey; if reg.OpenKeyReadOnly(s) then begin n := reg.GetDataSize('EDID'); Break; end; end; end; //for i if n = 0 then raise Exception.Create('EDID?'); // ==> finally SetLength(Result, n); reg.ReadBinaryData( 'EDID', Result[1], n); finally reg.CloseKey; keyList.Free; reg.Free; end; except SetLength(Result, 0); raise; end; end; function ExtractMonitorNameNumbText(Tag: Byte; var edid: String): String; var i, k: Integer; begin Result := ''; if Length(edid) > 60 then for i := 55 to Length(edid) do begin if (edid[i] = Chr(0)) and (edid[i+1] = Chr(0)) and (edid[i+2] = Chr(0)) and (edid[i+4] = Chr(0)) and (edid[i+3] = Chr(Tag)) then begin for k := i+5 to Length(edid) do if edid[k] = Chr($0A) then Break else Result := Result + edid[k]; end; end; end; function ExtractMonitorName(var edid: String): String; begin Result := ExtractMonitorNameNumbText($FC, edid); end; function ExtractMonitorSerNumb(var edid: String): String; begin Result := ExtractMonitorNameNumbText($FF, edid); end; function ExtractMonitorAddedText(var edid: String): String; begin Result := ExtractMonitorNameNumbText($FE, edid); end; //... end.
Delphi-Quellcode:
- Das meiste habe ich mir hier oder an anderer Internet-Stelle "aufgelesen".
//...
var Memo1: TMemo; edid, s: String; for i := 0 to Screen.MonitorCount-1 do begin edid := GetMonitorEDID(Screen.Monitors[i].Handle); Memo.Lines.Add(ExtractMonitorName(edid)); end; - Wer den Programmierstil für unmodern hält, hat sicher recht. Aber ich bin inzwischen so alt, dass mir Überschaubarkeit wichtiger ist als Eleganz. - Wer Fehler findet, sollte sie nicht behalten, sondern mir um die Ohren hauen :roteyes: |
AW: Monitornamen wie in Systemsteuerung auslesen
Zitat:
(Z80-Eigenbau in Assembler):wink: |
AW: Monitornamen wie in Systemsteuerung auslesen
Getestet unter Delphi2007 mit zwei Monitoren:
Fehler in der Funktion "GetMonitorEDID"
Delphi-Quellcode:
Es wird immer die Exception ausgelöst, da
n := Pos('MONITOR\', s);
if n <> 1 then raise Exception.Create('DeviceID?'); // ==> finally
Code:
0 zurück gibt.
Pos('MONITOR\', s);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz