Recent

Author Topic: Correct way to save application state on exit  (Read 4506 times)

_N_

  • New Member
  • *
  • Posts: 33
Correct way to save application state on exit
« on: February 04, 2018, 09:14:16 am »
Hello.
I need to save some data before my application exits. I do that in FormDestroy. But this approach works fine when I close my application via menu (handler just invokes Application.Terminate) or with the window button. It doesn't work when user reboot/turn off computer.
I also tried
Code: Pascal  [Select][+][-]
  1. Self.OnExit := @Self.OnExitHandler; // code is copied from FormDestroy and FormDestroy is cleaned
but it doesn't work at all (even via menu) for me as well as
Code: Pascal  [Select][+][-]
  1. Application.AddOnEndSessionHandler(@Self.OnExitHandler);

My question: what is the right way to save state on application exit? As I understand, before reboot/shutdown OS asks an app to close, why the handler with FormDestroy doesn't work then? And what Form.OnExit and Application.AddOnEndSessionHandler are supposed to do (and when, because they wasn't invoked in my app)?

I tried it on Windows XP and 7. Lazarus 1.6.4, FPC 3.0.2
Thanks for help.

_N_

  • New Member
  • *
  • Posts: 33
Re: Correct way to save application state on exit
« Reply #1 on: February 04, 2018, 10:29:25 am »
I found what is Self.OnExit.  From docs:
Quote
Handler for control loosing the focus. This is a good place for checking the finished user input.

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Correct way to save application state on exit
« Reply #2 on: February 04, 2018, 10:53:12 am »
Try this...

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
  9.  
  10. type
  11.   TForm1 = class(TForm)
  12.    ApplicationProperties1: TApplicationProperties;
  13.    procedure ApplicationProperties1EndSession(Sender: TObject);
  14.   end;
  15.  
  16. var
  17.   Form1: TForm1;
  18.  
  19. implementation
  20.  
  21. {$R *.lfm}
  22.  
  23.  
  24. procedure TForm1.ApplicationProperties1EndSession(Sender: TObject);
  25. begin
  26.  // Shutdown Save
  27. end;
  28.  
  29. end.


You can use FormCloseQuery for example...
Code: Pascal  [Select][+][-]
  1. Procedure TwndGUI.FormCloseQuery(Sender: TObject; Var CanClose: Boolean);
  2.  Begin
  3.   If Memo.Modified
  4.   Then
  5.    If Memo.Text <> ''
  6.    Then
  7.     Begin
  8.      If Saved
  9.      Then CanClose:= True
  10.      Else CanClose:= False;
  11.     End;
  12.  End;

« Last Edit: February 04, 2018, 11:02:19 am by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

_N_

  • New Member
  • *
  • Posts: 33
Re: Correct way to save application state on exit
« Reply #3 on: February 04, 2018, 12:40:16 pm »
RAW, thank you for your answer.
I tried to use FormCloseQuery but it works weird... When I close form via window button everything is ok, but when I close it via menu neither Application.Terminate nor MainForm.Close doesn't work.
As about TApplicationProperties it doesn't work at all. Shouldn't I register them somewhere?

_N_

  • New Member
  • *
  • Posts: 33
Re: Correct way to save application state on exit
« Reply #4 on: February 04, 2018, 12:44:46 pm »
Also I've tried
Code: Pascal  [Select][+][-]
  1. MainForm.AddHandlerClose(@OnExitHandler);

but it doesn't work with reboot/shutdown  :(

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Correct way to save application state on exit
« Reply #5 on: February 04, 2018, 12:46:22 pm »
If you use Application.Terminate directly (not recommended for normal apps...), then the code inside FormCloseQuery and FormClose won't be executed.
You can drag TApplicationProperties (Additional Tab) onto your form and take a look at the events... works perfectly for me.


EDIT: Load the lpi-File inside Shutdown.zip...
The normal way to close an application is just "CLOSE".
« Last Edit: February 04, 2018, 01:09:01 pm by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

_N_

  • New Member
  • *
  • Posts: 33
Re: Correct way to save application state on exit
« Reply #6 on: February 04, 2018, 01:21:05 pm »
Thanks for sample. I added code (into both handlers), which writes Form1.Left into file, but nothing happened. Then I just set breakpoints there and close the form via windows button, but it never stops on them  %)

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Correct way to save application state on exit
« Reply #7 on: February 04, 2018, 01:32:32 pm »
This works for me...

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ApplicationProperties1EndSession(Sender: TObject);
  2. var
  3.  sl: TStringlist;
  4. begin
  5.  sl:= TStringlist.Create;
  6.   Try
  7.    sl.Text:= 'Save On Shutdown...';
  8.    sl.SaveToFile('I:\Save.txt');
  9.   Finally
  10.    sl.Free;
  11.   End;
  12. end;
  13.  
  14. procedure TForm1.ApplicationProperties1QueryEndSession(var Cancel: Boolean);
  15. begin
  16.  // Cancel:= True // If you want to cancel the shutdown (at least on WXP)
  17. end;
  18.  
  19. end.
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

_N_

  • New Member
  • *
  • Posts: 33
Re: Correct way to save application state on exit
« Reply #8 on: February 04, 2018, 01:47:26 pm »
Thanks a lot for your help.
I copy/pasted your methods and ran it. But it doesn't work for me, unfortunately... I set breakpoint but application never suspended on it  :(
I use windows 7 (32 bit), Lazarus 1.6.4, FPC 3.0.2 maybe that's make difference... Otherwise I have no idea why it doesn't work for me...

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Correct way to save application state on exit
« Reply #9 on: February 04, 2018, 02:06:01 pm »
Quote
I use windows 7 (32 bit), Lazarus 1.6.4, FPC 3.0.2 maybe that's make difference...
No it shouldn't make any difference... Works very good on my W7x64 machine ...
??? Don't know what exactly the problem is, maybe you will find out later...  :)
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Correct way to save application state on exit
« Reply #10 on: February 04, 2018, 02:58:01 pm »
Maybe this works? // I know should be exactly the same...  :)
On Windows 7 you cannot access C:\ as user I guess, so choose another path...
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

_N_

  • New Member
  • *
  • Posts: 33
Re: Correct way to save application state on exit
« Reply #11 on: February 04, 2018, 03:38:16 pm »
I replaced absolute path to relative (to save a file in the current directory and avoid permissions issue) and this works for reboot but doesn't work for just window closing :). But now I have a way to resolve my issue. Thanks a lot!
P.S. maybe other ways works too, I just expected singe point handler (and gave up when it failed on window close) don't know why... my bad, sorry. Thank you again.

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Correct way to save application state on exit
« Reply #12 on: February 04, 2018, 04:00:34 pm »
I have run into issues like that before an they are hard to resolve so what I have become a
heavy user of Tinifile lately. I keep it open and in various places where data needs to be updated on changes
made I make the updates to the file at that time..

  if you have sensitive data that needs to be synchronized with other items from a single change then you
can write a procedure Update_Important_Settings;

 This has worked great for me where one value change in one event may require several other values to be
updated (properties for example) then use a master update for that to file;
The only true wisdom is knowing you know nothing

_N_

  • New Member
  • *
  • Posts: 33
Re: Correct way to save application state on exit
« Reply #13 on: February 04, 2018, 05:05:30 pm »
Thank you jamie. Makes sense. I have used TIniFile already and have separate wrapper class for it.
The only problem that I cannot write to file on each change (I need to save state of some UI elements and if I write file each time when user drags window or click switches... I am afraid of performance and hardware (ssd) issues).

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Correct way to save application state on exit
« Reply #14 on: February 04, 2018, 06:05:59 pm »
That's not an issue actually, TiniFile has an option to stream it which means you can stream it to a Tmemorystream,
when closed, it then can commit to file.

 Look at that options in the Create....
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018