AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Monitor X per ChangeDisplaySettingsEx (A) akivieren ?
Thema durchsuchen
Ansicht
Themen-Optionen

Monitor X per ChangeDisplaySettingsEx (A) akivieren ?

Offene Frage von "Y.Elm"
Ein Thema von Rumpi · begonnen am 2. Feb 2005 · letzter Beitrag vom 23. Nov 2011
Antwort Antwort
Seite 2 von 2     12   
Muetze1
(Gast)

n/a Beiträge
 
#11

Re: Monitor X per ChangeDisplaySettingsEx (A) akivieren ?

  Alt 9. Feb 2005, 11:45
Moin!

Ist \\.\DISPLAY2 auch der 2. Monitor/Grafikkartenausgang und nicht vielleicht der TV Out Ausgang? Schonmal die Bits zu den Einträgen angeschaut?

Delphi-Quellcode:
Procedure TForm1.FillMonitorList;
Var
  Cntr : Cardinal;
  Info : TDisplayDevice;
  AdapterName : PChar;
  OldPos : Integer;
Const
  DISPLAY_DEVICE_ATTACHED_TO_DESKTOP = $00000001;
  DISPLAY_DEVICE_MULTI_DRIVER = $00000002;
  DISPLAY_DEVICE_PRIMARY_DEVICE = $00000004;
  DISPLAY_DEVICE_MIRRORING_DRIVER = $00000008;
  DISPLAY_DEVICE_VGA = $00000010;
Begin
  lbMonitorList.Items.Add('------------------ Displays ----------------');

  Cntr := 0;
  Info.cb := SizeOf(Info);
  While EnumDisplayDevices(Nil, Cntr, Info, 0) Do
  Begin
    lbMonitorList.Items.Add('* Device '+IntToStr(Cntr)+':');
    lbMonitorList.Items.Add(' DeviceName : '+Info.DeviceName);
    lbMonitorList.Items.Add(' DeviceString: '+Info.DeviceString);

    OldPos := lbMonitorList.Items.Add(' StateFlags: ');

    If ( Info.StateFlags And DISPLAY_DEVICE_ATTACHED_TO_DESKTOP ) = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP Then
      lbMonitorList.Items.Add(' + Display Device Attached To Desktop')
    Else
      lbMonitorList.Items.Add(' - Display Device Attached To Desktop');

    If ( Info.StateFlags And DISPLAY_DEVICE_MULTI_DRIVER ) = DISPLAY_DEVICE_MULTI_DRIVER Then
      lbMonitorList.Items.Add(' + Display Device Multi Driver')
    Else
      lbMonitorList.Items.Add(' - Display Device Multi Driver');

    If ( Info.StateFlags And DISPLAY_DEVICE_PRIMARY_DEVICE ) = DISPLAY_DEVICE_PRIMARY_DEVICE Then
      lbMonitorList.Items.Add(' + Display Device Primary Device')
    Else
      lbMonitorList.Items.Add(' - Display Device Primary Device');

    If ( Info.StateFlags And DISPLAY_DEVICE_MIRRORING_DRIVER ) = DISPLAY_DEVICE_MIRRORING_DRIVER Then
      lbMonitorList.Items.Add(' + Display Device Mirroring Driver')
    Else
      lbMonitorList.Items.Add(' - Display Device Mirroring Driver');

    If ( Info.StateFlags And DISPLAY_DEVICE_VGA ) = DISPLAY_DEVICE_VGA Then
      lbMonitorList.Items.Add(' + Display Device VGA')
    Else
      lbMonitorList.Items.Add(' - Display Device VGA');


    AdapterName := StrAlloc(SizeOf(Info.DeviceName));
    StrCopy(AdapterName, Info.DeviceName);
    EnumDisplayDevices(AdapterName, 0, Info, 0);
    lbMonitorList.Items.Insert(OldPos, ' Monitorname : ' + Info.DeviceString);
    StrDispose(AdapterName);

    Inc(Cntr);
  End;
End;
Mach mal ein Testprogramm und pack den Aufruf da mal mit rein und schau mal nach welche Flags danach in der lbMonitorList ListBox stehen. Das wäre so dies was mir denn dazu noch einfällt. Eine Fehlermeldung kommt auch nicht (so ala falsche Flags o.ä.)??

MfG
Muetze1
  Mit Zitat antworten Zitat
