![]() |
Auf Abmelden/Herunterfahren in onClose reagieren
Hallo,
ich versuche gerade, folgendes zu bewerkstelligen: Mein Programm öffnet im onClose-Event des Hauptformulars eine Messagebox. Diese soll allerdings nur kommen, wenn das Programm "von Hand" beendet wird, nicht aber, wenn Windows gerade am Herunterfahren/Abmelden/Neustarten ist, schließlich will ich ja nicht das Herunterfahren verhindern ;) Ich habe es schon mit WM_QUERYENDSESSION versucht, aber das Event wird erst *nach* dem onClose-Event ausgelöst. Gibt es eine Möglichkeit, es anders hinzubekommen? Thx! Tschüss The_Unknown |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Hi,
Du musst das OnCloseQuery Event nehmen, das kommt vorher. Gruss |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Und wie stelle ich dann im onCloseQuery-Event fest, ob gerade heruntergefahren/abgemeldet/neugestartet wird?
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Der Event wird aufgerufen, wenn die Beendigung des Programmes verlangt wird
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Aber das Event wird doch auch dann aufgerufen, wenn ich das Programm "von Hand" beende, sprich das kleine X oben rechts anklicke. Und genau hier soll ja unterschieden werden, ob der Rechner gerade am Herunterfahren ist oder nicht.
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
kannst du nicht im WM_QUERYENDSESSION einen Boolean setzen, denn du im OnClose bzw. OnCloseQuery auswertest?
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Zitat:
Zitat:
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Zitat:
Bei mir nicht. Alles so wie' sein soll. WMQUERYENDSESSION OnCloseQuery OnClose Wäre irgendwie auch doof, wenn Windows das Programm beendet und danach erst fragt, oder ? |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Mhm, bei mir (Windows 7 x64):
OnCloseQuery WM_QueryEndSession Nur weiß ich nicht, ob das immer und bei jedem so ist. Anscheinend ja nicht :gruebel: Gibts vielleicht noch eine andere Variante, das zu lösen? |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Schau mal, ob
Delphi-Quellcode:
(erst ab XP) dir weiterhilft.
if GetSystemMetrics(SM_SHUTTINGDOWN) <> 0 then
//is shutting down Ich bin mir aber nicht sicher, ob das auch bei Neustart funktioniert. |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Nope, leider nicht. Das Abmelden z.B. wird nicht erkannt.
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Hallo
bei mir ist das so gelöst und klappt bisher ganz gut.
Delphi-Quellcode:
Gruß Bernd
procedure TMainForm.FormCreate(Sender: TObject);
begin ... Application.HookMainWindow(WMEndSession); ... end; procedure MainForm.FormDestroy(Sender: TObject); begin ... Application.UnhookMainWindow(WMEndSession); ... end; function TMainForm.WMEndSession(var Message: TMessage):Boolean; begin if (Message.Msg=WM_ENDSESSION) and TWMEndSession(Message).EndSession then begin SessionEnd:=True; // diese kann dann ausgewertet werden ... end; Result:=False; end; |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Das sieht schon mal ganz gut aus, es tritt aber ein seltsamer Fehler auf. Ich habe es nun so gemacht:
Delphi-Quellcode:
Wenn ich die Anwendung normal über "X" beende, kommt die Meldung 0, also alles ok.
function TForm1.WMEndSession(var Message: TMessage):Boolean;
begin if (Message.Msg=WM_ENDSESSION) and TWMEndSession(Message).EndSession then begin SessionEnd := True; // diese kann dann ausgewertet werden end; Result:=False; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin showmessage(inttostr(Integer(SessionEnd))); end; procedure TForm1.FormCreate(Sender: TObject); begin Application.HookMainWindow(WMEndSession); end; procedure TForm1.FormDestroy(Sender: TObject); begin Application.UnhookMainWindow(WMEndSession); end; Wenn ich nun aber zB. abmelde, kommt überhauptkeine Message (weder 0 noch 1), was ja nicht sein kann, denn ich habe in der Showmessage ja was stehen!? |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Also ich habe es bei mir so gemacht. Vielleicht hilft dir das ja weiter:
Delphi-Quellcode:
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
var Button : Word; begin Button := MessageBox(Handle, PChar('Beenden?'), PChar('Ende der Anwendung'), MB_YESNO or MB_ICONQUESTION); case Button of mrNo : begin Action := caNone; Application.Minimize; end; mrYes : begin Action := caFree; end; end; end; |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Das hilft nicht wirklich weiter.
Ich schildere am besten mal, was ich genau damit machen will. Ich möchte, wenn ich das MainForm schließe, dass eine Nachricht kommt "Achtung: Das Programm ist immernoch geöffnet, nur dass es jetzt neben der Systemuhr ist..." (die Nachricht kommt natürlich nur 1x und dann nie wieder). Wenn nun allerdings der User herunterfährt und das Hauptfenster ist noch offen und die Meldung wurde noch nie angezeigt, dann kommt die Meldung beim Herunterfahren, was etwas unglücklich ist. Ich hoffe, nun ist es klarer ;) |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Hi,
ich denke Du solltest mal dies versuchen:
Delphi-Quellcode:
ungetestet, aber ähnlich mache ich es in meinen Programmen auch - ausser der TrayMessage.
Interface
Type tForm1 = class(TForm) ... procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); private FEndSession: boolean; TrayMessageDone: boolean; protected procedure WMQueryEndSession(var msg: tMessage); message WM_QUERYENDSESSION; procedure WMEndSession(var msg: tMessage); message WM_ENDSESSION; end; Implementation procedure tForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin CanClose := FEndSession; // wenn endsession flag gesetzt, dann kompromisslos beenden if not CanClose then begin if not TrayMessageDone then begin TrayMessageDone := true; showmessage('wir gehen jetzt in den Tray'); end; // minimieren oder in den tray legen. Hide; end; end; procedure tForm1.WMEndSession(var msg: tMessage); begin FEndSession := bool(msg.wParam); if FEndSession then begin // aufräumarbeiten durchführen // ich lagere diese in eine Prozedur Finish aus, und rufe sie hier und im FormDestroy auf. // achtung - nur einmal aufrufen - flag setzen end; msg.result := 0; end; procedure tForm1.WMQueryEndSession(var msg: tMessage); begin FEndSession := true; bool(msg.result) := TRUE; end; Gruss |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Zitat:
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Also soweit ich mich richtig erinnere war es so: [X] am Fenster: OnCloseQuery OnClose OnDestroy Abmelden/Herunterfahren: WM_QUERYENDSESSION OnCloseQuery WM_ENDSESSION OnDestroy Und soweit ich die Hilfe von M$ richtig verstanden habe, steht ja zum Zeitpunkt von WM_QUERYENDSESSION nicht fest ob wirklich herunter gefahren wird. Es wird ja nur nach gefragt ob es gehen würde. Es könnte auch noch abgebrochen werden von einer anderen Anwendung. Und es gab noch einen merkwürdigen Effekt. Beim schließen über [X] wurde OnCloseQuery nur vom MainForm ausgelöst während beim Herunterfahren/Abmelden alle Forms des Projekts die ein OnCloseQuery hatten abgefragt wurden. Hatte bei mir sogar das Herunterfahren verhindert :-( Gruß, Chris [Edit] Hab nochmal das DemoProjekt nachgebaut, welches meine These unterstützt :-)[/Edit] |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Ja, genau dieses Problem habe ich bei mir auch.
Nur wenn ich herunterfahre, und ich habe bei onCloseQuery showmessage('Hallo'); drin stehen, dann poppt diese meldung beim Herunterfahren auch nicht auf. Ich bin langsam wirklich etwas ratlos in dieser Sache. |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Folgendes solltest du doch jetzt lösen können:
Wenn du wie in meinem Beispielprojekt deinem MainForm eine WMQueryEndSession verpasst kannst du bei WM_QUERYENDSESSION ja zuerst eine Boolsche Variable setzen. Der Trick ist erst die Variable setzten und dann erst inherited auf zu rufen :-)
Delphi-Quellcode:
Wenn du jetzt in deine CloseQuery kommst dort einfach nur abfragen ob die Var gesetzt ist. Wenn ja, dann kommt der Aufruf zum schließen wohl nicht vom Anwender per [X]-Knopf sondern vom System wegen Abmelden / Runterfahren.
procedure TMainForm.WMQueryEndSession(var Message: TMessage);
begin FWmQueryEndsession := TRUE; inherited; end; Denn du willst es ja glaube ich genau so, oder? -> Zitat:
|
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Jetzt funktioniert es tatsächlich :thumb:
Kann es sein, dass inherited; den Konstruktor der Superklasse von WMQUERYENDESSEION aufruft (ähnlich zu super(); in Java)? Jetzt fehlt mir nur noch eine Antwort auf ein weiteres - anscheinend nicht minder verzwicktes - Problem, wo mir niemand antwortet :( --> ![]() |
Re: Auf Abmelden/Herunterfahren in onClose reagieren
Hi
Wie kann ich den erkennen ob nach dem ich das WM_QUERYENDSESSION reagiert habe (IsShutingDown = True) wer anderer das Herunterfahren abgebrochen hat? Gibts da ein WM_ContinueSession oder so auf das ich reagieren könnte? Danke Jakson [edit] Ich hab die frage noch einmal in einem neuen Thread gestellt ![]() [/edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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