Correct way to save application state on exit lazarus / 31-LCL ---------------------------------------------------------------------- _N_ · 2018-02-04 08:14 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Self.OnExit := @Self.OnExitHandler; // code is copied from FormDestroy and FormDestroy is cleanedbut it doesn't work at all (even via menu) for me as well as Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 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_ · 2018-02-04 09:29 I found what is Self.OnExit.  From docs: QuoteHandler for control loosing the focus. This is a good place for checking the finished user input. ---------------------------------------------------------------------- RAW · 2018-02-04 09:53 Try this... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs; type  TForm1 = class(TForm)   ApplicationProperties1: TApplicationProperties;   procedure ApplicationProperties1EndSession(Sender: TObject);  end; var  Form1: TForm1; implementation {$R *.lfm}  procedure TForm1.ApplicationProperties1EndSession(Sender: TObject);begin // Shutdown Saveend; end. You can use FormCloseQuery for example... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Procedure TwndGUI.FormCloseQuery(Sender: TObject; Var CanClose: Boolean); Begin  If Memo.Modified  Then   If Memo.Text <> ''   Then    Begin     If Saved     Then CanClose:= True     Else CanClose:= False;    End; End; ---------------------------------------------------------------------- _N_ · 2018-02-04 11:40 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_ · 2018-02-04 11:44 Also I've tried Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MainForm.AddHandlerClose(@OnExitHandler); but it doesn't work with reboot/shutdown ---------------------------------------------------------------------- RAW · 2018-02-04 11:46 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". ---------------------------------------------------------------------- _N_ · 2018-02-04 12:21 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 · 2018-02-04 12:32 This works for me... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.ApplicationProperties1EndSession(Sender: TObject);var sl: TStringlist;begin sl:= TStringlist.Create;  Try   sl.Text:= 'Save On Shutdown...';   sl.SaveToFile('I:\Save.txt');  Finally   sl.Free;  End;end; procedure TForm1.ApplicationProperties1QueryEndSession(var Cancel: Boolean);begin // Cancel:= True // If you want to cancel the shutdown (at least on WXP)end; end. ---------------------------------------------------------------------- _N_ · 2018-02-04 12:47 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 · 2018-02-04 13:06 QuoteI 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... ---------------------------------------------------------------------- RAW · 2018-02-04 13:58 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... ---------------------------------------------------------------------- _N_ · 2018-02-04 14:38 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 · 2018-02-04 15:00 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; ---------------------------------------------------------------------- _N_ · 2018-02-04 16:05 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 · 2018-02-04 17:05 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.... ---------------------------------------------------------------------- _N_ · 2018-02-04 17:32 Thanks, I'll look