![]() |
Hibernate und Standby erkennen
Achtung: Der Code funktioniert nur bis Windows XP!
H4ndy stellt ![]() Zuerst muss die Windows-Nachrichtenabfrage überschrieben werden:
Delphi-Quellcode:
Die genaue Funktion sieht in der Implementierung so aus:
Form1...
procedure WndProc(var MyMessage: TMessage); override;
Delphi-Quellcode:
In der obigen Funktion gehe ich auf die Anfrage zum Standby und Ruhezustand ein.
procedure TForm1.WndProc(var MyMessage: TMessage);
begin if MyMessage.Msg = WM_POWERBROADCAST then begin // windows powermanagement message if (MyMessage.WParam = PBT_APMQUERYSUSPEND) or (MyMessage.WParam = PBT_APMQUERYSTANDBY) then begin // windows want to go into standby or hibernation mode // Hier hin, was getan werden muss, bevor Windows in den Standby darf, // z.B. Netzwerk- oder Datenbankverbindungen trennen, Timer abstellen, etc. MyMessage.Result := 1; // allow standby/hibernation // MyMessage.Result := BROADCAST_QUERY_DENY; // deny standby/hibernation end else if (MyMessage.WParam = PBT_APMRESUMECRITICAL) or (MyMessage.WParam = PBT_APMRESUMESUSPEND) or (MyMessage.WParam = PBT_APMRESUMESTANDBY) then begin // windows returns from standby or hibernation // Hier z.B. Verbindungen wiederherstellen end; end; inherited WndProc(MyMessage); end; Durch abfragen von PBT_APMSUSPEND oder PBT_APMSTANDBY kann man noch etwas ausführen, kurz bevor der PC definitiv in den Standby geht. Sollten die Konstanten nicht verfügbar sein, hier die Deklaration:
Delphi-Quellcode:
Näheres zu den einzelnen Konstanten gibts im Windows SDK unter WM_POWERBROADCAST
PBT_APMQUERYSUSPEND = $0000;
PBT_APMQUERYSTANDBY = $0001; PBT_APMQUERYSUSPENDFAILED = $0002; PBT_APMQUERYSTANDBYFAILED = $0003; PBT_APMSUSPEND = $0004; PBT_APMSTANDBY = $0005; PBT_APMRESUMECRITICAL = $0006; PBT_APMRESUMESUSPEND = $0007; PBT_APMRESUMESTANDBY = $0008; PBTF_APMRESUMEFROMFAILURE = $00000001; PBT_APMBATTERYLOW = $0009; PBT_APMPOWERSTATUSCHANGE = $000A; PBT_APMOEMEVENT = $000B; PBT_APMRESUMEAUTOMATIC = $0012; Windows wartet ca. 10-20 Sekunden auf die Antwort des Programms. |
Re: Hibernate und Standby erkennen
Hallo,
ich untersuche heute den Sachverhalt mal genauer mit einer Test-Applikation, sieht mir unter Vista alles ein bisschen spanisch aus. Wäre bei uns in der Firma bissle schlecht wenn das ganze Verhalten unter Vista nicht mehr funktioniert. |
Re: Hibernate und Standby erkennen
der Windows Media Player scheint es aber doch unter Vista dennoch zu kennen, oder kommt das mir nur so vor?
|
Re: Hibernate und Standby erkennen
Zitat:
Es geht auch weiterhin unter Vista. Getestet habe ich unter Vista Ultimate SP1 sowie XP Pro SP3. Ich hab mir eine kleinen Anwendung geschrieben, welche die leicht modifizierte Funktion von DLG-Luke ( ![]()
Delphi-Quellcode:
(Windowsversion wurde von
unit FormMain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, GetWindowsVersion; type TfrmMain = class(TForm) MemoMessageLog: TMemo; StatusBar1: TStatusBar; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } procedure WMPowerBroadcast(var MyMessage: TMessage); message WM_POWERBROADCAST; end; var frmMain: TfrmMain; const PBT_APMQUERYSUSPEND = $0000; PBT_APMQUERYSTANDBY = $0001; PBT_APMQUERYSUSPENDFAILED = $0002; PBT_APMQUERYSTANDBYFAILED = $0003; PBT_APMSUSPEND = $0004; PBT_APMSTANDBY = $0005; PBT_APMRESUMECRITICAL = $0006; PBT_APMRESUMESUSPEND = $0007; PBT_APMRESUMESTANDBY = $0008; PBTF_APMRESUMEFROMFAILURE = $00000001; PBT_APMBATTERYLOW = $0009; PBT_APMPOWERSTATUSCHANGE = $000A; PBT_APMOEMEVENT = $000B; PBT_APMRESUMEAUTOMATIC = $0012; implementation {$R *.dfm} { TfrmMain } function TranslatePowerBroadcast(const Msg: Cardinal): string; begin case Msg of WM_POWERBROADCAST: Result := 'WM_POWERBROADCAST'; PBT_APMQUERYSUSPEND: Result := 'PBT_APMQUERYSUSPEND'; PBT_APMQUERYSTANDBY: Result := 'PBT_APMQUERYSTANDBY'; PBT_APMQUERYSUSPENDFAILED: Result := 'PBT_APMQUERYSUSPENDFAILED'; PBT_APMQUERYSTANDBYFAILED: Result := 'PBT_APMQUERYSTANDBYFAILED'; PBT_APMSUSPEND: Result := 'PBT_APMSUSPEND'; PBT_APMSTANDBY: Result := 'PBT_APMSTANDBY'; PBT_APMRESUMECRITICAL: Result := 'PBT_APMRESUMECRITICAL'; PBT_APMRESUMESUSPEND: Result := 'PBT_APMRESUMESUSPEND'; PBT_APMRESUMESTANDBY: Result := 'PBT_APMRESUMESTANDBY'; //PBTF_APMRESUMEFROMFAILURE: Result := 'PBTF_APMRESUMEFROMFAILURE'; PBT_APMBATTERYLOW: Result := 'PBT_APMBATTERYLOW'; PBT_APMPOWERSTATUSCHANGE: Result := 'PBT_APMPOWERSTATUSCHANGE'; PBT_APMOEMEVENT: Result := 'PBT_APMOEMEVENT'; PBT_APMRESUMEAUTOMATIC: Result := 'PBT_APMRESUMEAUTOMATIC'; else Result := 'Unknown Message "'+IntToStr(Msg)+'"'; end; end; procedure TfrmMain.WMPowerBroadcast(var MyMessage: TMessage); begin if MyMessage.Msg = WM_POWERBROADCAST then begin MemoMessageLog.Lines.Append('Msg: '+TranslatePowerBroadcast(MyMessage.Msg)); MemoMessageLog.Lines.Append('WParam: '+TranslatePowerBroadcast(MyMessage.WParam)); MemoMessageLog.Lines.Append(''); MemoMessageLog.Lines.SaveToFile(ExtractFileDir(Application.ExeName)+'\Message.log'); // windows powermanagement message if (MyMessage.WParam = PBT_APMQUERYSUSPEND) or (MyMessage.WParam = PBT_APMQUERYSTANDBY) then begin // windows wants to go into standby or hibernation mode // Hier hin, was getan werden muss, bevor Windows in den Standby darf, // z.B. Netzwerk- oder Datenbankverbindungen trennen, Timer abstellen, etc. MyMessage.Result := 1; // allow standby/hibernation // MyMessage.Result := BROADCAST_QUERY_DENY; // deny standby/hibernation end else if (MyMessage.WParam = PBT_APMRESUMECRITICAL) or (MyMessage.WParam = PBT_APMRESUMESUSPEND) or (MyMessage.WParam = PBT_APMRESUMESTANDBY) then begin // windows returns from standby or hibernation // Hier z.B. Verbindungen wiederherstellen end; end; end; procedure TfrmMain.FormCreate(Sender: TObject); begin MemoMessageLog.Lines.Append('Running on:'); MemoMessageLog.Lines.Append(GetWinVersion); MemoMessageLog.Lines.Append(''); end; end. ![]() Heraus kam folgendes:
Code:
Windows Message Log
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Running on: Microsoft Windows Server 2003, Media Center Edition Service Pack 1 (Build 6001) <-- Ist Vista Ult. SP1 Msg: WM_POWERBROADCAST WParam: PBT_APMSUSPEND Msg: WM_POWERBROADCAST WParam: PBT_APMRESUMEAUTOMATIC Msg: WM_POWERBROADCAST WParam: PBT_APMRESUMESUSPEND
Code:
Wie man sieht, lässt Vista nur das "Nachfragen um Erlaubnis" weg, benachrichtigt aber weiterhin die Programme. Meiner Meinung nach ein Rückschritt, da ich noch nicht ermitteln konnte, ob und wie lange man Zeit hat da noch was im Programm abzuarbeiten.
Windows Message Log
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Running on: Microsoft Windows XP Professional Service Pack 3 (Build 2600) Msg: WM_POWERBROADCAST WParam: PBT_APMQUERYSUSPEND Msg: WM_POWERBROADCAST WParam: PBT_APMSUSPEND Msg: WM_POWERBROADCAST WParam: PBT_APMRESUMESUSPEND Msg: WM_POWERBROADCAST WParam: PBT_APMRESUMEAUTOMATIC |
Re: Hibernate und Standby erkennen
http://msdn.microsoft.com/en-us/library/aa372721(VS.85).aspx :arrow:
Zitat:
|
Re: Hibernate und Standby erkennen
Hier die fertige, leicht geänderte Fassung aus dem ersten Post, welche auch unter Vista greifen sollte:
Delphi-Quellcode:
Ausführung für 2000, XP, Vista & wahrscheinlich neuer.
TForm1 = class(TForm)
private { Private declarations } public { Public declarations } procedure WMPowerBroadcast(var MyMessage: TMessage); message WM_POWERBROADCAST; end; Man hat nur noch max. 2 Sekunden Zeit.
Delphi-Quellcode:
Ausführung für 2000 & XP. Vista sendet zu 99% kein "QUERY" mehr.
procedure TForm1.WMPowerBroadcast(var MyMessage: TMessage);
begin if MyMessage.Msg = WM_POWERBROADCAST then begin // windows powermanagement message if (MyMessage.WParam = PBT_APMSUSPEND) or (MyMessage.WParam = PBT_APMSTANDBY) then begin // Hier hin, was getan werden muss, bevor Windows in den Standby darf, // z.B. Netzwerk- oder Datenbankverbindungen trennen, Timer abstellen, etc. // Seit Vista hat man hier nur noch max. 2 Sekunden Zeit was zu erledigen. MyMessage.Result := 1; // Standby/Ruhezustand erlauben // MyMessage.Result := BROADCAST_QUERY_DENY; // Standby/Ruhezustand verweigern end else if (MyMessage.WParam = PBT_APMRESUMECRITICAL) or (MyMessage.WParam = PBT_APMRESUMESUSPEND) or (MyMessage.WParam = PBT_APMRESUMESTANDBY) then begin // Windows kommt aus dem Standby/Ruhezustand wieder. // Hier z.B. Verbindungen wiederherstellen. end; end; inherited; end; Hier hat man noch ca. 10-20 Sekunden Zeit etwas zu erledigen.
Delphi-Quellcode:
procedure TForm1.WMPowerBroadcast(var MyMessage: TMessage);
begin if MyMessage.Msg = WM_POWERBROADCAST then begin // windows powermanagement message if (MyMessage.WParam = PBT_APMQUERYSUSPEND) or (MyMessage.WParam = PBT_APMQUERYSTANDBY) then begin // Hier hin, was getan werden muss, bevor Windows in den Standby darf, // z.B. Netzwerk- oder Datenbankverbindungen trennen, Timer abstellen, etc. // Windows wartet ca. 10-20 Sekunden auf die Antwort des Programms. MyMessage.Result := 1; // Standby/Ruhezustand erlauben // MyMessage.Result := BROADCAST_QUERY_DENY; // Standby/Ruhezustand verweigern end else if (MyMessage.WParam = PBT_APMRESUMECRITICAL) or (MyMessage.WParam = PBT_APMRESUMESUSPEND) or (MyMessage.WParam = PBT_APMRESUMESTANDBY) then begin // Windows kommt aus dem Standby/Ruhezustand wieder. // Hier z.B. Verbindungen wiederherstellen. end; end; inherited; end; |
Re: Hibernate und Standby erkennen
Es kann sein das ich das falsch verstehe aber die Standby-Sachen wie PBT_APMSTANDBY werden doch nicht mehr unterstützt, oder?
![]() |
Re: Hibernate und Standby erkennen
Zitat:
|
Re: Hibernate und Standby erkennen
ich fahr einige Programme von mir auch in 'nen Pausemodus, bevor der PC in den Standby/Hibernate fährt ... damit beim runterfahren/hochfahren die Festplatten nicht so ausgelastet sind (und falls beim Hochfahren die entsprechenden Verzeichnisse noch nicht gleich verfügbar sind)
was ich nur Blöd vind, daß einige Programme durch blokieren dieser Abfragen den PC am runterfahren hindern (wozu muß meine TV-Software denn den PC am ausschalten hindern?) OK, die dexplore.exe dreht hier auch durch und läßt manchma den PC sich nichtmal ausschalten. |
Re: Hibernate und Standby erkennen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:21 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