![]() |
WM_QUERYENDSESSION verwenden
Hallo,
vorweg: Ich weiß, dass es zu diesem Thema bereits unzählige Beiträge in diesem Forum gibt. Ich habe mich bereits stundenlang da durch gequält. Leider ohne greifbares Ergebnis. Mein Problem ist folgendes: Ich möchte meine Anwendung "geregelt" (alles Speichern usw.) beenden, wenn der Anwender Windows herunterfährt. Dafür habe ich z.B. folgendes in das Hauptformular meiner Anwendung eingebaut:
Delphi-Quellcode:
Es scheint so zu sein, dass meine Anwendung die Nachricht nicht erhält, weder beim einfachen "Abmelden" noch beim "Herunterfahren". Jedenfalls wird ShowMessage nicht ausgeführt und Windows fährt nicht herunter.
procedure WMQueryEndSession(var Msg:TWMQueryEndSession); message WM_QUERYENDSESSION;
procedure TFMain.WMQueryEndSession(var Msg:TWMQueryEndSession); begin showmessage('***Ende***'); Msg.Result := 1; end; Wer weiß, wie es richtig gemacht werden muss? Gruß Johann |
Re: WM_QUERYENDSESSION verwenden
Hallo,
ich mach das in meinen Programmen immer so:
Delphi-Quellcode:
Mit der Variablen "Windows_Session_End" umgeh ich die Frage ob wirklich beendet werden soll, beim Schliessen des Programmes
private
procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QueryEndSession; {...} procedure TMainForm.WMQueryEndSession (var Msg : TWMQueryEndSession); begin //Windows erlauben zu beenden Msg.Result := 1; //Wenn Windows beendet wird, dann Variable auf true setzen Windows_Session_End := true; //Programm schliessen close; inherited; end; und Speichere gleich drauf los |
Re: WM_QUERYENDSESSION verwenden
Hallo Helmi,
vielen Dank für deine Antwort. Mein Problem ist allerdings nicht, wie ich überflüssige Abfragen verhindere oder das Programm beende, sondern dass die Botschaft WM_QUERYENDSESSION scheinbar garnicht in meinem Programm ankommt. Gruß Johann |
Re: WM_QUERYENDSESSION verwenden
Wenn Windows nicht beendet wird, reagiert deine Anwendung offensichtlich auf diese Nachricht.
ShowMessage aufzurufen ist an dieser Stelle eine ganz schlechte Idee. Diese Nachricht muss unverzüglich beantwortet werden. Windows befindet sich sozusagen im Ausnahmezustand, bis alle Anwendungen reagiert haben. Da darf man nicht einfach neue Fenster erstellen. Wenn man das Beenden von Windows verhindert, kann man sich aber selbst noch schnell eine Nachricht Posten und nachträglich auf dieses Ereignis reagieren. ![]() |
Re: WM_QUERYENDSESSION verwenden
@Blub
Wenn ich ShowMessage mal testweise durch close ersetze, passiert ebenfalls rein garnichts. Die Anwendung bleibt geöffnet, ist weiter bedienbar und Windows aktiv, so als ob ich garnichts gemacht hätte. Übrigens: In einer kleinen Testanwendung, die nur aus dem Hauptfenster bestand, hat die Behandlung von WM_QUERYENDSESSION wunschgemäß funktioniert. Gruß Johann |
Re: WM_QUERYENDSESSION verwenden
Auch Close solltest du an dieser Stelle nicht aufrufen.
Windows hat noch nicht entschieden ob es beendet wird. Es fragt alle Fenster ab und wenn auch nur eins mit 0 antwortet, passiert nichts. Das ist die Standardantwort die jedes Fenster zurückgibt:
Delphi-Quellcode:
Das einzige sinnvolle andere Reaktion ist Result auf 0 zu setzen und/oder sich dieses Ereignis zu merken.
begin
Msg.Result := 1; end; Der von Helmi gepostete Code gehört eigentlich in die Verarbeitung der Nachricht WM_EndSession. Wenn deine Methode WMQueryEndSession entfernt wird und sich Windows trotzdem nicht beenden lässt, dann reagiert irgend ein anderes Fenster deiner Anwendung falsch auf diese Nachricht. Das kann auch ein unsichtbares Fenster sein, das z.B. von irgend einer Komponente/Klasse für interne Zwecke erzeugt wurde. |
Re: WM_QUERYENDSESSION verwenden
Stimmt - Das close ist falsch.
Eigentlich kann man das close auch gleich vernachlässigen |
Re: WM_QUERYENDSESSION verwenden
Auch das Setzen des Flags "Windows_Session_End" ist formal gesehen falsch.
Denn ![]() cu Oliver |
Re: WM_QUERYENDSESSION verwenden
Ich habs ausprobiert:
Bei WM_EndSession das Flag setzen ist zu spät Ich habs daran gemerkt, dass meine Meldung, ob wirklich geschlossen werden soll, trotzdem kam, als ich Windows beendete Mit dem Flag will ich das aber überbrücken. |
Re: WM_QUERYENDSESSION verwenden
Für eine Frage ob die Anwendung wirklich geschlossen werden soll, kenne ich in dieser Situation nur diese Variante.
Ist zwar umständlich, funktioniert aber sicher. Wenn noch Daten in Bearbeitung sind die Nachricht mit 0 beantworten und dem eigenen Fenster eine Nachricht posten. Diese Nachricht kann auch die Info enthalten, in welchen Modus Windows versetzt werden sollte (siehe unten). Als Reaktion auf diese Nachricht dann die Frage nach dem Speichern/Beenden und wenn erfolgreich/ja anschließend Close. Zum Schluss Windows selbst in den entsprechenden Modus versetzen oder diesen Schritt dem Anwender überlassen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz