Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Windows beendet Programm nicht (https://www.delphipraxis.net/51124-windows-beendet-programm-nicht.html)

Matze 6. Aug 2005 12:22


Windows beendet Programm nicht
 
Moin!

Ich habe etliche Möglichkeiten schon durch probiert, die hier im Forum auch genannt werden, doch keine schafft es Windows nicht, mein Programm beim Herunterfahren zu beenden. Windows lässt sich folglich erst herunterfahren, wenn ich das Programm manuell beende.

Hier die mir am einleuchtesten erscheinende, nicht funktionierende Möglichkeit:

Delphi-Quellcode:
procedure WMQUERYENDSESSION(var msg: TMessage); message WM_QUERYENDSESSION;

[...]

procedure TForm1.WMQUERYENDSESSION(var msg: TMessage);
begin
  inherited;

  //Falls eingestellt, dass das Programm bei Klick auf "X" minimiert werden soll
  MinimizeAtClose := false;

  //Falls eingestellt, dass Nachfrage beim Beenden erscheint
  AskForClose := false;

  msg.Result := 1;
end;
Die evtl. relevanten Stellen meines Code sehen wie folgt aus:

Delphi-Quellcode:
//TNA - auf Mausklicks reagieren:
procedure TForm1.WndProc(var Msg: TMessage);
var
  Point: TPoint;
begin
  if Msg.Msg = WM_USER + 20 then
  begin
    case Msg.lParam of
      WM_RBUTTONDOWN:
        begin
          SetForegroundWindow(Handle);
          GetCursorPos(Point);
          PopUpMenu1.PopUp(Point.X, Point.Y);
        end;
      WM_LBUTTONDBLCLK:
        begin
          Form1.Show;
          Shell_NotifyIcon(NIM_DELETE, @IconData);
        end;
    end;
  end;
  inherited;
end;
Delphi-Quellcode:
//Beim Minimieren Icon in TNA:
procedure TForm1.WMSysCommand(var Message: TWMSysCommand);
begin
  if Message.CmdType and $FFF0 = SC_MINIMIZE then
  begin
    MinimizeToTray;
  end
  else
    inherited;
end;
Delphi-Quellcode:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if AskForClose and (not MinimizeAtClose) then
  begin
    if Application.MessageBox('Programm beenden?', 'Hinweis', MB_YESNO) = IDYes then
    begin
      AskForClose := false;
      MinimizeAtClose := false;
      CanClose := true;
      Application.MainForm.Close;
    end else
      CanClose := false;
  end;
end;
Sieht jemand von euch da einen Fehler? Ich kann beim besten Willen keinen entdecken.

turboPASCAL 6. Aug 2005 12:53

Re: Windows beendet Programm nicht
 
Weil CanClose := false; gesetzt ist auch bei der WM_QueryEndSession Message ?

Flocke 6. Aug 2005 12:59

Re: Windows beendet Programm nicht
 
Nur 'n paar Gedanken...

1. Schießt du dir bei <HIER> nicht selbst in den Hintern? Du bist doch schon im Close weil CloseQuery aufgerufen wurde.

Zitat:

Zitat von Matze
Delphi-Quellcode:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if AskForClose and (not MinimizeAtClose) then
  begin
    if Application.MessageBox('Programm beenden?', 'Hinweis', MB_YESNO) = IDYes then
    begin
      AskForClose := false;
      MinimizeAtClose := false;
      CanClose := true;
      Application.MainForm.Close; // <--- HIER
    end else
      CanClose := false;
  end;
end;

2. Reagiere nicht auf WM_QUERYENDSESSION sondern auf WM_ENDSESSION mit wParam<>0 -> Application.MainForm.Close oder Application.Terminate

3. Wenn das nichts hilft würde ich mir in WndProc einen Logger packen, der alle Fenstermeldungen mitschreibt. Dann weißt du mal, was so ein Windows Shutdown überhaupt an Meldungen verursacht.

Ansonsten wüsste ich nicht, was den Shutdown aufhalten sollte. Was klappt denn nicht, kommt die Rückfragebox?

Matze 6. Aug 2005 15:05

Re: Windows beendet Programm nicht
 
Zitat:

Zitat von turboPASCAL
Weil CanClose := false; gesetzt ist auch bei der WM_QueryEndSession Message ?

Ich denke eigentlich, dass die WM_QueryEndSession-Message eintritt, bevor das OnCloseQuery-Ereignis aufgerufen wird. Ich stelle bei der Message ja die boolschen Variablen auf false. Wenn danach dann das OnCloseQuery kommt, steht CanClose ja auf true.

Zitat:

Zitat von Flocke
Schießt du dir bei <HIER> nicht selbst in den Hintern?

Tatsache, da hatte ich einen Fehler drin, danke, nur lag's nicht an dem.

Zitat:

Zitat von Flocke
Reagiere nicht auf WM_QUERYENDSESSION sondern auf WM_ENDSESSION mit wParam<>0 -> Application.MainForm.Close oder Application.Terminate

Wieso das?
Dann kann ich ja nicht mehr entsprechend reagieren.

Zitat:

Zitat von Flocke
Wenn das nichts hilft würde ich mir in WndProc einen Logger packen, der alle Fenstermeldungen mitschreibt. Dann weißt du mal, was so ein Windows Shutdown überhaupt an Meldungen verursacht.

Ich schau mal, wie das geht, vielleicht komme ich dann zu einer Lösung.

Zitat:

Zitat von Flocke
Was klappt denn nicht, kommt die Rückfragebox?

Nein, es kommt gar nichts. Das Programm läuft weiter, als ob sein Chef (Windows) nichts gesagt hätte. ;)

