Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Hibernate und Standby erkennen (https://www.delphipraxis.net/81507-hibernate-und-standby-erkennen.html)

himitsu 28. Nov 2006 13:27


Hibernate und Standby erkennen
 
Hab zwar schon einiges gefunden, wie man das Herunterfahren erkennen kann (WINDOWS_SESSION_END und Co.),
allerdings bekommt man nirgends ein Ereignis, wenn der Rechner in den Standby, oder Ruhezustand gefahren wird.

Ich würde einfach gerne mein Programm in einen Pausemodus versetzen, wenn derartiges passiert.


PS: der MediaPlayer (ich glaub seit v7) kann ja auch sowas.

H4ndy 28. Nov 2006 15:27

Re: Hibernate und Standby erkennen
 
Folgendes ist nötig, um auf den Standby oder Ruhezustand (Hibernation) reagieren zu können
(inkl. Nachricht, wenn das System aus diesem wieder zurückgeholt wird):

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

Nachtrag:
Windows wartet was um die 10-20 Sekunden auf die Antwort deine Programms,
von daher würde ich nix großartig rechenintensives machen ;)

DGL-luke 28. Nov 2006 15:33

Re: Hibernate und Standby erkennen
 
Das geht auch einfacher ;)

Einfach in den Klassenrumpf von TForm1 (bzw. der hauptform halt)

Delphi-Quellcode:
procedure WMPowerBroadcast(var Msg: TMessage); message WM_POWERBROADCAST;
Darin kann man dann alles machen, was man auch in der Windowproc hätte machen können. Entzerrt einiges.

himitsu 4. Dez 2006 16:46

Re: Hibernate und Standby erkennen
 
Jo, funktioniert perfekt :)

dankö :angel:

fkerber 22. Aug 2007 11:47

Re: Hibernate und Standby erkennen
 
Hi!

Den Code würde ich gerne in die Codelib übernehmen, allerdings scheint es ein Problem mit Windows Vista zu geben.

Im MSDN findet sich

Zitat:

The following messages are not supported on any of the operating systems listed in the Requirements section:


PBT_APMQUERYSTANDBY
PBT_APMQUERYSTANDBYFAILED
PBT_APMSTANDBY
PBT_APMRESUMESTANDBY
Zitat:

Requirements
Client
Requires Windows Vista, Windows XP, or Windows 2000 Professional.

Server
Requires Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
Quelle: http://msdn2.microsoft.com/en-us/library/aa373247.aspx

Ein Test unter Vista zeigt auch, dass oben stehender Code wohl nicht mehr funktioniert...

Kann das jemand widerlegen oder hat vllt. anderen/funktionierenden Code, der auch unter Vista funktioniert?


Ciao, Frederic

r_amse_s 5. Dez 2007 15:02

Re: Hibernate und Standby erkennen
 
tatsächlich wird unter Vista das Abfangen von standby- und sleepmode nicht mehr supportet.
schade...

...oder kann jemand das gegenteil behaupten ?

himitsu 5. Dez 2007 15:21

Re: Hibernate und Standby erkennen
 
Wieso hat Windows dieses denn entfernt o.O

ein Programm, welches "ausversehn" ein Runterfahren (Standby/Hypernate) verhindert, kann so doch garnicht mehr darauf reagieren und die Behinderung beseitigen?

Der_Ventilator 14. Nov 2010 17:43

AW: Hibernate und Standby erkennen
 
Wie sieht es denn z.Z. aus? Läuft der oben vor 3 Jahren genannte Code immernoch weder unter Vista noch Windows 7? Gibt es alternativen?

sar3th 17. Dez 2010 13:35

AW: Hibernate und Standby erkennen
 
Laut MSDN gibt es jetzt PBT_APMSUSPEND. In meinen Tests auf Windows 7 hat das auch zuverlässig funktioniert :)
Delphi-Quellcode:
procedure WMPowerBroadcast(var Msg: TMessage); message WM_POWERBROADCAST;
Delphi-Quellcode:
//Beispiel-Routine
procedure TfrmMain.WMPowerBroadcast(var Msg: TMessage);
begin
  case Msg.wParam of
    PBT_APMSUSPEND:
    begin
      //System wird in einen Energiesparmodus versetzt
    end;
    PBT_APMRESUMESUSPEND:
    begin
      //System ist wieder aufgewacht
    end;
    PBT_APMRESUMEAUTOMATIC:
    begin
      //Nach dem Aufwachen wurde eine Benutzeraktivität festgestellt
    end;
  end;
end;
Allerdings hab ich nichts gefunden um festzustellen, ob das System in den Ruhezustand oder Standby wechselt. APMSUSPEND kommt bei beiden und gibt laut MSDN keine Auskunft darüber.
Hat jemand eine Idee wie man das rausfinden kann?

Der_Ventilator 17. Dez 2010 15:21

AW: Hibernate und Standby erkennen
 
Ist das wichtig, ob Standby oder Ruhezustand? Windows 7 wechselt in der Standardeinstellung "Energie sparen" in den Ruhezustand UND Standbymodus gleichzeitig. Und wacht dann aus dem Standby oder -wenn zwischendrin der Strom weg war- aus dem Ruhezustand wieder auf.

sar3th 20. Dez 2010 00:05

AW: Hibernate und Standby erkennen
 
In dem Fall ist es gewünscht, da ich gerne ein kleines Log meiner Batterie und Rechnernutzung erstellen würde, um das im Nachhinein auswerten zu können (also ein "Batterie-Benchmark"). Ich aktiviere den Ruhezustand/Standby via Startmenü oder Energiespartaste manuell, in dem Fall greift die Automatik von Windows 7 sowieso nicht. Das aber jedes mal dem Programm von Hand mitzuteilen wäre extrem lästig, deswegen dieser Ansatz.

Der_Ventilator 20. Dez 2010 12:24

AW: Hibernate und Standby erkennen
 
Wenn das Programm nur für dich ist, könntest du den Ruhezustand oder Standby über das Programm selbst aufrufen.
Vielleicht mit zwei Desktopverknüpfungen, die mittels Parameter dem Programm sagen, den Log zu starten und den Rechner in den gewünschten Modus zu versetzen.

Aber andererseits ist es bestimmt möglich, zu erkennen, welcher Modus aktiv war (vielleicht aus der Ereignisanzeige von Windows?).

Wie läuft das eigentlich bei dem hybriden Modus. Wenn mein Laptop in diesem ist, wann entscheidet Windows den Standby aufzugeben und in den Ruhezustand zu wechseln? Wenn die Batterie leer ist oder schon vorher, wenn "abzusehen" ist, dass in nächster Zeit ich das Laptop nicht mehr anschalten werde? Oder ist das erst 3 Tage in der Tasche im Standby und hat dann keine Energie mehr?

Cylence 20. Dez 2010 12:42

AW: Hibernate und Standby erkennen
 
hi,

ich verwende folgende kleine freie komponente, mit der kann man auch shutdowns verhindern, aber es hat events für wakeupfromhibernate und wakeupfromstandby...

Hier gibts das teil:

http://www.delphipages.com/comp/pwrsave-4884.html

gruß

tom

mm1256 22. Jul 2016 09:15

AW: Hibernate und Standby erkennen
 
Hallo,

jetzt habe ich auch das Problem, dass ich Energiesparmodus und Ruhezustand verhindern muss. So funktioniert das leider nicht:

Delphi-Quellcode:
procedure TForm1.WMPowerBroadcast(var Msg: TMessage);
var
  t: TextFile;
begin
  case Msg.wParam of
    PBT_APMSUSPEND:
      begin // System wird in einen Energiesparmodus versetzt
        Msg.Result := BROADCAST_QUERY_DENY;
        AssignFile(t,'D:\BROADCAST_QUERY_DENY.TXT');
        Rewrite(t);
        WriteLn(t,TimeToStr(Now)+' ==> Msg.wParam.BROADCAST_QUERY_DENY');
        CloseFile(t);
      end;
    PBT_APMRESUMESUSPEND:
      begin //System ist wieder aufgewacht
        ShowMessage('Energiesparmodus: Hurrraaa wir leben wieder');
      end;
    PBT_APMRESUMEAUTOMATIC:
      begin //Nach dem Aufwachen wurde eine Benutzeraktivität festgestellt
        ShowMessage('Energiesparmodus: ...und aktiv sind wir auch schon wieder ;-)');
      end;
  end;
end;
ALle 3 Messages werden gefeuert, aber Msg.Result := BROADCAST_QUERY_DENY bewirkt nichts. Wo ist da der Haken?

Der schöne Günther 22. Jul 2016 09:32

AW: Hibernate und Standby erkennen
 
Ohne es je gemacht zu haben, ich würde sagen so ist es schon zu spät. Da ist die Entscheidung sich schlafen zu legen schon gefallen.

Du musst vorher mit SetThreadExecutionState(..) festlegen dass sich das System bitte nicht schlafen legt bis du es wieder erlaubst.

Sir Rufo 22. Jul 2016 09:39

AW: Hibernate und Standby erkennen
 
Ab Vista muss man mit
Delphi-Quellcode:
SetThreadExecutionState
arbeiten

https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx

t.roller 22. Jul 2016 10:30

AW: Hibernate und Standby erkennen
 
Ab WIN7: PowerCreateRequest

Der schöne Günther 22. Jul 2016 10:42

AW: Hibernate und Standby erkennen
 
Zitat:

Zitat von t.roller (Beitrag 1343182)

Wenn ich das richtig verstehe geht es da um "Connected Standby", ein Feature das (soweit ich weiß) nur ziemlich neue Mobilgeräte haben. Damit bittet eine Anwendung, auch im Standby weiterlaufen zu dürfen. Aber wie lange sie das darf entscheidet das Betriebssystem.

Vielleicht liege ich auch daneben.

mm1256 22. Jul 2016 10:59

AW: Hibernate und Standby erkennen
 
Vielen Dank für die Antworten!

Mann oh Mann ist das wieder eine komplizierte Sache. Ich hoffte schon, das (Programmierer-)Leben könnte ausnahmsweise auch mal freundlich zu einem sein. Vielleicht (sehr wahrscheinlich sogar) habe ich mich auch falsch bzw. unvollständig ausgedrückt, denn so richtig "komplett" verhindern will ich Hibernate und Standby nicht. Es geht um folgendes:

Vorhanden ist eine MDI-Anwendung die eine Client-Server-Datenbank verwendet. Was machen die Kunden? Sie haben mehrere MDI's geöffnet, und womöglich noch ein modales Fenster, das von einem MDI-Fenster aus geöffnet wurde. Dann ist Mittagspause, und keiner schert sich darum, wenigstens einen laufenden Editiervorgang zu benden, bevor man den Arbeitsplatz verlässt. Da kann man predigen was man will :cyclops:

Wenn sie dann von der Mittagspause zurück kommen und der PC ist im Standby....ist natürlich die Verbindung zum DB-Server abgebrochen. Nun kann ich ja nicht bei jedem Editiervorgang oder Fensterwechsel (MDIChildCount > 0) usw. mit SetThreadExecutionState regieren, das wäre overkill.

Wenn bei PBT_APMSUSPEND MDIChildCount 0 ist, dann schließe ich einfach die DB-Verbindung und gut isses, aber was tun wenn MDICHildCount > 0 ist, und noch modale Fenster offen sind? Ich denke, da muss ich jetzt ansetzen, weil mit SetThreadExecutionState komme ich wohl nicht weiter. Es sei denn, jemand hätte eine geniale Idee?

Neutral General 22. Jul 2016 12:53

AW: Hibernate und Standby erkennen
 
Ja gut aber WAS willst du denn machen? Wenn ein MDI-Child offen ist willst du Standby nicht verhindern, aber du willst auch kein Standby haben. :gruebel: Du musst dich für eins entscheiden.
Oder hoffst du auf eine Datenbankverbindung die den Standby überlebt? Keine Ahnung ob sowas geht, aber darauf würde ich nicht wetten.

Sir Rufo 22. Jul 2016 12:59

AW: Hibernate und Standby erkennen
 
Adhoc sehe ich zwei Möglichkeiten:
  1. Stateless mit einem ClientDataSet (der Umbau wird aber wohl zu aufwändig sein)
  2. Eine statische Klasse die Tokens (Interface wegen ARC) herausgibt und beim ersten Token den Modus setzt und beim Verschwinden des letzten Tokens den Status wieder zurücksetzt (geringer Aufwand beim Einbau in das aktuelle Programm)

Auf die Schnelle mal dahingetippt
Delphi-Quellcode:
unit System.PowerManagement;

interface

uses
  System.Generics.Collections;

type
  TPowerModeOption = ( Display, System, Away );
  TPowerModeOptions = set of TPowerModeOption;

  IPowerManagementToken = interface
    [ '{F6326420-9BE9-4CAE-9EC8-0E6C4EE1B265}' ]
    function GetOptions( ): TPowerModeOptions;
    property Options: TPowerModeOptions read GetOptions;
  end;

  IPowerManagementService = interface
    procedure SetOptions( PowerModeOptions: TPowerModeOptions );
  end;

  PowerManagement = class sealed
  private type
    TInternalPowerManagementToken = class
    private
      FOptions: TPowerModeOptions;
    public
      constructor Create( Options: TPowerModeOptions );
      destructor Destroy; override;

      property Options: TPowerModeOptions read FOptions;
    end;

    TPowerManagementToken = class( TInterfacedObject, IPowerManagementToken )
    private
      function GetOptions( ): TPowerModeOptions;
    private
      FToken: TInternalPowerManagementToken;
    public
      constructor Create( Options: TPowerModeOptions );
      destructor Destroy; override;
    end;

    TNullService = class( TInterfacedObject, IPowerManagementService )
    private { IPowerManagementService }
      procedure SetOptions( PowerModeOptions: TPowerModeOptions );
    end;
  private
    class var _Service      : IPowerManagementService;
    class var _Tokens       : TList<TInternalPowerManagementToken>;
    class var _CurrentOptions: TPowerModeOptions;
    class constructor Create( );
    class destructor Destroy( );
    class procedure TokensNotify( Sender: TObject; const Item: TInternalPowerManagementToken; Action: TCollectionNotification );
  public
    class function GetToken( const PowerModeOptions: TPowerModeOptions ): IPowerManagementToken;
  end;

implementation

uses
{$IFDEF MSWINDOWS}
  System.PowerManagement.Win,
{$ENDIF}
  System.SysUtils;

{ PowerManagement.TPowerManagementToken }

constructor PowerManagement.TPowerManagementToken.Create( Options: TPowerModeOptions );
begin
  inherited Create( );
  if Options <> [ ]
  then
    FToken := TInternalPowerManagementToken.Create( Options );
end;

destructor PowerManagement.TPowerManagementToken.Destroy;
begin
  FToken.DisposeOf( );
  inherited;
end;

function PowerManagement.TPowerManagementToken.GetOptions: TPowerModeOptions;
begin
  if Assigned( FToken )
  then
    Result := FToken.Options
  else
    Result := [ ];
end;

{ PowerManagement }

class constructor PowerManagement.Create;
begin
{$IFDEF MSWINDOWS}
  _Service := TWindowsPowerManagementService.Create;
{$ELSE}
  _Service := TNullService.Create;
{$ENDIF}
  _Tokens         := TList<TInternalPowerManagementToken>.Create( );
  _Tokens.OnNotify := TokensNotify;
  _CurrentOptions := [ ];
end;

class destructor PowerManagement.Destroy;
begin
  _Service.SetOptions( [ ] );
  _Tokens.Free;
end;

class function PowerManagement.GetToken( const PowerModeOptions: TPowerModeOptions ): IPowerManagementToken;
var
  lToken: TPowerManagementToken;
begin
  lToken := TPowerManagementToken.Create( PowerModeOptions );
  Result := lToken;
end;

class procedure PowerManagement.TokensNotify(
  Sender   : TObject;
  const Item: TInternalPowerManagementToken;
  Action   : TCollectionNotification );
var
  lToken : TInternalPowerManagementToken;
  lOptions: TPowerModeOptions;
begin
  lOptions := [ ];

  for lToken in _Tokens do
    begin
      lOptions := lOptions + lToken.FOptions;
    end;

  if _CurrentOptions <> lOptions
  then
    begin
      _Service.SetOptions( lOptions );
      _CurrentOptions := lOptions;
    end;
end;

{ PowerManagement.TNullService }

procedure PowerManagement.TNullService.SetOptions( PowerModeOptions: TPowerModeOptions );
begin
  // do nothing
end;

{ PowerManagement.TInternalPowerManagementToken }

constructor PowerManagement.TInternalPowerManagementToken.Create( Options: TPowerModeOptions );
begin
  inherited Create;
  FOptions := Options;
  _Tokens.Add( Self );
end;

destructor PowerManagement.TInternalPowerManagementToken.Destroy;
begin
  _Tokens.Remove( Self );
  inherited;
end;

end.
Delphi-Quellcode:
unit System.PowerManagement.Win;

interface

uses
  Winapi.Windows,
  System.SysUtils,
  System.PowerManagement;

type
  TWindowsPowerManagementService = class( TInterfacedObject, IPowerManagementService )
  private { IPowerManagementService }
    procedure SetOptions( PowerModeOptions: TPowerModeOptions );
  end;

implementation

{ TWindowsPowerManagementService }

procedure TWindowsPowerManagementService.SetOptions( PowerModeOptions: TPowerModeOptions );
var
  esFlags: Cardinal;
  lResult: Cardinal;
begin
  esFlags := 0;

  if TPowerModeOption.Display in PowerModeOptions
  then
    esFlags := esFlags or ES_DISPLAY_REQUIRED;
  if TPowerModeOption.System in PowerModeOptions
  then
    esFlags := esFlags or ES_SYSTEM_REQUIRED;
  if TPowerModeOption.Away in PowerModeOptions
  then
    esFlags := esFlags or ES_AWAYMODE_REQUIRED;

  if esFlags <> 0
  then
    esFlags := esFlags or ES_CONTINUOUS;

  lResult := SetThreadExecutionState( esFlags );
  if lResult = 0
  then
    raise Exception.Create( 'Could not set ThreadExecutionState' );
end;

end.
Delphi-Quellcode:
unit Forms.MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes, System.PowerManagement,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class( TForm )
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    SetModeButton: TButton;
    ClearModeButton: TButton;
    procedure ClearModeButtonClick( Sender: TObject );
    procedure SetModeButtonClick( Sender: TObject );
  private
    FToken: IPowerManagementToken;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ClearModeButtonClick( Sender: TObject );
begin
  FToken := nil;
end;

procedure TForm1.SetModeButtonClick( Sender: TObject );
var
  lOptions: TPowerModeOptions;
begin
  lOptions := [ ];

  if CheckBox1.Checked
  then
    lOptions := lOptions + [ TPowerModeOption.Display ];

  if CheckBox2.Checked
  then
    lOptions := lOptions + [ TPowerModeOption.System ];

  if CheckBox3.Checked
  then
    lOptions := lOptions + [ TPowerModeOption.Away ];

  FToken := PowerManagement.GetToken( lOptions );
end;

end.

mm1256 22. Jul 2016 16:48

AW: Hibernate und Standby erkennen
 
Danke @Sir Rufo für das Beispiel. Um auf Anhieb zu verstehen, wie du das meinst, muss ich erst mal meinen Kenntnisstand etwas vertiefen. Schöne Aufgabe für das Wochenende.

Zitat:

Zitat von Neutral General (Beitrag 1343189)
Ja gut aber WAS willst du denn machen? Wenn ein MDI-Child offen ist willst du Standby nicht verhindern, aber du willst auch kein Standby haben. :gruebel: Du musst dich für eins entscheiden.
Oder hoffst du auf eine Datenbankverbindung die den Standby überlebt? Keine Ahnung ob sowas geht, aber darauf würde ich nicht wetten.

Es ist so, wenn kein MDI aktiv ist, habe ich kein Problem damit, bei PBT_APMSUSPEND die Db-Connection zu schließen, und bei PBT_APMRESUMEAUTOMATIC (das kommt ja schon, wenn der User nur seine Maus bewegt) wieder zu verbinden. Wenn aber MDI- oder andere Fenster geöffnet sind, müsste ich mir den Zustand (offen/geschlossen), den Satzzeiger (DB-Cursor) und den Status (Browse, Edit usw.) aller offenen Datenbanken merken und anschließend wieder restaurieren. Dass ist sehr aufwändig, wenn nicht gar unmöglich. Die Datenbank (NexusDB) unterstützt auch einen Re-Connect, aber eben diese umfassende Restauration nicht, und dann kommt die Standby-Verhinderung ins Spiel.

Sir Rufo 22. Jul 2016 18:00

AW: Hibernate und Standby erkennen
 
@mm1256

Eigentlich ganz einfach:

In jeder Form-Instanz die jetzt den Ruhezustand doof finden würde, holst du dir einfach ein Token
Delphi-Quellcode:
FToken := PowerManagement.GetToken( [ TPowerModeOption.System ] );
.

Es ist egal ob du dir das Token holst, wenn die Instanz erzeugt wird, oder erst zum Zeitpunkt wenn du einen Ruhezustand-Kritischen Moment erreichst.

Wenn es der Form-Instanz dann wieder egal ist, ob das System in den Ruhezustand geht, dann einfach das Token auf
Delphi-Quellcode:
nil
setzen.

Die
Delphi-Quellcode:
PowerManagement
-Klasse sorgt nun dafür, dass der Modus ab einem Token eingeschaltet wird und auch wieder ausgeschaltet wird, wenn es kein Token mehr gibt.

mm1256 23. Jul 2016 10:52

AW: Hibernate und Standby erkennen
 
Vielen Dank Sir Rufo für die Erklärung! :thumb:

Jetzt hätte ich nur noch ein Problem zu lösen: Die Anwendung verwendet insgesamt (grob geschätzt) etwa 150 Formulare, aufgeteilt auf mehrere Module (Exen). Viele von den Formularen sind vererbt. Das reduziert zwar den Aufwand etwas, ist mir aber trotzdem noch etwas zu hoch. Aber, für ein kleineres Projekt in dem ich auch diese Anforderung habe, werde ich es mal ausprobieren!

Sir Rufo 23. Jul 2016 11:19

AW: Hibernate und Standby erkennen
 
Du kannst dir diese Funktionalität auch mit einer Unit hineinbringen
Delphi-Quellcode:
unit Vcl.BaseForm;

interface

uses
  System.PowerManagement,
  Vcl.Forms;

type
  TForm = class( Vcl.Forms.TForm )
  private
    FToken: IPowerManagementToken;
    function GetPowerModeOptions: TPowerModeOptions;
    procedure SetPowerModeOptions( const Value: TPowerModeOptions );
  protected
    function GetDefaultPowerMode( ): TPowerModeOptions; virtual;
    property PowerModeOptions: TPowerModeOptions read GetPowerModeOptions write SetPowerModeOptions;
  public
    procedure AfterConstruction; override;
  end;

implementation

{ TForm }

procedure TForm.AfterConstruction;
begin
  FToken := PowerManagement.GetToken( GetDefaultPowerMode( ) );
  inherited;
end;

function TForm.GetDefaultPowerMode: TPowerModeOptions;
begin
  Result := [ ];
end;

function TForm.GetPowerModeOptions: TPowerModeOptions;
begin
  Result := FToken.Options;
end;

procedure TForm.SetPowerModeOptions( const Value: TPowerModeOptions );
begin
  if PowerModeOptions <> Value
  then
    FToken := PowerManagement.GetToken( Value );
end;

end.
und diese Unit einfach nur noch nach der
Delphi-Quellcode:
Vcl.Forms
in die uses Liste aufnehmen. Dann brauchst du bei den Forms, die so etwas benötigen entweder nur die
Delphi-Quellcode:
GetDefaultPowerMode
zu überschreiben oder du setzt einfach den Wert der Eigenschaft
Delphi-Quellcode:
PowerModeOptions
.

;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:24 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