Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Fensterposition sowie -größe auf zweitem Monitor speichern und laden (https://www.delphipraxis.net/196056-fensterposition-sowie-groesse-auf-zweitem-monitor-speichern-und-laden.html)

günni0 19. Apr 2018 11:42


Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Die Fensterposition und -größe zu speichern ist absolut kein Problem.

Jetzt wäre ich noch gerne in der Lage zu speichern und laden, auf welchem Monitor das Formular zuletzt war.
Ich habe schon ein bisschen mit Screen.Monitors[] rumgespielt aber das bringt mich nicht weiter, da ich weder laden noch speichern kann.

Mein Grundgedanke:
beim Speichern
Delphi-Quellcode:
X := Screen.MonitorFromWindow(FormHandle... )
showmessage( X.MonitorNum.ToString );
um den Monitor zu bekommen.
Aber wie lade ich das nun und zeige das Formular auch auf diesem Monitor wieder an?

Solche Sachen wie "MonitorLinks.Breite + ....." und sowas kann man ja total vergessen. Denn nicht jeder hat die Monitore nebeneinander.

Zacherl 19. Apr 2018 11:48

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Zitat von günni0 (Beitrag 1399826)
Solche Sachen wie "MonitorLinks.Breite + ....." und sowas kann man ja total vergessen. Denn nicht jeder hat die Monitore nebeneinander.

Mir wäre nicht bekannt, dass man eine Art "id" des Monitors abfragen kann. Der Desktop ist ein Bereich, der zusammengesetzt wird aus Höhe und Breite aller Monitore. Die Anordnung kann deshalb ja z.B. in der Windows Systemsteuerung explizit angegeben werden. Wenn sich hier etwas ändert wären gespeicherte Positionen natürlich hinfällig (aber mal ehrlich, wie oft kommt sowas vor?). Zut Not kann man hier zumindest noch testen, ob die Dimensionen des kompletten Desktops sich geändert haben und ggfls. die gesicherten Fensterpositionen verwerfen.

Delphi-Quellcode:
MonitorFromWindow
arbeitet auch mit der Fensterposition bzw. genauer gesagt "The MonitorFromWindow function retrieves a handle to the display monitor that has the largest area of intersection with the bounding rectangle of a specified window".

günni0 19. Apr 2018 11:49

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Das heißt ich speichere aktuell falsch. Aktuell speichere ich einfach nur X und Y vom "Monitor" und achte gar nicht drauf welcher.

Aktuell übergebe ich meiner Funktion schlicht
Delphi-Quellcode:
aForm.Width, aForm.Height, aForm.Left, aForm.Top
und speichere das in 4 ini idents ab.
Wie müsste man das denn abspeichern, um MultiMonitor-Support zu gewährleisten?

Zacherl 19. Apr 2018 11:52

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Zitat von günni0 (Beitrag 1399828)
Das heißt ich speichere aktuell falsch. Aktuell speichere ich einfach nur X und Y vom "Monitor" und achte gar nicht drauf welcher.

Ich würde einfach X und Y vom Fenster speichern. Diese Koordinaten beziehen sich eh auf den kompletten Desktop. Also links vom primären Bildschirm sind die (X-)Koordinaten negativ.

Edit:
Du hast grade editiert. So wie du es machst, sollte es "automatisch" schon passen :)

günni0 19. Apr 2018 11:57

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Leider nicht. Ich speichere X, Y Höhe und Breite ganz normal.

Beim Laden gehe ich so vor

Delphi-Quellcode:
  _Screen := Screen.MonitorFromWindow(frmMain.Handle);
 
  if IniFrm.ValueExists('window_options', 'x') and IniFrm.ValueExists('window_options', 'y') then
   begin
    x := IniFrm.ReadInteger('window_options', 'x', (_Screen.Width - frmOptions.Width) div 2);
    y := IniFrm.ReadInteger('window_options', 'y', (_Screen.Height - frmOptions.Height) div 2);
   end
  else
   begin
    x := (_Screen.Width - frmOptions.Width) div 2;
    y := (_Screen.Height - frmOptions.Height) div 2;
   end;

  frmOptions.Left := x;
  frmOptions.Top := y;

Zacherl 19. Apr 2018 11:58

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Lass das ganze Gedöhns mit dem Screen einfach weg :P Einfach nur X, Y, Width, Height speichern und 1 zu 1 wieder laden. Auf dem richtigen Monitor landet das Fenster dann automatisch.

günni0 19. Apr 2018 11:59

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Einfach nur X, Y, Width, Height speichern und 1 zu 1 wieder laden
mache ich doch :P

Das Screens ist nur für die Ini-Default-Werte da, falls beim Auslesen was nicht klappt.

Zacherl 19. Apr 2018 12:00

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Zitat von günni0 (Beitrag 1399834)
Das Screens ist nur für die Ini-Default-Werte da, falls beim Auslesen was nicht klappt.

Mein Fehler, falsch gelesen.

Was genau funktioniert beim Laden denn nicht? Die Positionen sind falsch?

haentschman 19. Apr 2018 12:01

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Einfach nur X, Y, Width, Height speichern
...und X und Y durch Form.Top und Form.Left ersetzen. :zwinker:
Hinweis:
Das Laden/Setzen der Werte im OnShow.

günni0 19. Apr 2018 12:02

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Die Position vom Hauptfenster wird wohl korrekt geschrieben (rechter Monitor).
Delphi-Quellcode:
[window_main]
x=2139
y=196
Beim Laden landet es aber auf Monitor 1 (also der linke)

Ich setze Top und Left im OnCreate-Event.

Jumpy 19. Apr 2018 12:02

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Evtl. könnte man noch speichern, ob das Fenster maximiert ist usw.

Zacherl 19. Apr 2018 12:03

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Also ich hab mir grade mal ein Testprogramm geschrieben und da funktioniert alles wie es soll. Muss ein Problem bei der Verarbeitung (Ini, etc.) vorliegen:
Delphi-Quellcode:
uses
  Clipbrd;

procedure TForm2.Button1Click(Sender: TObject);
var
  S: String;
begin
  S := Left.ToString + ',' + Top.ToString + ',' + Width.ToString + ',' + Height.ToString;
  Clipboard.AsText := S;
end;

procedure TForm2.Button2Click(Sender: TObject);
var
  A: TArray<String>;
begin
  A := Clipboard.AsText.Split([',']);
  Left := A[0].ToInteger;
  Top := A[1].ToInteger;
  Width := A[2].ToInteger;
  Height := A[3].ToInteger;
end;
Edit:
Der Hinweis von haentschman bezüglich OnShow ist wichtig, wenn es sich um das (aktuelle) eigene Fenster handelt.

Uwe Raabe 19. Apr 2018 12:43

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Zitat von günni0 (Beitrag 1399838)
Ich setze Top und Left im OnCreate-Event.

Dann setz dort doch auch noch
Delphi-Quellcode:
Position := poDesigned
- vielleicht steht da ja noch was anderes drin.

günni0 19. Apr 2018 12:47

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
poDesigned war schon gesetzt.

Der Tipp mit OnShow hat geholfen. Tatsächlich darf man wohl keine Fensterpositionen im OnCreate setzen.

TigerLilly 20. Apr 2018 07:31

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Aber Achtung: Das Fenster wird dorthin verschoben, egal, ob es die Position/den Monitor auch gibt + wird damit uU unsichtbar.

Haben wir immer wieder, wenn Benutzer den zweiten Monitor nicht aufdrehen oder von einem anderen Rechner mit nur einem Monitor aus arbeiten. :-/

günni0 20. Apr 2018 07:36

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Da bietet das Forum eine einfache Lösung für

https://www.delphipraxis.net/1359914-post7.html

markus5766h 22. Apr 2018 21:40

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1399853)
Zitat:

Zitat von günni0 (Beitrag 1399838)
Ich setze Top und Left im OnCreate-Event.

Dann setz dort doch auch noch
Delphi-Quellcode:
Position := poDesigned
- vielleicht steht da ja noch was anderes drin.

... müsste es nicht
Delphi-Quellcode:
Position := poDefault
sein - o.k. es funktioniert beides . . .

markus5766h 22. Apr 2018 21:41

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Zitat von günni0 (Beitrag 1399855)
. . .Tatsächlich darf man wohl keine Fensterpositionen im OnCreate setzen.

doch, sollte auch im OnCreate funktionieren.

Redeemer 22. Apr 2018 23:14

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Bei mir funktioniert es auch in
Delphi-Quellcode:
OnCreate
.

