In the above comment, I summed up the answer I found (link) . Basically, it says to provide your own handler for WM_QUERYENDSESSION. This is the recommended code:
procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession); begin inherited; { let the inherited message handler respond first } {--------------------------------------------------------------------} { at this point, you can either prevent windows from closing... } { Message.Result:=0; } {---------------------------or---------------------------------------} { just call the same cleanup procedure that you call in FormClose... } MyCleanUpProcedure; {--------------------------------------------------------------------} end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin MyCleanUpProcedure; end;
I'm not sure if the Inherited call before the MyCleanUpProcedure call is completely correct. If the Inherited procedure first reverts to Windows, Windows can still close the application before completing MyCleanUpProcedure. I'm not sure what Inherited does for the message WM_QUERYENDSESSION - I assume that by default it allows you to exit immediately. MyCleanUpProcedure is very fast in my application, so it will not force Windows to display the Do Not Respond dialog box due to the lack of response to the WM_QUERYENDSESSION message.
To make sure my procedure is complete, perhaps the procedure should look like this:
procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession); begin MyCleanUpProcedure; inherited; end;
Or maybe it?
procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession); begin MyCleanUpProcedure; Message.Result:=1; // tell Windows it is OK to shut down end;
source share