Ich habe auch testweise ShowMessage in der WMQUERYENDSESSION Prozedur und im OnCloseQuery aufgerufen, doch sehe ich nie einen Dialog. Evtl. tritt das Ereignis gar nicht erst ein. :gruebel:

turboPASCAL 6. Aug 2005 15:28

Re: Windows beendet Programm nicht
 
Zitat:

Zitat von Matze
Zitat:

Zitat von turboPASCAL
Weil CanClose := false; gesetzt ist auch bei der WM_QueryEndSession Message ?


Ich denke eigentlich, dass die WM_QueryEndSession-Message eintritt, bevor das OnCloseQuery-Ereignis aufgerufen wird. Ich stelle bei der Message ja die boolschen Variablen auf false. Wenn danach dann das OnCloseQuery kommt, steht CanClose ja auf true.

Auwaija, ich glaube ich hatte ein END; übersehen. :spin:

Was haste denn für ein OS ?

Matze 6. Aug 2005 15:42

Re: Windows beendet Programm nicht
 
Zitat:

Zitat von turboPASCAL
Was haste denn für ein OS ?

Windows XP Home SP2

Also mein Msg-Log zeigt, dass folgende Messages aufgerufen werden (lParam):

Zitat:

0, 1, 1239556, 1240484, 1240528, 1241896, 1241952, 1241972, 1242004, 1242100, 1242968, 1243456, 1243896, 1243932, 1243940, 1376837, 9647792, 12321082, 12321301, 12779825, 13697557, 1244844, 316, 11469105, 1243568, 1243612, 1243920, 15008277, 1716, 1769796
Wohl am wichtigsten: Gegen Ende des Programmes:

Zitat:

512, 516, 517, 9647952, 9654092
Kann man irgendwo nachsehen, was welche Message ist? Im MSDN finde ich dazu nichts.

turboPASCAL 6. Aug 2005 16:03

Re: Windows beendet Programm nicht
 
http://www.swissdelphicenter.ch/torr...ode.php?id=939

Delphi-Quellcode:
private
  procedure WMQueryEndSession (var Msg : TWMQueryEndSession); message WM_QueryEndSession;
end;

Implementation

procedure TForm1.WMQueryEndSession (var Msg : TWMQueryEndSession);
begin
  if MessageDlg('Close Windows now/ Windows beenden?',
                            mtConfirmation,
                            [mbYes,mbNo], 0) = mrNo then
      Msg.Result := 0
   else
      Msg.Result := 1;
end;

Matze 6. Aug 2005 16:09

Re: Windows beendet Programm nicht
 
Das habe ich auch schon versucht, danke, nur ändert das auch nichts. Ich verstehe das absolut nicht.

TStringlist 6. Aug 2005 16:19

Re: Windows beendet Programm nicht
 
Die Flags (MinimizeAtClose u. AskForClose) müsstest du eigentlich vor dem inherited setzen, da FormCloseQuery nämlich in Delphis eigenen QueryEndSession-Handler aufgerufen wird (und dieser Handler selbst wieder durch das inherited).

TStringlist 6. Aug 2005 16:54

Re: Windows beendet Programm nicht
 
Zitat:

Zitat von Matze
Ich habe auch testweise ShowMessage in der WMQUERYENDSESSION Prozedur und im OnCloseQuery aufgerufen, doch sehe ich nie einen Dialog. Evtl. tritt das Ereignis gar nicht erst ein.

Das wäre eigentlich nur dann möglich, wenn deine Application noch mehr Formen hätte und eine davon die QueryEndSession-Message davor schon bekommen und diese mit False beantwortet hätte. (Das wäre z.B. auch schon dann der Fall, wenn du dort auch schon nur zufälligerweise eine ganz leere << procedure TForm1.WMQUERYENDSESSION(var msg: TMessage); begin end; >> stehen hättest).

Normalerweise bekommen nämlich alle Formen einer Application eine solche Message zugeschickt und nur dann, wenn alle sie mit True beantwortet haben, deaktiviert die Application anschließend auch. Beantwortet nur eine Form diese Message mit false, bekommen die weiteren Formen keine QueryEndSession-Message mehr und die Application bleibt am Leben.


(hoffe ich erzähle hier keinen Bockmist, glaube es aber nicht :-))


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:00 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz