2013-04-01 7 views
5

EDIT - Update am EndeHmonitor lösen müssen -> device (oder device -> Hmonitor) in Fenster

Siehe 7.0 Dies ist für Delphi bauen 4,453

Zusammenfassung

Ich muss in der Lage sein, die Handle-Eigenschaft von einem TMonitor-Objekt (ein Element im Monitors-Array in der TScreen-Komponente), das ein HMONITOR ist, in den String umzuwandeln, den Sie in Aufrufen von EnumDisplaySettings als LpszDeviceName-Parameter verwenden würden.

(mein Endziel ist es, eine Liste von Geräteeinstellungen von einem gegebenen HMONITOR-Wert zu erhalten, indem ich den aufgelösten lpszDeviceName in Aufrufe von EnumDisplaySettings übergebe).

Detaillierte Informationen

Wie oben erwähnt, sind die Screen.Monitors [x] .Handle Eigenschaft ist vom Typ Hmonitor und wird normalerweise verwendet, in die GetMonitorInfo Funktion zu übergeben, die zurückgibt, Geometrieinformationen, aber keine lpszDeviceName . (Hinweis: Es gibt eine TMonitorInfoEx Struktur, die ein SzDevice-Feld hat, aber es scheint nicht in meinem System ausgefüllt werden, obwohl ich das cbSize-Feld auf die entsprechende Größe festlegen).

Alternativ, wenn ich eine szDeviceName können das Äquivalent Hmonitor Wert zu erhalten, ich es in die folgende Funktion stecken könnte, was es in einem Vergleich verwenden würde (ich habe einen Aufruf an fiktive Funktion hMonitorFromDeviceName genannt eingefügt im Code unten), um anzugeben, wie es verwendet würde.

function GetMonitorDeviceName(hmon : HMONITOR) : string; 
var 
    DispDev : TDisplayDevice; 
    deviceName : string; 
    nDeviceIndex : integer; 
begin 
    Result := ''; 

    FillChar(DispDev, sizeof(DispDev),0); 
    DispDev.cb := sizeof(DispDev); 

    nDeviceIndex := 0; 
    while (EnumDisplayDevices(nil, nDeviceIndex, DispDev, 0)) do 
    begin 

    if (hMonitorFromDeviceName(DispDev.DeviceString) = hmon) then 
    begin 
     Result := StrPas(DispDev.DeviceString); 
     exit; 
    end; 

    inc(nDeviceIndex); 

    end; 
end; 

aktualisieren

Dank David Heffernan, ich habe seine Lösung, getestet und hier ist eine Beispielfunktion den Monitor Namen von einem bestimmten Griff zu bekommen:

function GetMonitorName(hmon : HMONITOR) : string; 
type 
    TMonitorInfoEx = record 
    cbSize: DWORD; 
    rcMonitor: TRect; 
    rcWork: TRect; 
    dwFlags: DWORD; 
    szDevice: array[0..CCHDEVICENAME - 1] of AnsiChar; 
end; 
var 
    DispDev : TDisplayDevice; 
    deviceName : string; 
    monInfo : TMonitorInfoEx; 
begin 
    Result := ''; 

    monInfo.cbSize := sizeof(monInfo); 
    if GetMonitorInfo(hmon,@monInfo) then 
    begin 

    DispDev.cb := sizeof(DispDev); 
    EnumDisplayDevices(@monInfo.szDevice, 0, DispDev, 0); 
    Result := StrPas(DispDev.DeviceString); 

    end; 
end; 

Antwort

5

Ich denke, dass Sie GetMonitorInfo falsch anrufen müssen. Dieser Code:

{$APPTYPE CONSOLE} 

uses 
    SysUtils, MultiMon, Windows, Forms; 

var 
    i: Integer; 
    MonitorInfo: TMonitorInfoEx; 
begin 
    MonitorInfo.cbSize := SizeOf(MonitorInfo); 
    for i := 0 to Screen.MonitorCount-1 do 
    begin 
    if not GetMonitorInfo(Screen.Monitors[i].Handle, @MonitorInfo) then 
     RaiseLastOSError; 
    Writeln(MonitorInfo.szDevice); 
    end; 
    Readln; 
end. 

erzeugt diese Ausgabe auf meinem Rechner:

 
\\.\DISPLAY1 
\\.\DISPLAY2 

Ich vermute, dass Ihr Anruf GetMonitorInfo in irgendeiner Weise versagt und vielleicht sind Sie nicht den Rückgabewert auf Fehler zu überprüfen.


Nachdem gesucht Quality Ich vermute, dass Sie Opfer auf einen bekannten Fehler in älteren Versionen von Delphi gefallen: QC#3239. Dies wird in der Version 10.0.2124.6661 behoben, die Delphi 2006 ist.


Ihre Kommentare bestätigen diese Diagnose. Um das Problem zu beheben, benötigen Sie eine neue TMonitorInfoEx Definition.Hier ist eine, die auf Ihrem Pre-Unicode Delphi arbeiten:

type 
    TMonitorInfoEx = record 
    cbSize: DWORD; 
    rcMonitor: TRect; 
    rcWork: TRect; 
    dwFlags: DWORD; 
    szDevice: array[0..CCHDEVICENAME - 1] of AnsiChar; 
    end; 

Wenn Sie hinzufügen, dass zu dem obigen Code (bevor Sie die Variablen natürlich erklären), dann halte ich es für Ihr Problem behoben wird. QC#114460:


Als interessante beiseite, auch in XE3, haben diese Strukturen nicht korrekt übersetzt worden. Zugegebenermaßen ist der Fehler eher gutartig, da er nur PMonitorInfoExA und TMonitorInfoExA betrifft, aber der Fehler hat mich erwischt, als ich versuchte, das Problem in dieser Frage zu lösen!

+0

Wenn ich dies auf meinem System ausführen, bekomme ich "der Parameter ist falsch" ausgelöst als Ausnahme. – unsynchronized

+0

Das passiert, wenn 'cbSize' falsch ist. Welchen Wert von cbSize sehen Sie unter dem Debugger? Und welche Version von Delphi hast du? Da ist etwas nicht in Ordnung. Ich bin sicher, dass wir dem auf den Grund gehen können und dass der API-Aufruf für Sie funktioniert. –

+0

Ich benutze Delphi 7, und Writeln (Format (TMonitorInfoEx =% d TMonitorInfo =% d ', [Größe von (TMonitorInfoEx), sizeof (TMonitorInfo)])) Ausgaben: TMonitorInfoEx = 76 TMonitorInfo = 40 – unsynchronized