AGB  ·  Datenschutz  ·  Impressum  







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

Hibernate und Standby erkennen

Ein Thema von himitsu · begonnen am 28. Nov 2006 · letzter Beitrag vom 23. Jul 2016
Antwort Antwort
Benutzerbild von Cylence
Cylence

Registriert seit: 2. Sep 2004
Ort: Allgäu
246 Beiträge
 
Delphi 7 Enterprise
 
#1

AW: Hibernate und Standby erkennen

  Alt 20. Dez 2010, 12:42
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
Tom
Just DO it
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#2

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 09:15
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?
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.196 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 09:32
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.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 09:39
Ab Vista muss man mit SetThreadExecutionState arbeiten

https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
t.roller
(Gast)

n/a Beiträge
 
#5

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 10:30
Ab WIN7: PowerCreateRequest
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.196 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 10:42
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.
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#7

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 10:59
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

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?
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 12:53
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. 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.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 12:59
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.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (22. Jul 2016 um 14:04 Uhr)
  Mit Zitat antworten Zitat
mm1256

Registriert seit: 10. Feb 2014
Ort: Wackersdorf, Bayern
642 Beiträge
 
Delphi 10.1 Berlin Professional
 
#10

AW: Hibernate und Standby erkennen

  Alt 22. Jul 2016, 16:48
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.

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. 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.
Gruss Otto PS: Sorry wenn ich manchmal banale Fragen stelle. Ich bin Hobby-Programmierer und nicht zu faul die SuFu zu benutzen
  Mit Zitat antworten Zitat
Antwort Antwort


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 19:55 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