Seite 1 von 2

Sofort beenden bei Shutdown umgehen?

Verfasst: 22.07.2010 23:02
von Tombi
Liebe Community,
habe öfters das Problem, das meine Programme beim herunterfahren des Rechers zu lange brauchen zum "herunterfahren" und einfach Fenster erscheint bei dem ich "Sofort schließen" klicken kann oder eben die paar Sekunden warten kann.

Kann ich irgendwie in meinem Programm abfangen, wenn Windows es versucht zu schließen und somit mein Programm normal versuchen zu schließen?

MFG,
Tombi

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 22.07.2010 23:24
von Kiffi
Tombi hat geschrieben:Kann ich irgendwie in meinem Programm abfangen, wenn Windows es versucht zu schließen und somit mein Programm normal versuchen zu schließen?
in einer normalen Eventschleife (WaitWindowEvent()) bekommst Du
nicht mit, wenn Windows die Rundmail "Ich fahre jetzt runter"
(#WM_QUERYENDSESSION) versendet. Dazu musst Du mittels
SetWindowCallback() einen erweiterten EventHandler einrichten.

Beispiel aus der PB-Hilfe leicht angepasst:

Code: Alles auswählen

Procedure WinCallback(hWnd, uMsg, wParam, lParam) 
  
  If uMsg = #WM_QUERYENDSESSION
    
    ; hier dein Programm adäquat beenden
    
  EndIf 
  
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 

If OpenWindow(0, 0, 0, 200, 100, "Messages", #PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget) 
  
  SetWindowCallback(@WinCallback())    ; activate the callback
  
  Repeat 
    Select WaitWindowEvent() 
      Case #PB_Event_CloseWindow 
        End 
    EndSelect 
  ForEver 
  
EndIf 
Grüße ... Kiffi

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 22.07.2010 23:32
von Tombi
Cool, werde ich gleich mal ausprobieren.
Wird schon schief gehen :D

Gibt es den noch andere Dinge die ich beachten sollte?

MFG,
Tombi

Edit:
Sollte funktionieren?

Code: Alles auswählen

Global Quit = 0
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
 
  If uMsg = #WM_QUERYENDSESSION
   
    Quit = 1
   
  EndIf
 
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 200, 100, "Test", #PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget)
 
  SetWindowCallback(@WinCallback())    ; activate the callback
 
  Repeat
    Debug "Anwendung läuft noch..."
    Delay(10000)
  Until Quit = 1
 
EndIf 
Edit2: Oder sollte ich anstelle "Quit = 1" lieber gleich mit "End" beenden?

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 23.07.2010 06:59
von ts-soft
Tombi hat geschrieben:Liebe Community,
habe öfters das Problem, das meine Programme beim herunterfahren des Rechers zu lange brauchen zum "herunterfahren" und einfach Fenster erscheint bei dem ich "Sofort schließen" klicken kann oder eben die paar Sekunden warten kann.
Dann solltest Du mal für eine vernünftige Eventloop-Schleife sorgen!
#WM_QUERYENDSESSION brauchste hierfür in keinem Fall (eher das gegenteil :mrgreen: )

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 23.07.2010 09:21
von Kiffi
In einer Eventschleife (so vernünftig sie auch programmiert sein möge) bekommst
Du IMO nicht mit, dass Dein Programm beendet wird, weil der Rechner herunterfährt.
ts-soft hat geschrieben:#WM_QUERYENDSESSION brauchste hierfür in keinem Fall (eher das gegenteil :mrgreen: )
was wäre das Gegenteil zu #WM_QUERYENDSESSION?

Grüße ... Kiffi

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 23.07.2010 09:30
von ts-soft
#WM_QUERYENDSESSION dient dazu, noch etwas zu speichern oder den runterfahren Prozeß zu verzögern.
Er möchte ja das Gegenteil, Windows fährt nicht sofort herunter, weil sein Programm nicht richtig beendet.
Hierfür hat er nicht auf diese Message zu reagieren, sondern sollte allgemein dafür sorgen das die
Messages im Pool nicht überlaufen (er den EventLoop nicht zu lange verläßt). Bei vernünftigem EventLoop
gäbe es das Problem nicht, das Windows meckert, es könne sein Programm nicht schnell genug beenden.

Gruß
Thomas

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 23.07.2010 12:07
von Kiffi
ts-soft hat geschrieben:#WM_QUERYENDSESSION dient dazu, noch etwas zu speichern oder den runterfahren Prozeß zu verzögern.
#WM_QUERYENDSESSION ist in allererster Hinsicht eine Nachricht.

Wie man auf diese Nachricht reagiert, ist dem Programmierer
überlassen.

#WM_QUERYENDSESSION impliziert nicht zwingend ein
verzögertes Programmende.

Ich verstehe deshalb nicht, warum Deiner Meinung nach
#WM_QUERYENDSESSION so gänzlich ungeeignet sein soll.

Grüße ... Kiffi

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 23.07.2010 14:13
von ts-soft
Weil #WM_QUERYENDSESSION mit seinem Problem nichts zu tun hat.
Sein Eventloop wird zu lange verlassen, so das das Programm auf #WM_CLOSE nicht schnell
genug reagiert. Wenn er zusätzlich bei dieser Message, die ja auch nicht schnell genug
bearbeitet wird, noch ein #WM_CLOSE (end) einfügt hat er rein garnichts erreicht, weil auch diese
Message einen besseren Eventloop benötigt!
Wenn der Wassereimer überläuft fülle ich doch nicht noch mehr Wasser ein :mrgreen:

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 24.07.2010 10:28
von mk-soft
Habe es mal mit PB4.51 unter Windows 7 getestet.
Purebasic beendet mit saubere EventLoop immer das Programm. Das Event #PB_Event_CloseWindow (WM_CLOSE) kommt nicht mehr an. Also selber über Callback darauf reagieren, wenn noch etwas erledigt werden muss.

Code: Alles auswählen

#ENDSESSION_LOGOFF = $80000000

Procedure WinCallback(hWnd, uMsg, wParam, lParam)
 
  If uMsg = #WM_QUERYENDSESSION
    
    If lParam & #ENDSESSION_LOGOFF
      MessageRequester("Query end session", "Benutzerabmeldung...")
    Else
      MessageRequester("Query end session", "Herunterfahren...")
    EndIf
    
  EndIf
 
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
FF :wink:

Re: Sofort beenden bei Shutdown umgehen?

Verfasst: 24.07.2010 10:38
von ts-soft
Wenn sein Programm zu selten das WaitWindowEvent erreicht nützt auch das Callback nicht viel.
Er sollte lieber ein vernünftiges EventLoop integrieren, so das im allg. die Events besser
verarbeitet werden, als sich darauf verlassen das es im callback besser funktionieren könnte, aber
der rest des programms trotzdem tod bleibt :mrgreen:

Wahrscheinlich geht ihr alle zu sehr auf seinem Titel ein, der eigentlich das Gegenteil seiner Frage ist.
Er braucht nicht dazu tun, das sein Programm bei #WM_QUERYENDSESSION schließt, lediglich sein
Programm sollte öfter mal bei WaitWindowEvent ankommen, weil Windows ja nicht ewig warten kann,
bevor es den Rechner runterfährt.

Das bearbeiten der Message ist nicht die Frage, lediglich ankommen muß sie (WaitWindowEvent(), die wird dann autom.
durchgereicht, bis sie wieder bei Windows ankommt und Windwos weiß, man hat Kenntnis davon und z.B. shutdown kann durchgeführt werden.

Versteht wahrscheinlich immer noch keiner, besser ausdrücken kann ich es aber nicht

Gruß
Thomas