8
votes

This question seems easy but for some reason I have trouble finding the answer.

I have an application that saves the form's size and position on an INI file. That's all an well, however when you close the application when maximized it will save the size and position of the form maximized but not its state.

What I mean is that on the next run the form would appear maximized when in fact it's "restored" but covering the whole desktop.

Is there a way to save the form size previous to the maximize event, then save the fact that the form is maximized. The on the read from the INI file create the form in a maximized state and set its "restore" size to the one before the maximize event?

thanks!

4

4 Answers

12
votes

Use the Windows API function GetWindowPlacement(), like so:

procedure TForm1.WriteSettings(AUserSettings: TIniFile);
var
  Wp: TWindowPlacement;
begin
  Assert(AUserSettings <> nil);

  if HandleAllocated then begin
    // The address of Wp should be used when function is called
    Wp.length := SizeOf(TWindowPlacement);
    GetWindowPlacement(Handle, @Wp);

    AUserSettings.WriteInteger(SektionMainForm, KeyFormLeft,
      Wp.rcNormalPosition.Left);
    AUserSettings.WriteInteger(SektionMainForm, KeyFormTop,
      Wp.rcNormalPosition.Top);
    AUserSettings.WriteInteger(SektionMainForm, KeyFormWidth,
      Wp.rcNormalPosition.Right - Wp.rcNormalPosition.Left);
    AUserSettings.WriteInteger(SektionMainForm, KeyFormHeight,
      Wp.rcNormalPosition.Bottom - Wp.rcNormalPosition.Top);
    AUserSettings.WriteBool(SektionMainForm, KeyFormMaximized,
      WindowState = wsMaximized);
  end;
end;
3
votes

Try the Form.WindowState property. By reading this, you can write it to the ini file, then read back from the ini to re-set the state in the form.show method. You might want to re-cast it to an integer as the WindowState is an enumerated type (TWindowState).

3
votes

Tom's answer should work nicely. Here is some Pseudo-Code to clarify a little:

procedure TfrmDatenMonitor.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  inherited;
  //*** Save the WindowState in every case
  aIniFile.WriteInteger(Name, 'State', Integer(WindowState));

  if WindowState = wsNormal then begin
    //*** Save Position and Size, too...
    aIniFile.WriteInteger(Name, 'Top',    Top);
    aIniFile.WriteInteger(Name, 'Left',   Left);
    aIniFile.WriteInteger(Name, 'Height', Height);
    aIniFile.WriteInteger(Name, 'Width',  Width);
  end;
end;

when reading the settings set Size and Position first. Then read the WindowState and assign it with a typecast:

WindowState := TWindowState(aIniFile.ReadInteger(Name, 'State', Integer(wsNormal)));
0
votes

DelphiDabbler has some nice window state components. You just drop one on your form and it will save the state to an ini file or the registry on form destroy and load it on form create.