Zitat:

Zitat von TigerLilly (Beitrag 1399916)
Aber Achtung: Das Fenster wird dorthin verschoben, egal, ob es die Position/den Monitor auch gibt + wird damit uU unsichtbar.

Haben wir immer wieder, wenn Benutzer den zweiten Monitor nicht aufdrehen oder von einem anderen Rechner mit nur einem Monitor aus arbeiten. :-/

Nach dem Laden der Position:
Delphi-Quellcode:
if Screen.MonitorFromWindow(Handle, mdNull) = nil then
Position := poScreenCenter;

haentschman 23. Apr 2018 05:48

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Moin...:P
Zitat:

Bei mir funktioniert es auch in OnCreate .
...eben, weil du nicht nicht Left und Top der Form setzt sondern nur poScreenCenter.

samso 23. Apr 2018 07:38

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Zitat:

Zitat von haentschman (Beitrag 1400192)
Moin...:P
Zitat:

Bei mir funktioniert es auch in OnCreate .
...eben, weil du nicht nicht Left und Top der Form setzt sondern nur poScreenCenter.

Das sehe ich nicht so. Folgendes Testprogramm funktioniert wunderbar (d.h. das Formular wird wie gewünscht auf dem rechten Monitor angezeigt)
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Position := poDesigned;
  Left := 2000; Top := 800;
end;

rokli 23. Apr 2018 11:11

AW: Fensterposition sowie -größe auf zweitem Monitor speichern und laden
 
Unabhängig von der Anzahl der Monitore verwende ich schon sehr lange die folgenden INIs:

Beim Programmstart:

Delphi-Quellcode:
procedure p_IniRead(AForm : TCustomForm);
// INI Datei einlesen und Fensterpositionen bestimmen
var
   Ini         : TIniFile;
   tmpFormName : string;
begin
   Ini          := TIniFile.Create(ChangeFileExt( Application.ExeName, '.INI' ) );
   try
      tmpFormName      := AForm.Name;
      AForm.Top      := Ini.ReadInteger(tmpFormName, 'Top', AForm.Top );
      AForm.Left      := Ini.ReadInteger(tmpFormName, 'Left', AForm.Left );
      AForm.Height   := Ini.ReadInteger(tmpFormName, 'Height', AForm.Height);
      AForm.Width      := Ini.ReadInteger(tmpFormName, 'Width', AForm.Width);
      if Ini.ReadBool( tmpFormName, 'InitMax', false ) then
         AForm.WindowState := wsMaximized
      else
         AForm.WindowState := wsNormal;
   finally
      Ini.Destroy;
   end;

   if Screen.MonitorFromWindow(aForm.Handle, mdNull) = nil then begin
      // Form is outside of any monitor. Move to center of main monitor
      aForm.Top      := (Screen.Monitors[0].Height - aForm.Height) div 2;
      aForm.Left      := (Screen.Monitors[0].Width - aForm.Width) div 2;
   end;

end;
und wenn Fenster geschlossen werden, speichern der Fensterpositionen:

Delphi-Quellcode:
procedure TFrmMain.p_IniFormPosRead(AForm : TCustomForm);
// Position der Form merken
var
   Ini         : TIniFile;
   tmpFormName : string;
begin
   Ini          := TIniFile.Create(ChangeFileExt( Application.ExeName, '.INI' ) );
   try
      tmpFormName      := AForm.Name;
      AForm.Top      := Ini.ReadInteger(tmpFormName, 'Top', AForm.Top );
      AForm.Left      := Ini.ReadInteger(tmpFormName, 'Left', AForm.Left );
      AForm.Height   := Ini.ReadInteger(tmpFormName, 'Height', AForm.Height);
      AForm.Width      := Ini.ReadInteger(tmpFormName, 'Width', AForm.Width);
      if Ini.ReadBool( tmpFormName, 'InitMax', false ) then
         AForm.WindowState := wsMaximized
      else
         AForm.WindowState := wsNormal;
   finally
      Ini.Destroy;
   end;
Und durch die Weitergabe der Form klappt das auch mit beliebigen Fenstern in einem Programm. Und das Handling, wenn mal nur ein Monitor vorhanden ist, ist auch gleich enthalten (wurde aber oben ja auch schon gezeigt).

Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:51 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