Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Auf Abmelden/Herunterfahren in onClose reagieren (https://www.delphipraxis.net/142347-auf-abmelden-herunterfahren-onclose-reagieren.html)

Dezipaitor 26. Okt 2009 22:40

Re: Auf Abmelden/Herunterfahren in onClose reagieren
 
Schau mal, ob
Delphi-Quellcode:
if GetSystemMetrics(SM_SHUTTINGDOWN) <> 0 then
  //is shutting down
(erst ab XP) dir weiterhilft.
Ich bin mir aber nicht sicher, ob das auch bei Neustart funktioniert.

The_Unknown 26. Okt 2009 22:44

Re: Auf Abmelden/Herunterfahren in onClose reagieren
 
Nope, leider nicht. Das Abmelden z.B. wird nicht erkannt.

BerndS 27. Okt 2009 13:06

Re: Auf Abmelden/Herunterfahren in onClose reagieren
 
Hallo
bei mir ist das so gelöst und klappt bisher ganz gut.


Delphi-Quellcode:
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;
Gruß Bernd

The_Unknown 27. Okt 2009 16:28

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:
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 die Anwendung normal über "X" beende, kommt die Meldung 0, also alles ok.
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!?

ringli 27. Okt 2009 16:53

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;

The_Unknown 27. Okt 2009 16:57

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 ;)

thkerkmann 27. Okt 2009 18:57

Re: Auf Abmelden/Herunterfahren in onClose reagieren
 
Hi,
ich denke Du solltest mal dies versuchen:

Delphi-Quellcode:
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;
ungetestet, aber ähnlich mache ich es in meinen Programmen auch - ausser der TrayMessage.

Gruss

Blup 28. Okt 2009 07:03

Re: Auf Abmelden/Herunterfahren in onClose reagieren
 
Zitat:

Zitat von The_Unknown
Wenn ich die Anwendung normal über "X" beende, kommt die Meldung 0, also alles ok.
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!?

Wenn die Session tatsächlich beendet wird, zeigt Windows neuen Fenster nicht mehr an.

ChrisE 28. Okt 2009 08:50

Re: Auf Abmelden/Herunterfahren in onClose reagieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von The_Unknown
Wenn ich die Anwendung normal über "X" beende, kommt die Meldung 0, also alles ok.
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!?

Wenn ich mich richtig erinnere, hatte ich ein ähnliches Problem. Und soweit ich noch weiß wurde OnClose nicht mehr ausgelöst, wenn der Rechner abgemeldet/heruntergefahren wurde.

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]

The_Unknown 28. Okt 2009 12:53

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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:49 Uhr.
Seite 2 von 3     12 3      

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