Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

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

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