Dlaczego globalny hook na klawiaturę nie działa?

0

Witam. Czytając dzisiaj kompedium programisty natrafiłem na rozdział pt. "Obsługa Komunikatów". Był tam również gotowy kod, który by przechwytywał wciśnięte klawisze na klawiaturze. Niestety ten kod:

unit MainFrm;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;
 
type
  TMainForm = class(TForm)
    Memo: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  end;
 
var
  MainForm: TMainForm;
 
implementation
 
{$R *.dfm}
 
var
  MainHook : HHOOK; // wskazanie na hooka
  lpWnd : PChar; // nazwa okna, w którym użytkownik naciska klawisz
 
function KeyboardHook(Code: Integer; wParam : WPARAM;
  lParam : LPARAM): Longint; stdcall;
var
  Buffer : TEventMsg; // deklaracja struktury 
  Wnd : array[0..255] of char;
 
  procedure TranslateKey(Key : Byte);
  begin
    with MainForm do
    begin
      case Key of
        13: Memo.Lines.Add('');
        8: Memo.Text := Memo.Text + '[backspace]';
        27: Memo.Text := Memo.Text + '[esc]';
        else Memo.Text := Memo.Text + Chr(Key);
      end;
    end;
  end;
 
begin
  Result := 0; // wartość zwracana przez procedurę
  Buffer := PEventMsg(lParam)^; // uzyskanie danych poprzez odczytanie wskaźnika
 
  if Buffer.Message = WM_KEYDOWN then { dotyczy tylko komunikatu WM_KEYDOWN }
  begin
    GetWindowText(Buffer.hwnd, Wnd, SizeOf(Wnd));  // pobierz tekst aktywnego okna
 
  { jeżeli użytkownik zapisuje dane w innym oknie }
    if Wnd <> lpWnd then
    begin
      lpWnd := Wnd;
      MainForm.Memo.Clear; // wyczyść zawartość komponentu
    end;
 
    TranslateKey(Buffer.paramL);
  end;
end;
 
procedure TMainForm.FormCreate(Sender: TObject);
begin
{ załóż hooka }
  MainHook := SetWindowsHookEx(WH_JOURNALRECORD, KeyboardHook, hInstance, 0);
  if (MainHook = NULL) then
   raise Exception.Create('Błąd! Hook nie został założony!');
end;
 
procedure TMainForm.FormDestroy(Sender: TObject);
begin
  UnhookWindowsHookEx(MainHook);
end;
 
end.

nie działa. Ktoś wie czemu?

1

Wszyscy wiedzą że czasy starych systemów wymarły. W nowych UAC nie pozwoli na to:
https://blogs.msdn.microsoft.com/winsdk/2009/07/16/setwindowhookex-api-with-wh_journalrecord-this-api-fails-with-access-denied-error-5/
Nie wiem co chcesz zrobić ale być może wystarczy Ci WH_KEYBOARD_LL (ten działa bez specjalnych uprawnień w nowych systemach) zamiast WH_JOURNALRECORD.

0

alternatywnie możesz korzystać z (GetKeyState):
https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms646301(v=vs.85).aspx
https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms646293(v=vs.85).aspx
i chyba nie trzeba uruchamiać programu jako admin. Wklejam te linki, bo może robisz program dla siebie i nie masz specjalnych wymagań.

1 użytkowników online, w tym zalogowanych: 0, gości: 1