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