AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Hibernate und Standby erkennen

Ein Thema von fkerber · begonnen am 27. Dez 2008 · letzter Beitrag vom 4. Feb 2009
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von fkerber
fkerber
(CodeLib-Manager)

Registriert seit: 9. Jul 2003
Ort: Ensdorf
6.723 Beiträge
 
Delphi XE Professional
 
#1

Hibernate und Standby erkennen

  Alt 27. Dez 2008, 15:18
Achtung: Der Code funktioniert nur bis Windows XP!

H4ndy stellt hier ein Stückchen Code vor, mit dem es möglich ist, zu erkenne, wenn Windows in Standby oder Ruhezustand geht:

Zuerst muss die Windows-Nachrichtenabfrage überschrieben werden:
Delphi-Quellcode:
Form1...
procedure WndProc(var MyMessage: TMessage); override;
Die genaue Funktion sieht in der Implementierung so aus:

Delphi-Quellcode:
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;
In der obigen Funktion gehe ich auf die Anfrage zum Standby und Ruhezustand ein.
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:
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;
Näheres zu den einzelnen Konstanten gibts im Windows SDK unter WM_POWERBROADCAST

Windows wartet ca. 10-20 Sekunden auf die Antwort des Programms.
Frederic Kerber
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#2

Re: Hibernate und Standby erkennen

  Alt 19. Jan 2009, 10:08
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.
Manuel
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#3

Re: Hibernate und Standby erkennen

  Alt 19. Jan 2009, 10:32
der Windows Media Player scheint es aber doch unter Vista dennoch zu kennen, oder kommt das mir nur so vor?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#4

Re: Hibernate und Standby erkennen

  Alt 19. Jan 2009, 11:11
Zitat von himitsu:
der Windows Media Player scheint es aber doch unter Vista dennoch zu kennen, oder kommt das mir nur so vor?
Richtig.

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 (hier) nutzt:

Delphi-Quellcode:
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.
(Windowsversion wurde von diesem Code hier ermittelt, hat wohl Probleme mit nem aktuellen Vista)

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:
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
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.
Manuel
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

Re: Hibernate und Standby erkennen

  Alt 19. Jan 2009, 11:30
http://msdn.microsoft.com/en-us/library/aa372721(VS.85).aspx
Zitat:
The system allows approximately two seconds for an application to handle this notification. If an application is still performing operations after its time allotment has expired, the system may interrupt the application.
Windows Server 2003 and Windows XP/2000: Applications are allowed up to 20 seconds to respond to the PBT_APMSUSPEND event.
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#6

Re: Hibernate und Standby erkennen

  Alt 3. Feb 2009, 13:32
Hier die fertige, leicht geänderte Fassung aus dem ersten Post, welche auch unter Vista greifen sollte:

Delphi-Quellcode:
TForm1 = class(TForm)
private
  { Private declarations }
public
  { Public declarations }
  procedure WMPowerBroadcast(var MyMessage: TMessage); message WM_POWERBROADCAST;
end;
Ausführung für 2000, XP, Vista & wahrscheinlich neuer.
Man hat nur noch max. 2 Sekunden Zeit.
Delphi-Quellcode:
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;
Ausführung für 2000 & XP. Vista sendet zu 99% kein "QUERY" mehr.
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;
Manuel
  Mit Zitat antworten Zitat
Benutzerbild von Mr_G
Mr_G

Registriert seit: 2. Sep 2004
Ort: Duisburg
468 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Hibernate und Standby erkennen

  Alt 3. Feb 2009, 18:37
Es kann sein das ich das falsch verstehe aber die Standby-Sachen wie PBT_APMSTANDBY werden doch nicht mehr unterstützt, oder?
http://msdn.microsoft.com/en-us/libr...47(VS.85).aspx
Jan
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#8

Re: Hibernate und Standby erkennen

  Alt 3. Feb 2009, 22:18
Zitat von Mr_G:
Es kann sein das ich das falsch verstehe aber die Standby-Sachen wie PBT_APMSTANDBY werden doch nicht mehr unterstützt, oder?
http://msdn.microsoft.com/en-us/libr...47(VS.85).aspx
Hmm keine Ahnung, jedenfalls kommen bei mir nach wie vor die entsprechenden Nachrichten am Programm an (siehe Testframe von mir). Wäre aber auch sehr schlecht, wenn es diese Nachrichten nicht mehr geben würde, da diese doch recht kritisch sind, vorallem wenn es um Netzwerk-Sachen geht.
Manuel
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#9

Re: Hibernate und Standby erkennen

  Alt 3. Feb 2009, 22:28
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#10

Re: Hibernate und Standby erkennen

  Alt 3. Feb 2009, 22:59
Zitat von himitsu:
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?)
Weil du dich sonst während des fernsehschauens auf dem Laptop aufregst, wenn der nach 20 Min des Nichtstuns am Rechner (keine Aktionen), da du fernsiehst, der Rechner herunter fährt. Gleiches gilt für den Bildschirmschoner für TV Software, DVD & Media Player, etc.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:25 Uhr.
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