Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Positionen aller Forms wiederherstellen (https://www.delphipraxis.net/146050-positionen-aller-forms-wiederherstellen.html)

Schwedenbitter 12. Jan 2010 23:08


Positionen aller Forms wiederherstellen
 
Hallo,

ich habe ein Programm bestehend aus mehreren Forms. Die Position der Hauptform (Top, Left, Height, Width) speichere ich beim Beenden in der Registry und lade sie bei einem Neustart. Die Positionen der SubForms kann ich auch speichern. Es hapert aber am Wiederherstellen. Da das Ereignis OnCreate() des MainForm vor dem aller anderen Forms ausgeführt wird und diese noch nicht angelegt sind, geht es dort nicht.

Ich hatte dann die Idee, die Create-Reihenfolge zu ändern, so dass alle Fenster angelegt sind, wenn das MainForm schließlich angelegt wird. Aber leider ist Application.MainForm nur ReadOnly, so dass auch das nicht geht.
In einem früheren Programm hatte ich das so "gelöst", dass ich mir die Positionen beim Schließen der Fenster immer merkte und vor jedem neuen Anzeigen wieder setzte; das ist aber sehr umständlich.

Gibt es andere Möglichkeiten?

Gruß und danke für Ideen, Alex

Hansa 13. Jan 2010 00:57

Re: Positionen aller Forms wiederherstellen
 
Zitat:

Zitat von Schwedenbitter
..In einem früheren Programm hatte ich das so "gelöst", dass ich mir die Positionen beim Schließen der Fenster immer merkte und vor jedem neuen Anzeigen wieder setzte; das ist aber sehr umständlich...

Inwiefern ist das umständlich ? :shock: Ich lese den Krempel im OnShow ein und schreibe den aktuellen Stand im OnClose wieder weg. Die können da ziehen und machen, was sie wollen. Wenn man dann noch den Speicherort der INI-Datei, die das speichert individuell macht, also User, AllUser oder sonstwas, dann hat sogar jeder seinen eigenen Stand.

Da anzunehmen ist, dass auch Fenster in unsichtbare Bereiche verschoben werden, an kaum sichtbaren Rand etc., Dann kann man die entsprechenden INIs ja auch mal einfach sichern ud wiederherstellen. Und diese Funktionalität würde ich den Forms von Anfang an mitgeben.

busybyte 13. Jan 2010 02:07

Re: Positionen aller Forms wiederherstellen
 
Delphi-Quellcode:
Function GetPlacement(AForm:TForm):TRect;
Var WP : TWindowPlacement;
begin
GetWindowPlacement(AForm.Handle, @WP);

with WP.rcNormalPosition do
begin
Result.Top:=Top;
Result.Left:=Left+Screen.WorkAreaLeft; //Taskleiste links/rechts oder unten? 
Result.Right:=Right+Screen.WorkAreaLeft;
Result.Bottom:=Bottom;
end;
end;


Function Save_Ini_Others(Form_:TForm;Filename_:String;Typ_:integer):Boolean;
var
  Ini: TIniFile;
  Section:String;
  FN_:String;
  FP_:String;
  R_:TRect;
begin
Result:=False;
FN_:=Filename_;
 while trim(FN_)='' do
  exit;

FP_:=Extractfilepath(FN_);
while trim(FP_)='' do
exit;

if not DirectoryExists(FP_) then
    ForceDirectories(FP_);

    Deletefile(PCHar(FN_));
    Ini:=TIniFile.Create(FN_);
    try
     with ini do
       begin
       Section:=Form_.Name;
       WriteInteger(Section,'WindowState',Integer(Form_.WindowState));
        case typ_ of
             0:R_:=GetPlacement(Form_); //Sizeable/Minimier-/Maximierbar
             1:R_:=Form_.BoundsRect; //Fix
        end;
       WriteInteger(Section,'Left',Integer(R_.Left));
       WriteInteger(Section,'Top',Integer(R_.Top));
       WriteInteger(Section,'Width',Integer(R_.Right-R_.Left));
       WriteInteger(Section,'Height',Integer(R_.Bottom-R_.Top));
       end;

  Result:=True;
 finally
 Ini.Free;
 end;
end;
Delphi-Quellcode:
Function Load_Ini_Others(Form_:TForm;Filename_:String;Typ:Integer):Boolean;
var
  Ini: TIniFile;
  Section:String;
  IntData:integer;
  FN_:String;
begin
Result:=False;

  FN_:=Filename_;
  while not Fileexists(FN_) do
  exit;

  Ini:=TIniFile.Create(FN_);
  try
   with Ini do
   begin
    Section:=Form_.Name;

    IntData:=ReadInteger(Section,'WindowState',-1);
    //...Windowstate... bei mir aber standard verkleinert

    IntData:=ReadInteger(Section,'Left',screen.WorkAreaLeft);
    Form_.Left:=IntData;
    IntData:=ReadInteger(Section,'Top',screen.DesktopTop);
    Form_.Top:=IntData;

    case Typ of
     1:; //Fix
     else begin
          IntData:=ReadInteger(Section,'Width',400);
          Form_.Width:=IntData;
          IntData:=ReadInteger(Section,'Height',300);
          Form_.Height:=IntData;
          end;
    end;

    end;
   end;
 result:=True;
finally ini.Free;end;
end;
für jede Form eine Ini Datei mit entsprechendem Namen
Die Unter-/Überschreitung der Grenzen musst du noch einbauen

lg busy

Hansa 13. Jan 2010 02:32

Re: Positionen aller Forms wiederherstellen
 
Zitat:

Zitat von busybyte
..für jede Form eine Ini Datei mit entsprechendem Namen
lg busy

Wozu denn das ? :shock: Jede Form hat einen Namen und der reicht aus, um das in EINE Datei zu packen.

busybyte 13. Jan 2010 02:36

Re: Positionen aller Forms wiederherstellen
 
dann muss er aber das deletefile weglassen bzw. nur bei der ersten aufrufenden Form ausführen
Ohne Deletefile werden leider alte Datenleichen in der Ini nicht gelöscht

Hansa 13. Jan 2010 02:51

Re: Positionen aller Forms wiederherstellen
 
Mit Verlaub gesagt : Dein Source ist allenfalls für Sakura gut. :mrgreen: :lol: Wozu soll der gut sein ? Das kann man mit 2 Zeilen erledigen. Gucke mir den Source auch nicht gross an. Mit DeleteFile soll was gelöscht werden, oder ? Soll die INI immer wieder neu aufgebaut werden oder was ? Wozu das Ganze ? :shock:

busybyte 13. Jan 2010 03:20

Re: Positionen aller Forms wiederherstellen
 
Zitat:

Mit Verlaub gesagt : Dein Source ist allenfalls für Sakura gut. Wozu soll der gut sein ? Das kann man mit 2 Zeilen erledigen. Gucke mir den Source auch nicht gross an. Mit DeleteFile soll was gelöscht werden, oder ? Soll die INI immer wieder neu aufgebaut werden oder was ? Wozu das Ganze ? Shocked
zeigst du mir die 2 zeilen mal bitte? ich lerne gerne was dazu

Schwedenbitter 13. Jan 2010 09:23

Re: Positionen aller Forms wiederherstellen
 
Danke für Eure Antworten / Ideen!

Spricht irgend etwas gegen meine Lösung, außer das das Laden nicht funktioniert?
Mit den 2 zusätzlichen Zeilen je Fensteraufruf könnte ich prima leben:

Delphi-Quellcode:
Function SaveWinPos(Wnd: TForm; Key: String): Boolean;
Var
   WP            : TWindowPlacement;
Begin
   Result:=False;
   WP.Length:=SizeOf(TWindowPlacement);
   GetWindowPlaceMent(Wnd.Handle, @WP);
   With TRegistry.Create(KEY_ALL_ACCESS) Do
   Try
      RootKey:=HKEY_CURRENT_USER;
      Try
         OpenKey(Key, True);
         WriteBinaryData(Wnd.Name, WP, WP.length);
         CloseKey;
         Result:=True;
      Except End;
   Finally
      Free;
   End;
End;

Function LoadWinPos(Wnd: TForm; Key: String): Boolean;
Var
   WP            : TWindowPlacement;
Begin
   Result:=False;
   WP.Length:=SizeOf(TWindowPlacement);
   With TRegistry.Create(KEY_READ) Do
   Try
      RootKey:=HKEY_CURRENT_USER;
      Try
         OpenKeyReadOnly(Key);
         ReadBinaryData(Wnd.Name, WP, WP.length);
         CloseKey;
         SetWindowPlaceMent(Wnd.Handle, @WP);
         Result:=True;
      Except End;
   Finally
      Free;
   End;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
   LoadWinPos(Form2, 'Alexander_Test');
   Form2.ShowModal;
   SaveWinPos(Form2, 'Alexander_Test');
end;
Wenn ich es so laufen lasse, dann setzt er zwar die Fensterposition. Allerdings lässt sich das Fenster dann nicht mehr bewegen und das Programm stürzt damit ab. Kann mir jemand die Ursache sagen?

Gruß und Dank, Alexander

hoika 13. Jan 2010 12:31

Re: Positionen aller Forms wiederherstellen
 
Hallo,

Zitat:

Spricht irgend etwas gegen meine Lösung, außer das das Laden nicht funktioniert?
Warum funktioniert das nicht?
Dann ist doch der Code fehlerhaft,
überscheibt im schlimmsten Fall Speicher !!!
Dann brauchst du dich nicht wundern, dass es kracht.

Erstelle mal ein Bsp-Projekt, was den Fehler reproduziert.
Kann es sein, dass du immer noch was im OnForm von Form2 stehen hast ?

Oder kommentiere mal nach und nach aus.
Was soll dieses

WP.Length:=SizeOf(TWindowPlacement);

?

Zitat:

In einem früheren Programm hatte ich das so "gelöst", dass ich mir die Positionen beim Schließen der Fenster immer merkte und vor jedem neuen Anzeigen wieder setzte; das ist aber sehr umständlich.
Warum ist das umständlich ?

Ich benutze Formular-Vererbung,
nur mein Basis-Form enthält den "2-Zeiler".

In keinem anderem Form steht was form LoadPosition, wozu auch ?


Heiko

Hansa 13. Jan 2010 12:43

Re: Positionen aller Forms wiederherstellen
 
Zitat:

Zitat von busybyte
..zeigst du mir die 2 zeilen mal bitte? ich lerne gerne was dazu

Delphi-Quellcode:
procedure TfrmAus.FormShow(Sender: TObject);
var FensterIni : TIniFile;
begin
  FensterIni := TIniFile.Create(FensterDateiName);
  try
    Left  := FensterIni.ReadInteger(Name,'Left',Left);
    Top   := FensterIni.ReadInteger(Name,'Top',Top);
// + sonstiges formspezifische
  finally
    FensterIni.Free;
  end;
Das steht auch in deinem Source drin. Nur : das Drumrum ist überflüssig und versteht auch kaum einer. Wie hoika sagt : vererbe solche Sachen. Es gilt lediglich, die einmal zu schreiben und prompt hat jede Form diese Funktionalität (->Objektablage).

Stop, das ist ja nur das, wenn die Form neu angezeigt wird. Um sich das zu merken :

Delphi-Quellcode:
procedure TfrmAus.FormClose(Sender: TObject;
  var Action: TCloseAction);
var FensterIni : TIniFile;
begin
  try
    FensterIni := TIniFile.Create(FensterDateiName); //FensterDateiName));
    if not CDstart then begin // auf CD kann nicht gespeichert werden !
      FensterIni.WriteInteger(Name,'Left',Left);
      FensterIni.WriteInteger(Name,'Top',Top);
    end;
  finally
    FensterIni.Free;
  end;
  Action := caFree;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:33 Uhr.
Seite 1 von 2  1 2      

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