jonx

Registriert seit: 7. Apr 2006
2 Beiträge
 
#12

Re: Monitor X per ChangeDisplaySettingsEx (A) akivieren ?

  Alt 12. Okt 2006, 12:49
vielen dank für your code sample.

please note that while trying to set a negative position for my monitor
lDevMode.dmPosition.x := -1280;

I had to change the TPOINTL record to
TPOINTL = Packed Record
x : Integer;
y : Integer;
End;

thanks again.
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#13

Re: Monitor X per ChangeDisplaySettingsEx (A) akivieren ?

  Alt 12. Okt 2006, 14:19
Zitat von jonx:
vielen dank für your code sample.

please note that while trying to set a negative position for my monitor
lDevMode.dmPosition.x := -1280;

I had to change the TPOINTL record to
TPOINTL = Packed Record
x : Integer;
y : Integer;
End;

thanks again.
Obviously, but I only copy it from another code and there was no need about negative coordinates. Thanks for the addition!
  Mit Zitat antworten Zitat
msickel

Registriert seit: 14. Mai 2005
108 Beiträge
 
Delphi 2005 Professional
 
#14

Re: Monitor X per ChangeDisplaySettingsEx (A) akivieren ?

  Alt 15. Jul 2009, 10:40
Zitat von Muetze1:
Moin!

Also bei mir funktioniert es - ich habe es endlich mal zeitlich hinbekommen dies auszuprobieren. Grundlegendes:

1. Was meinst du die ganze Zeit mit dmPelsWidth und dmPelsHeight? Das ist die Auflösung des Monitors und nicht seine Position im MultiMon System und bedeutet daher auch nicht die Aktivierung/Deaktivierung.

2. Die TDevMode[A/W] in Delphi (zumindes in Delphi 5 bei mir) ist fehlerhaft - besser: nicht vollständig - und daher kann man kein dmPosition angeben. Ich vermute mal ganz stark du hast einfach nach einem ähnlichen Member der struct gesucht.

3. Nach der MSDN gibt es einen Teil der Strukt wo an gleicher Stelle Monitorinformationen und Papier/Druckerinformationen liegen. Darunter fällt auch die dmPosition die ich mir dann mal definiert habe:

Delphi-Quellcode:
Type
  TPOINTL = Packed Record
    x : DWORD;
    y : DWORD;
  End;
  TPrinterMonitor = Packed Record
    Case Integer Of
      0 : (Paper: Packed Record
            dmOrientation: SHORT;
            dmPaperSize: SHORT;
            dmPaperLength: SHORT;
            dmPaperWidth: SHORT;
            dmScale: SHORT;
            dmCopies: SHORT;
            dmDefaultSource: SHORT;
            dmPrintQuality: SHORT;
          End;);
      1 : (Monitor: Packed Record
            dmPosition : TPOINTL;
            dmDisplayOrientation : DWORD;
            dmDisplayFixedOutput : DWORD;
           End;)
  End;
  TDevModeA_new = packed record
    dmDeviceName: array[0..CCHDEVICENAME - 1] of AnsiChar;
    dmSpecVersion: Word;
    dmDriverVersion: Word;
    dmSize: Word;
    dmDriverExtra: Word;
    dmFields: DWORD;

    /// !!!
    Dual : TPrinterMonitor;
    /// !!!

    dmColor: SHORT;
    dmDuplex: SHORT;
    dmYResolution: SHORT;
    dmTTOption: SHORT;
    dmCollate: SHORT;
    dmFormName: array[0..CCHFORMNAME - 1] of AnsiChar;
    dmLogPixels: Word;
    dmBitsPerPel: DWORD;
    dmPelsWidth: DWORD;
    dmPelsHeight: DWORD;
    dmDisplayFlags: DWORD;
    dmDisplayFrequency: DWORD;
    dmICMMethod: DWORD;
    dmICMIntent: DWORD;
    dmMediaType: DWORD;
    dmDitherType: DWORD;
    dmICCManufacturer: DWORD;
    dmICCModel: DWORD;
    dmPanningWidth: DWORD;
    dmPanningHeight: DWORD;
  end;
Die Struktur ist sogar gleich gross wie die TDevModeA (bzw. DEVMODEA) und ist somit kompatibel. Die Definition hätte man bestimmt auch anders hinbekommen, aber das war mir erstmal egal.

