Živě.cz o počítačích a internetu

Tipy a triky v Delphi, díl 186. – detekce zamčení stanice

Jan Šindelář 25.5.2005

Dnes se podíváme opět hlouběji do systému a s využitím funkcí API se naučíme detekovat zamykání stanice. Tip tedy bude pouze pro novější verze Windows.

Úkol nebude dnes příliš složitý, protože tu hlavní práci za nás zařídí knihovna wtsapi32.dll, na níž se "napíchneme" a použijeme funkci WTSRegisterSessionNotification. Pomocí zpráv systému poté budeme schopni detekovat změnu, která v běžící "session" nastala a určit, k čemu došlo (tedy například zamknutí a odemknutí).

Vytvoříme si tedy nový projekt, přičemž na formuláři bude pouze komponenta Memo, do níž budeme vypisovat změny stavu. Můžete samozřejmě použít libovolnou jinou komponentu pro vizuální výstup, provádět zápis do souboru a podobně. Celá akce bude "spuštěna" ihned po startu aplikace, neboť funkce pro zapnutí hlídání změn stavu systému je umístěna v události OnCreate formuláře. Po spuštění tedy aplikace čeká, co se bude dít, a v případě změny stavu (zamčení či odemčení systému) zaznamená do Mema tuto změnu.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    LCount: Integer;
  public
    { Public declarations }
    procedure WndProc(var Message: TMessage); override;
  end;
  function WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): BOOL; stdcall;
  function WTSUnRegisterSessionNotification(hWND: HWND): BOOL; stdcall;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function WTSRegisterSessionNotification; external `wtsapi32.dll` Name `WTSRegisterSessionNotification`;

function WTSUnRegisterSessionNotification; external `wtsapi32.dll` Name `WTSUnRegisterSessionNotification`;

procedure TForm1.WndProc(var Message: TMessage);
begin
  case Message.Msg of
    WM_WTSSESSION_CHANGE:
      begin
        if Message.wParam = WTS_SESSION_LOCK then
          begin
            Inc(LCount);
            Memo1.Lines.Add(`Stanice zamčena...`);
          end;
        if Message.wParam = WTS_SESSION_UNLOCK then Memo1.Lines.Add(`Stanice odemčena...(` + IntToStr(LCount) + `)`);
      end;
  end;
  inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  WTSRegisterSessionNotification(Handle, 1);
  LCount := 0;
end;

end.

Zbývá upozornit na dvě důležité věci. Všimněte si nejprve proměnné LCount. Ta nám počítá, kolikrát došlo k zamčení a odemčení dané session. Zároveň můžeme ovlivnit, zda budeme hlídat změnu pouze aktuálního přihlášení a nebo všech. To lze zařídit prostřednictvím druhého parametru funkce WTSRegisterSessionNotification. Jednička znamená hlídání všech sessions, nula pak zařídí kontrolu pouze aktuálního přihlášení.

Jako obyčejně si můžete hotový ukázkový příklad stáhnout zde.