--- ---

When Windows is about to shut down, it sends a WM_QUERYENDSESSION message to all open applications. To detect (and prevent shutdown), we must define a message handler for this message. Put this definition in the private section of the main form:

    procedure WMQueryEndSession(var Msg: TWMQueryEndSession);
      message WM_QUERYENDSESSION;

Also, to prevent Windows shutting down put this method in the implementation section of the unit:

    procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
    begin
      if MessageDlg('Close Windows ?', mtConfirmation, [mbYes,mbNo], 0) = mrNo then
        Msg.Result := 0
      else
        Msg.Result := 1 ;
    end;

To detect Windows Shutdown, we must trap the WM_ENDSESSION message. Declare a message handling procedure in your main frm's private section:

    procedure WMEndSession(var Msg: TWMEndSession); message WM_ENDSESSION;

Also, add the following procedure to the implementation section of your unit:

    procedure TForm1.WMEndSession(var Msg: TWMEndSession);
    begin
      if Msg.EndSession = True then
        ShowMessage(
          'Windows is shutting down ' + #10#13 + 'at ' + FormatDateTime('c', Now)
        );
      inherited;
    end;