Jump to content
Sign in to follow this  
Squall_FF8

[Resolved] Window State and position saver

Recommended Posts

Hi guys,

 

I want to save/load the main window position, size, state so every time you reopen it, it looks the it was when you close it.

So the snippet bellow. It works ,... almost. When I close the app with a maximized window, after relaunch it is maximized, If I click the button to make it Normal, it doesnt go where I left it previously before maximizing.
Can you help me? What I'm missing?

 

P.S. If it matters, I use Delphi 12.2, on Win 10.
 

OnCreate:
  Left   := ini.ReadInteger(cSection, 'Left', Left);
  Top    := ini.ReadInteger(cSection, 'Top', Top);
  Width  := ini.ReadInteger(cSection, 'Width', Width);
  Height := ini.ReadInteger(cSection, 'Height', Height);
  WindowState := tWindowState(ini.ReadInteger(cSection, 'State', ord(WindowState)));

OnDestroy:
  ini.WriteInteger(cSection, 'State', ord(WindowState));
  if WindowState = wsNormal then begin
    ini.WriteInteger(cSection, 'Left', Left);
    ini.WriteInteger(cSection, 'Top', Top);
    ini.WriteInteger(cSection, 'Width', Width);
    ini.WriteInteger(cSection, 'Height', Height);
  end;

 

Edited by Squall_FF8

Share this post


Link to post

This works for me:

uses
  Math;

procedure TFormMain.ApplyWindowState(const Bounds: TRect; State: TWindowState);
var
  Monitor: TMonitor;
  WorkareaRect: TRect;
  NewTop, NewLeft, NewWidth, NewHeight: integer;
begin
  ASSERT(Position= poDesigned);

// Find the monitor containing the top/left corner.
  // If the point is outside available monitors then the nearest monitor is used.
  Monitor := Screen.MonitorFromPoint(Bounds.TopLeft);

  WorkareaRect := Monitor.WorkareaRect;

  NewHeight := Min(Bounds.Bottom-Bounds.Top, WorkareaRect.Bottom-WorkareaRect.Top);
  NewWidth := Min(Bounds.Right-Bounds.Left, WorkareaRect.Right-WorkareaRect.Left);

  if (PtInRect(WorkareaRect, Bounds.TopLeft)) then
  begin
    NewTop := Bounds.Top;
    NewLeft := Bounds.Left;
  end else
  begin
    // Center on monitor if top/left is outside screen (e.g. if a monitor has been
    // removed)
    NewTop := WorkareaRect.Top + ((WorkareaRect.Bottom-WorkareaRect.Top) - NewHeight) div 2;
    NewLeft := WorkareaRect.Left + ((WorkareaRect.Right-WorkareaRect.Left) - NewWidth) div 2;
  end;

  SetBounds(NewLeft, NewTop, NewWidth, NewHeight);

  if (State in [wsNormal, wsMaximized]) then
    WindowState := State;
end;

...

procedure TFormMain.FormCreate(Sender: TObject);
begin
  ApplyWindowState(Rect(100, 100, 400, 400), wsMaximized);
end;

 

Share this post


Link to post
25 minutes ago, Squall_FF8 said:

Hi guys,

 

I want to save/load the main window position, size, state so every time you reopen it, it looks the it was when you close it.

So the snippet bellow. It works ,... almost. When I close the app with a maximized window, after relaunch it is maximized, If I click the button to make it Normal, it doesnt go where I left it previously before maximizing.
Can you help me? What I'm missing?

 

P.S. If it matters, I use Delphi 12.2, on Win 10.

 

Set the DefaultMonitor property of the form to dmDesktop, this way the form left and top do not depend on the monitor the form is on and will restore the form to the monitor it was on before (unless the user rearranges his desktop configuration). For the necessary code see the PB.Winset unit in the attached archive.

Winset.zip

Share this post


Link to post
13 minutes ago, PeterBelow said:

Set the DefaultMonitor property of the form to dmDesktop, this way the form left and top do not depend on the monitor the form is on and will restore the form to the monitor it was on before (unless the user rearranges his desktop configuration). For the necessary code see the PB.Winset unit in the attached archive.

Winset.zip

Woah, THANK YOU!!!
It worked just by changing it! I was afraid its going to be something about DPI awareness (new in Delphi, staring with  12) 

Share this post


Link to post

I always drop a Jedi's JvFormStorage on my form and that's it..

Quote

Use a TJvFormStorage component to store and retrieve data from a storage. Use in combination with TJvAppStorage-descendants like TJvAppIniFileStorage (to use ini-files), TJvAppRegistryStorage (-> Registry) or similar. The component can store, retrieve and restore published properties of any component on the form.

and the position and state..

Share this post


Link to post
43 minutes ago, Die Holländer said:

and that's it..

"that's it" meaning "implicitly include the 347 other units it depends on".

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×