Autor Beitrag
fero
Hält's aus hier
Beiträge: 14

WinXP, Vista
D5, D7, D2005 PE
BeitragVerfasst: Do 02.06.05 00:04 
Hallo,

ich habe da folgendes Problem: Ich habe ein Programm geschrieben, das im Hintergrund ständig aktiv ist und den User warnen soll, falls er den Rechner herunterfahren will und das Programm noch nicht bereit dazu ist. Das ist soweit kein Problem, aber Windows macht mir einen kleinen Strich durch die Rechnung. Ich fange also WM_QUERYENDSESSION ab und öffne eine MessageBox (Win API, nicht Delphi), die der User erst mit "Nein" beantworten muss, bevor das System endgültig herunterfährt.

Meine Nachricht taucht auf - so weit, so gut. Dummerweise taucht fünf Sekunden später eine weitere Box auf, in der Windows vorschlägt, mein Programm "sofort zu beenden", weil es angeblich nicht reagiert (ich denke, Ihr kennt das Fenster alle... :D), nur weil der User meine Box nicht innerhalb dieser fünf Sekunden beantwortet hat (der Text darin ist manchmal ziemlich lang). Mal abgesehen davon, dass dieses Ding im Vordergrund auftaucht (was sich ja vermutlich umgehen lässt), ist es an sich ziemlich blöd, da der User vorzugsweise MEIN Fenster beantworten und nicht auf "sofort beenden" klicken sollte.

Kann ich - ohne das System des Users anzupassen (von wegen schnelles Herunterfahren und ähnliche Scherze) - Windows davon abhalten, diese Nachricht anzuzeigen, ohne den Shutdown vor Anzeige meiner MessageBox abzubrechen?

Bin dankbar für jeden Tipp.

Edit:

Hm, ich habe jetzt festgestellt, dass es zwei Arten von diesen doofen "sofort beenden" Fenstern gibt. Eins, in dem steht, dass das Programm nicht reagiert und sich dann dieser Fortschrittsbalken bewegt (so eins hab ich) und eins, in dem steht, dass das Programm eine Interaktion vom Benutzer erwartet (so eins will ich). Denn dort gibt's keinen Timer, der abläuft, sondern nur die Buttons "Sofort beenden" und "Abbrechen". In ersterem Fenster gibt es nur den Button "Sofort beenden". Letzteres Fenster taucht z.B. auf, wenn man herunterfahren will und der Editor noch schnell fragt, ob man speichern möchte. Irgendwie teilt der Windows anscheinend mit, dass er auf eine Benutzereingabe wartet. Das möchte ich auch. Wie kann ich das denn machen? Vielen Dank im Voraus.


Gruß -- Andy aka fero
arj
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 378

Win XP/Vista, Debian, (K)Ubuntu
Delphi 5 Prof, Delphi 7 Prof, C# (#Develop, VS 2005), Java (Eclipse), C++, QT, PHP, Python
BeitragVerfasst: Fr 03.06.05 08:16 
Bin mir nicht hunderprozentig sicher, aber ich vermute, dass du die Message WM_QUERYENDSESSION beantworten solltest bevor du deine MessageBox darstellst.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
TMyThread = class(TThread)
protected
  procedure Execute; override;
public
  MsgBoxResult : Integer;
end;
[...]
TMyForm = class(TForm)
private
  FSelfShutDown : Boolean;
  thread : TMyThread;
  procedure WMQueryEndSession(var msg : TMessage); message WM_QUERYENDSESSION;
  procedure OnThreadFinished(Sender : TObject);
end;
[...]
procedure TMyThread.Execute;
begin
  MsgBoxResult := MessageDlg('Wirklich herunterfahren?',[mbyes,mbno],0);
  FreeOnTerminate := True;
end;
[...]
procedure TMyForm.OnCreate(Sender : TObject);
begin
  FSelfShutDown  := False;
  thread := TMyThread.Create(true);
  thread.OnFinished := OnThreadFinished;
end;

procedure TMyForm.WMQueryEndSession(var msg : TMessage);
begin
  if not FSelfShutDown then
  begin
    Result := False
    thread.Resume;
  end
  else
    Result := True;
end;

procedure TMyForm.OnThreadFinished(Sender : TObject);
begin
  if (Sender as TMyThread).MsgBoxResult = mrYes then
  begin
     { Hier muss ggf. EWX_LOGOFF verwendet werden, siehe WM_QUERYENDSESSION.lParam
       und evtl. noch Berechtigungen gesetzt werden }

     FSelfShutDown := True;
     ExitWindowsEx(EWX_SHUTDOWN,0);
  end;
end;


Der Source ist nicht getestet, da ich momentan kein Delphi verfügbar ist. :)
Viel Spaß beim Testen.
Harry M.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754

Win 2000, XP
D2005
BeitragVerfasst: Fr 03.06.05 09:04 
Reicht es nicht wenn Du in WMQueryEndSession das weitere runterfahren abbrichst mit  FALSE dann dürfte doch auch kein Windows-Fenster kommen??

Ich habe nämlich nen ähnliches Problem - nur genaus anderes rum - bei mir will er nicht runterfahren trotz  TRUE.

_________________
Gruß Harry
Et spes me per dies sine te ducat et amor me ferat, si dolor spem tollit.
arj
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 378

Win XP/Vista, Debian, (K)Ubuntu
Delphi 5 Prof, Delphi 7 Prof, C# (#Develop, VS 2005), Java (Eclipse), C++, QT, PHP, Python
BeitragVerfasst: Fr 03.06.05 14:17 
@Harry M.:

Er will doch eine MessageBox mit Auswahl, ob trotzdem heruntergefahren werden soll!
(Zumindest habe ich es so verstanden)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 03.06.05 14:35 
Wenn's Hooks sein dürfen: Hooken der Funktionen ExitWindowsEx und InitiateSystemShutdown (NT-based).

Dafür muss aber ein globaler Hook eingerichtet werden. Siehe uallCollection.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
STATUS_ACCESS_DENIED
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 13.06.05 11:47 
user profile iconBenBE hat folgendes geschrieben:
Wenn's Hooks sein dürfen: Hooken der Funktionen ExitWindowsEx und InitiateSystemShutdown (NT-based).
Und was noch alles? Seid doch fair zu ihm und sagt ihm, daß es nicht geht.