![]() |
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 |
Re: Positionen aller Forms wiederherstellen
Zitat:
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. |
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:
für jede Form eine Ini Datei mit entsprechendem Namen
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; Die Unter-/Überschreitung der Grenzen musst du noch einbauen lg busy |
Re: Positionen aller Forms wiederherstellen
Zitat:
|
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 |
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:
|
Re: Positionen aller Forms wiederherstellen
Zitat:
|
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:
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?
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; Gruß und Dank, Alexander |
Re: Positionen aller Forms wiederherstellen
Hallo,
Zitat:
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:
Ich benutze Formular-Vererbung, nur mein Basis-Form enthält den "2-Zeiler". In keinem anderem Form steht was form LoadPosition, wozu auch ? Heiko |
Re: Positionen aller Forms wiederherstellen
Zitat:
Delphi-Quellcode:
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).
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; 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 12:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz