Jak v Delphi vypnout uspávání počítače během kritické operace

25. 6. 2019, Vladimír Klaus, přečteno 154x

Delphi
Windows

Pokud programujete nějakou časově náročnou operaci, je nanejvýš vhodné zajistit, aby se vám během zpracování počítač neuspal, případně ani nevypnul monitor.

Přestože je uvedený zdroj, ze kterého jsem čerpal, 10 let starý, stále perfektně funguje v době psaní článku i na Windows 10.

Jak v Delphi vypnout uspávání počítače během kritické operace

unit SystemCriticalUnit;

interface

uses
  Windows;

type
  TSystemCritical = class
  private
    FIsCritical: Boolean;
    procedure SetIsCritical(const Value: Boolean) ;
  protected
    procedure UpdateCritical(Value: Boolean) ; virtual;
  public
    constructor Create;
    property IsCritical: Boolean read FIsCritical write SetIsCritical;
  end;

var
  SystemCritical: TSystemCritical;

implementation

type
  EXECUTION_STATE = DWORD;

const
  ES_SYSTEM_REQUIRED = $00000001;
  ES_DISPLAY_REQUIRED = $00000002;
  ES_USER_PRESENT = $00000004;
  ES_AWAYMODE_REQUIRED = $00000040;
  ES_CONTINUOUS = $80000000;

{
  Pomocí funkce SetThreadExecutionState umožníte, aby vaše aplikace
  informovala Windows systém, že potřebuje pracovat a není žádoucí,
  aby došlo k uspání nebo třeba vypnutí monitoru apod.
}
procedure SetThreadExecutionState(ESFlags: EXECUTION_STATE);
  stdcall; external kernel32 name 'SetThreadExecutionState';

constructor TSystemCritical.Create;
begin
  inherited;
  FIsCritical := False;
end;

procedure TSystemCritical.SetIsCritical(const Value: Boolean);
begin
  if FIsCritical=Value then Exit;

  FIsCritical:=Value;
  UpdateCritical(FIsCritical);
end;

procedure TSystemCritical.UpdateCritical(Value: Boolean);
begin
  if Value
    //Zajistím, aby nedošlo k uspání
    then SetThreadExecutionState(ES_SYSTEM_REQUIRED or ES_CONTINUOUS)
    //tímto zapnu zase výchozí chování...
    else SetThreadExecutionState(ES_CONTINUOUS);
end;


initialization
  SystemCritical:=TSystemCritical.Create;

finalization
  SystemCritical.IsCritical:=False;
  SystemCritical.Free;

end.

Pokud do projektu přidáte tuto unitu, získáte systém, kterým třeba na začátku kritické části vypnete usínání a na konci zase zapnete výchozí chování.

//vypnu možnost usínání počítače
SystemCritical.IsCritical:=true;
try
  //...provádím náročnou akci a nechci, aby se počítač uspal...

finally
  //zapnu možnost usínání počítače
  SystemCritical.IsCritical:=false;
end;

Zdroje: