Wie kann ich abfragen oder verhindern, ob Windows heruntergefahren wird?


Normalerweise kann man mit dem OnCloseQuery Event abfangen, ob ein Formular geschlossen werden soll und dies notfalls verhindern. Leider kann man hier nicht unterscheiden ob nur der Benutzer das Programm beendet oder ob Windows heruntergefahren werden soll.

Idee: Man muß die Windows-Messsage WM_QUERYENDSESSION abfangen, mithilfe dieser Nachricht kann man sogar das Beenden von Windows verhindern.

So sieht der Ablauf aus, wenn Windows heruntergefahren wird und die eigene Anwendung noch läuft:

  1. Windows sendet die WM_QUERYENDSESSION Nachricht an alle laufenden Anwendungen und wartet auf deren Antwort
  2. Diese Antowrt besteht aus einen Rückgabewert ungleich Null wenn die Anwendung jetzt geschlossen werden kann, oder 0, wenn das jetzt nicht geht.
  3. Nur wenn alle Anwendungen mit ok (<>0) geantwortet haben, sendet Windows eine WM_ENDSESSION Nachricht an alle Anwendungen
  4. Jede Anwendung, die darauf mit TRUE antwortet, kann jederzeit von Windows beendet werden. Bei Delphi scheint es so zu sein, daß Delphi nach dem TRUE sofort die FormDestroy-Methode aufruft. Scheinbar wird hier auch der Aufruf von FormClose vergessen.
  5. Windows beendet sich
type
  TForm1 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION;
  ...
  end;

implementation
procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
  inherited;
  Message.Result := 0; // Windows fährt *nicht* runter!
end;
Delphi 1 Delphi 2 Delphi 3 Delphi 4
nicht getestet Version nicht betroffen getestet

siehe auch:


Delphi FAQ