Delphi - Egér kattintások számlálása

forráskód letöltése
Múlt heti újságunkban készítettünk egy olyan programot, mely képes volt arra, hogy megszámlálja, hogy egy nap alatt hány billentyűt ütünk le - függetlenül a futó alkalmazástól - a billentyűzeten.
Mostani példánkban egy olyan alkalmazást készítünk, mely ennek mintájára az egér kattintásokat számlálja.
Múltkori példához hasonlóan most is a Windows hook szolgáltatását használjuk ki, annyi különbséggel, hogy most az egér műveleteket figyeltetjük. Ehhez szükségünk lesz egy DLL készítésére, melyben két függvényt exportálunk, a SetHook és a UnHook függvényeket.
function SetHook: boolean; export;
function UnHook: boolean; export;
Az egér kattintások számát a Windows regisztrációs adatbázisában tároljuk az alábbi kulcson.
const
  key='Software\Animare Software\KeyMouse\';
SetHook függvény meghívásával kérjük a Windows-tól az egér műveletek figyelését, melyhez most is a SetWindowsHookEx függvényt használjuk, annyi változással, hogy most első paraméterként WH_MOUSE konstanst adjuk meg.
function SetHook: Boolean;
begin
  if not FOk then begin
    FH:=SetWindowsHookEx(WH_MOUSE, HookProc, integer(HInstance), 0);
    FOk:=true;
    FI:=0;
  end;
  result:=FH<>0;
end;
Amikor már nem lesz szükségünk erre a műveletre, akkor hívjuk meg az UnHook függvényt.
function UnHook:Boolean;
begin
  result:=UnHookWindowsHookEx(FH);
  FOk:=false;
end;
Amikor a HookProc függvény meghívásra kerül a Windows által, akkor biztosak lehetünk abban, hogy valamely alkalmazásban egér művelet történt. Mivel több olyan egér művelet is történhet, melyekre nincs szükségünk, így vizsgálnunk kell a számláló növelése előtt, hogy mi is történt.
function HookProc(Code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if Code=HC_ACTION then begin
    case wParam of
Ha az egér valamely gombját lenyomjuk, illetve ha valamelyikkel duplán kattintunk, akkor kell a számlálónk értékét eggyel növelni. Dupla kattintás esetén is elegendő a számláló értékének eggyel való növelése, annak ellenére, hogy ilyenkor két kattintás történik, mivel az első kattintásnál egy WM_xBUTTONDOWN üzenetet kapunk.
      WM_MBUTTONDBLCLK, WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, WM_MBUTTONDOWN, WM_LBUTTONDOWN, WM_RBUTTONDOWN: begin
        s:=FormatDateTime('yyyymmdd', Now);
        reg:=TRegistry.Create;
        reg.OpenKey(key+s, true);
        try
          i:=reg.ReadInteger('Mouse');
        except
          i:=0;
        end;
        reg.WriteInteger('Mouse', i+1);
        reg.Free;
      end;
    end;
  end;
  result:=CallNextHookEx(FH, Code, wParam, lParam);
end;
A DLL-t felhasználó alkalmazásban a múlt heti példához képest szinte semmi változás nem történt. A program indulásakor meghívjuk a DLL SetHook függvényt, ezzel elindítva a számlálási folyamatot, míg programunk leállásakor az UnHook függvénnyel leállítjuk azt.
procedure TForm1.FormCreate(Sender: TObject);
begin
  SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
  SetHook;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UnHook;
end;