Windows wird heruntergefahren
Das verarbeiten WM_ENDSESSION etc.
Autor: HALLVARD VASSBOTN
{
In einem früheren per e-Mail mit dem Betreff 'Ernsthaftigkeit [Delphi] Fehler beim Schließen
Windows???'[email protected](Per Bakkendorff) schreibt:
> Wenn Sie haben eine Delphi-Anwendung ausgeführt, und Sie sind Windows Herunterfahren,
> (nicht in der Nähe Ihrer app zuerst), keiner von Ihren Destruktoren heißen!!!
Zuerst dachte ich, das Problem war der Programmierer Code, aber dann merkte ich, dass es sich wirklich um einen Bug oder zumindest ein sehr faul 'Feature' ist.
Das Problem scheint zu sein, dass beim Schließen Sie Windows es zuerst eine WM_QueryEndSession-Meldung an alle Fenster läuft auf höchster Ebene zu senden. Dies ist behandelt und durch das TForm-Objekt im VCL korrekt verarbeitet.
Dann wird vorausgesetzt, dass alle Anwendungen darauf hingewiesen, dass es war in Ordnung, zu schließen, Windows WM_EndSession Nachrichten an alle Fenster gesendet. Diese Meldung ist nicht von VCL behandelt. Die Anwendung ist einfach mit einem Knall gesenkt.
Keine Fenster sind geschlossen, kein Destruktor aufgerufen und keine Prozeduren aufgerufen beendet.
Die Lösung soll die Meldung WM_EndSession selbst behandeln. Es gibt mehrere Möglichkeiten der Behandlung von Meldungen in Delphi, aber die einzig zuverlässige Möglichkeit der Umgang mit den WM_ENDSESSION ist die HookWindow-Methode der Anwendung veranschaulicht.
Überprüfen Sie in den Meldungshandler, wenn die Nachricht eine WM_ENDSESSION ist. Wenn ja, sollten wir die Anwendung schließen. Wir könnten genannt, haben die Close-Methode des Hauptfensters, aber die Windows-API-Dokumentation-Staaten, die das System kann jederzeit nach der Rückkehr aus dem WM_ENDSESSION eingehen und eine gebuchte WM_QUIT Nachricht möglicherweise niemals zur Anwendung kommen.
Die Lösung ist einfach Halt stattdessen anzurufen. Dies wird alle Registred Ausfahrt Prozeduren, einschließlich derjenigen in Steuerelementen und DB aufrufen Einheiten. Diese kostenlose Anwendung und Bildschirm Objekte und BDE ordnungsgemäß herunterzufahren.
Es folgt ein einfaches Beispiel:
}
Einheit Tst2u;
Schnittstelle
verwendet
SysUtils, WinTypes, WinProcs, Nachrichten, Klassen, Graphics, Kontrollen,
Formen, Dialoge, Gitter, DBGrids, DB DBTables;
Typ
TForm1 = class(TForm)
DataSource1: TDataSource;
Tabelle1: Nachrüstbar;
DBGrid1: TDBGrid;
Prozedur FormCreate(Sender: TObject);
Private
{Private Deklarationen}
Funktion HookProc (Var Message: TMessage): boolean;
öffentliche
{Public Deklarationen}
Ende;
var
Form1: TForm1;
Umsetzung
{$R *. DFM}
const
FlagFileName = 'C:\Flag.Fil';
Prozedur CreateFlagFile;
var
F: System.Text;
beginnen
System.Assign (F, FlagFileName);
System.Rewrite(F);
Writeln (F, 'Diese Datei ist eine Pseudo-Flag');
System.Close(F);
Ende;
Prozedur KillFlagFile;
var
F: Datei;
beginnen
System.Assign (F, FlagFileName);
System.Erase(F);
Ende;
Prozedur MyExitProc; weit;
beginnen
KillFlagFile;
Ende;
Prozedur TForm1.FormCreate(Sender: TObject);
beginnen
Application.HookMainWindow(HookProc);
Ende;
Funktion TForm1.HookProc (Var Message: TMessage): boolean;
beginnen
Ergebnis: = False;
Wenn Message.Msg WM_EndSession dann =
beginnen
Wenn WordBool(Message.wParam) dann
beginnen
{Windows ist Schließung - bereinigen!!}
{Dies sollten alle ExitProcs ausgeführt, Fenster schließen und rufen Sie Destruktoren...}
Halt; {Funktioniert!}
{Dies sollte schließen Dinge nach unten richtig,
aber haben wir genügend Zeit, alle gebuchten Meldungen vor Windows behandeln
ist bereits nach unten?? Dies führt zu einer PostQuitMessage, die möglicherweise
niemals kommen Sie!}
{Schließen}; {Dies funktioniert nicht immer - vermeiden Sie es}
Ende;
Ende;
Ende;
Initialisierung
CreateFlagFile;
AddExitProc(MyExitProc);
Ende.
Dieses Gerät zeigt, dass die Ausfahrt-Prozeduren aufgerufen werden, wenn die app normalerweise und wenn Windows die Schließung und mit HookMainWindow zu schließen. Ohne den Aufruf von HookMainWindow wird das Ausfahrt Proc nicht aufgerufen werden. Dies ist besonders wichtig für DB-Anwendungen. Ohne den Halt, LCK-Dateien werden nicht gelöscht, Puffer möglicherweise nicht geleert, Änderungen bekannt gegeben und so weiter.
Windows wird heruntergefahren
Windows wird heruntergefahren : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
Das verarbeiten WM_ENDSESSION etc.
Autor: HALLVARD VASSBOTN
{
In einem früheren per e-Mail mit dem Betreff 'Ernsthaftigkeit [Delphi] Fehler beim Schließen
Windows???'[email protected](Per Bakkendorff) schreibt:
> Wenn Sie haben eine Delphi-Anwendung ausgeführt, und Sie sind Windows Herunterfahren,
> (nicht in der Nähe Ihrer app zuerst), keiner von Ihren Destruktoren heißen!!!
Zuerst dachte ich, das Problem war der Programmierer Code, aber dann merkte ich, dass es sich wirklich um einen Bug oder zumindest ein sehr faul 'Feature' ist.
Das Problem scheint zu sein, dass beim Schließen Sie Windows es zuerst eine WM_QueryEndSession-Meldung an alle Fenster läuft auf höchster Ebene zu senden. Dies ist behandelt und durch das TForm-Objekt im VCL korrekt verarbeitet.
Dann wird vorausgesetzt, dass alle Anwendungen darauf hingewiesen, dass es war in Ordnung, zu schließen, Windows WM_EndSession Nachrichten an alle Fenster gesendet. Diese Meldung ist nicht von VCL behandelt. Die Anwendung ist einfach mit einem Knall gesenkt.
Keine Fenster sind geschlossen, kein Destruktor aufgerufen und keine Prozeduren aufgerufen beendet.
Die Lösung soll die Meldung WM_EndSession selbst behandeln. Es gibt mehrere Möglichkeiten der Behandlung von Meldungen in Delphi, aber die einzig zuverlässige Möglichkeit der Umgang mit den WM_ENDSESSION ist die HookWindow-Methode der Anwendung veranschaulicht.
Überprüfen Sie in den Meldungshandler, wenn die Nachricht eine WM_ENDSESSION ist. Wenn ja, sollten wir die Anwendung schließen. Wir könnten genannt, haben die Close-Methode des Hauptfensters, aber die Windows-API-Dokumentation-Staaten, die das System kann jederzeit nach der Rückkehr aus dem WM_ENDSESSION eingehen und eine gebuchte WM_QUIT Nachricht möglicherweise niemals zur Anwendung kommen.
Die Lösung ist einfach Halt stattdessen anzurufen. Dies wird alle Registred Ausfahrt Prozeduren, einschließlich derjenigen in Steuerelementen und DB aufrufen Einheiten. Diese kostenlose Anwendung und Bildschirm Objekte und BDE ordnungsgemäß herunterzufahren.
Es folgt ein einfaches Beispiel:
}
Einheit Tst2u;
Schnittstelle
verwendet
SysUtils, WinTypes, WinProcs, Nachrichten, Klassen, Graphics, Kontrollen,
Formen, Dialoge, Gitter, DBGrids, DB DBTables;
Typ
TForm1 = class(TForm)
DataSource1: TDataSource;
Tabelle1: Nachrüstbar;
DBGrid1: TDBGrid;
Prozedur FormCreate(Sender: TObject);
Private
{Private Deklarationen}
Funktion HookProc (Var Message: TMessage): boolean;
öffentliche
{Public Deklarationen}
Ende;
var
Form1: TForm1;
Umsetzung
{$R *. DFM}
const
FlagFileName = 'C:\Flag.Fil';
Prozedur CreateFlagFile;
var
F: System.Text;
beginnen
System.Assign (F, FlagFileName);
System.Rewrite(F);
Writeln (F, 'Diese Datei ist eine Pseudo-Flag');
System.Close(F);
Ende;
Prozedur KillFlagFile;
var
F: Datei;
beginnen
System.Assign (F, FlagFileName);
System.Erase(F);
Ende;
Prozedur MyExitProc; weit;
beginnen
KillFlagFile;
Ende;
Prozedur TForm1.FormCreate(Sender: TObject);
beginnen
Application.HookMainWindow(HookProc);
Ende;
Funktion TForm1.HookProc (Var Message: TMessage): boolean;
beginnen
Ergebnis: = False;
Wenn Message.Msg WM_EndSession dann =
beginnen
Wenn WordBool(Message.wParam) dann
beginnen
{Windows ist Schließung - bereinigen!!}
{Dies sollten alle ExitProcs ausgeführt, Fenster schließen und rufen Sie Destruktoren...}
Halt; {Funktioniert!}
{Dies sollte schließen Dinge nach unten richtig,
aber haben wir genügend Zeit, alle gebuchten Meldungen vor Windows behandeln
ist bereits nach unten?? Dies führt zu einer PostQuitMessage, die möglicherweise
niemals kommen Sie!}
{Schließen}; {Dies funktioniert nicht immer - vermeiden Sie es}
Ende;
Ende;
Ende;
Initialisierung
CreateFlagFile;
AddExitProc(MyExitProc);
Ende.
Dieses Gerät zeigt, dass die Ausfahrt-Prozeduren aufgerufen werden, wenn die app normalerweise und wenn Windows die Schließung und mit HookMainWindow zu schließen. Ohne den Aufruf von HookMainWindow wird das Ausfahrt Proc nicht aufgerufen werden. Dies ist besonders wichtig für DB-Anwendungen. Ohne den Halt, LCK-Dateien werden nicht gelöscht, Puffer möglicherweise nicht geleert, Änderungen bekannt gegeben und so weiter.
Windows wird heruntergefahren
By Wiezutun
Windows wird heruntergefahren : Mehreren tausend Tipps, um Ihr Leben einfacher machen.