4. Deaktiviern eines Monitors funktioniert über das setzen des Monitors per DM_POSITION in Flags und setzen von dmPosition auf 0,0. Dieses funktioniert nur bei nicht primären Monitore! Primäre Monitor kann man nicht deaktivieren, da deren dmPosition immer bei 0,0 liegen. Um einen primären Monitor zu deaktivieren müsste man einen aktiven secondären Monitor auf dmPosition (0,0) setzen und (CDS_PRIMARY Or CDS_UPDATEREGISTRY) damit dieser Primär wird - danach kann man den nun neuen sekundären (bis zuvor noch primären) Monitor deaktivieren.

5. Ohne Angabe von CDS_UPDATEREGISTRY kann man keine Änderungen am MultiMon-System vornehmen - man muss es immer dauerhaft speichern - dynamische Änderungen sind dabei nicht zulässig.

6. Meine Routine um einen deaktivierten sekundären Monitor zu aktivieren:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
Var
  lDevMode : TDevModeA_new;
  lRes : Cardinal;
begin
    FillChar(lDevMode, SizeOf(lDevMode), 0);

    lDevMode.dmSize := SizeOf(lDevMode);
    lDevMode.dmBitsPerPel := 32;
    lDevMode.dmDisplayFrequency := 85; // alles hard kodiert für meinen 2. Monitor
    lDevMode.dmPelsWidth := 1280;
    lDevMode.dmPelsHeight := 1024;
    lDevMode.Dual.Monitor.dmPosition.x := 1280; // die Weite/Auflösung des primären Monitors bzw. Lage des Monitors in Relation zum primären Monitor mit 0,0 oben links
    lDevMode.Dual.Monitor.dmPosition.y := 0;
    lDevMode.dmFields := DM_BITSPERPEL Or
                                          DM_DISPLAYFREQUENCY Or
                                          DM_PELSWIDTH Or
                                          DM_PELSHEIGHT Or
                                          DM_POSITION;

    lRes := ChangeDisplaySettingsEx( PChar('\\.\DISPLAY2'),
                             TDevMode(lDevMode),
                             0,
                             CDS_UPDATEREGISTRY,
                             0);

    If lres <> 0 Then
      ShowMessage('hat nicht geklappt');
end;
HTH

MfG
Muetze1

Bei delphi 2009 bringt diese Zeile


lRes := ChangeDisplaySettingsEx( PChar('\\.\DISPLAY2'),
TDevMode(lDevMode),
0,
CDS_UPDATEREGISTRY,
0);

einen Typenumwandlungsfehler, wie muss es denn geändert werden das es auch mit delphi 2009 geht?

Martin
ich weiss, das ich nichts weiss!
  Mit Zitat antworten Zitat
Y.Elm

Registriert seit: 19. Sep 2011
Ort: Berlin
21 Beiträge
 
Delphi 2010 Professional
 
#15

AW: Re: Monitor X per ChangeDisplaySettingsEx (A) akivieren ?

  Alt 23. Nov 2011, 11:10
Bei delphi 2009 bringt diese Zeile


lRes := ChangeDisplaySettingsEx( PChar('\\.\DISPLAY2'),
TDevMode(lDevMode),
0,
CDS_UPDATEREGISTRY,
0);

einen Typenumwandlungsfehler, wie muss es denn geändert werden das es auch mit delphi 2009 geht?

Martin
Die Antwort kommt wohl etwas spät, aber vielleicht hilft es ja doch noch jemandem:
Das Record TPrinterMonitor ist ja nicht viel mehr als eine Erweiterung von Windows.TDevMode.
Wenn man nun den ganzen Verweisen folgt, sieht man, dass TDevMode in älteren Delphi-Versionen letztendlich auf TDeviceModeA verweist. Durch die ganze Unicode-Umstellung ab Delphi 2009 verweist es nun aber auf TDeviceModeW.
Man muss also folgende Zeilen ändern, um TDevModeA_new zuweisungskompatibel zu TDeviceModeW zu machen:
Delphi-Quellcode:
  TDevModeW_new = packed record // Name wurde der Konsistenz halber geändert, ist aber nicht unbedingt nötig
    dmDeviceName: array[0..CCHDEVICENAME - 1] of WideChar;
    ...
    dmFormName: array[0..CCHFORMNAME - 1] of WideChar;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:01 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz