Formular Größe/WindowState merken und wiederherstellen

Rund um die LCL und andere Komponenten
Antworten
MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Formular Größe/WindowState merken und wiederherstellen

Beitrag von MmVisual »

Hallo,

Ich habe diesmal fast schon ein Anfängerproblem und ich bin mir da nicht sicher ob das nicht ein Lazarus Bug ist. Folgender Quellcode:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
Var Ini: TIniFile;
begin
  Ini := TIniFile.Create('my.ini');
  rcForm.Left := ini.ReadInteger('F', 'L', Left);
  rcForm.Top := ini.ReadInteger('F', 'T', Top);
  rcForm.Right := ini.ReadInteger('F', 'W', Width);
  rcForm.Bottom := ini.ReadInteger('F', 'H', Height);
  stWindowForm := TWindowState(ini.ReadInteger('F', 'S', ord(WindowState)));
  Ini.Free;
 
  Left := rcForm.Left;
  Top := rcForm.Top;
  Width := rcForm.Right;
  Height := rcForm.Bottom;
  WindowState := stWindowForm;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
Var Ini: TIniFile;
begin
  Ini := TIniFile.Create('my.ini');
  If WindowState = wsNormal Then
  Begin
    ini.WriteInteger('F', 'L', Left);
    ini.WriteInteger('F', 'T', Top);
    ini.WriteInteger('F', 'W', Width);
    ini.WriteInteger('F', 'H', Height);
  end;
  If WindowState <> wsMinimized Then
    ini.WriteInteger('F', 'S', ord(WindowState));
  ini.UpdateFile;
  ini.Free;
end;
Die Wunsch-Funktion:

- Formular wiederherstellen wsMaximized / wsNormal
- bei wsNormal die Position
- wenn wsMaximized ist und man drückt wsNormal (Border-Icon) dann soll das Formular auf die letzte bekannte (INI Datei) Größe/Position springen.

Das Vorgehen:
Start EXE, wsNormal.
Ende EXE, speichern Position + wsNormal
Start EXE, Position zeigt sich richtig
Drücke BorderIcon für wsMaximized
Ende EXE, speichert wsMaximized, keine Position
Start EXE, wiederherstellen von wsMaximized
Drücke BorderIcon für wsNormal >> Fehler Größe/Position falsch

Nun, ich habe darauf hin versucht das zu korrigieren indem ich diesen Code dazu geschrieben habe:

Code: Alles auswählen

procedure TForm1.FormWindowStateChange(Sender: TObject);
begin
  If (stWindowForm = wsMaximized) And (WindowState = wsNormal) Then
  Begin
    Left := rcForm.Left;
    Top := rcForm.Top;
    Width := rcForm.Right;
    Height := rcForm.Bottom;
    stWindowForm := wsMinimized;
  end;
end;
Jetzt wird zwar nach dem Status wechsel von wsMaximized > wsNormal das Formular korrekt positioniert aber:

EXE beenden speichert die falschen Werte in die INI Datei, also Width/Height werden nicht korrekt aus dem Formular gelesen.
Erst wenn das Formular ein mal verschoben wird, dann klappt das !?

Weiß jemand wie ich das anstelle, dass es richtig klappt?

Grüße Markus

Edit: Var rcForm: TRect;
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Formular Größe/WindowState merken und wiederherstellen

Beitrag von MmVisual »

Ich habe jetzt FormDestroy so abgeändert:

Code: Alles auswählen

procedure TForm1.FormDestroy(Sender: TObject);
Var Ini: TIniFile;
begin
  Ini := TIniFile.Create('my.ini');
  If WindowState = wsNormal Then
  Begin
    ini.WriteInteger('F', 'L', Left);
    ini.WriteInteger('F', 'T', Top);
    If (Width < Screen.WorkAreaWidth) And (Height < Screen.WorkAreaHeight) Then
    Begin
      ini.WriteInteger('F', 'W', Width);
      ini.WriteInteger('F', 'H', Height);
    End;
  end;
  If WindowState <> wsMinimized Then
    ini.WriteInteger('F', 'S', ord(WindowState));
  ini.UpdateFile;
  ini.Free;
end;
Jetzt funktioniert es zwar, aber irgendwie ist das ganze auch nicht das gelbe vom Ei.

Wie geht das richtig?

Grüße Markus.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Formular Größe/WindowState merken und wiederherstellen

Beitrag von Scotty »

Sieht doch ganz vernünftig aus. Ansonsten vielleicht TIniPropStorage.

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Formular Größe/WindowState merken und wiederherstellen

Beitrag von MmVisual »

Es funktioniert dennoch nicht richtig :(

Anbei mein Demo-Code:
TestForm.zip
(2.03 KiB) 54-mal heruntergeladen
- Start EXE
- Maximieren
- Ende EXE
- Start EXE
- Normal setzen (BorderIcon)
- >> BUG

Er setzt zwar jetzt die Form an die richtige Position / Größe
Aber der Inhalt des Formulars wird nicht angepasst, der glaubt immer noch "groß" zu sein. man sieht es daran, dass der rechte Scrollbalken vom TMemo nicht sichtbar ist.
Erst wenn man ein mal das Formular verschiebt passt sich der Inhalt an und man sieht wieder den Scrollbalken.

Ein Refresh oder Repaint hilft da auch nicht.

Weiß noch jemand Rat?

Grüße Markus.

Edit, ich teste das mit TIniPropStorage morgen. Ich müsste die Kompo wohl irgendwie umbiegen so dass ich die Daten in eine eigene Textdatei speichern kann, da meine EXE das schlussendlich anders handhabt. Nur in dem Demo Code habe ich eine INI Datei der Einfachheit halber genommen.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Formular Größe/WindowState merken und wiederherstellen

Beitrag von MmVisual »

Der Krückstock wird immer größer...

Jetzt habe ich nicht mehr die Größe im Event FormWindowStateChange() gesetzt, sondern nur noch einen Timer mit Intervall 1ms gestartet. der wiederum positioniert das Formular richtig:

SetBounds(rcForm.Left, rcForm.Top, rcForm.Right, rcForm.Bottom);

Und dann klappt das ganze auch.

Nachteil: im Bildschirm zappelt das ganze wild durch die Gegend.

Aber das muss doch irgendwie eleganter gehen :?:
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten