Author: Jonas Bilinkevicius How to catch windows keystrokes and pass them to an assigned event Answer: For those interested, here's a keyboard hook component that catches windows keystrokes and passes them to an assigned event. 1 unit KeyboardHook; 2 { 3 By William Egge 4 Sep 20, 2002 5 egge@eggcentric.com 6 http://www.eggcentric.com 7 8 This code may be used/modified however you wish. 9 } 10 11 interface 12 13 uses 14 Windows, Classes; 15 16 type 17 TCallbackThunk = packed record 18 POPEDX: Byte; 19 MOVEAX: Byte; 20 SelfPtr: Pointer; 21 PUSHEAX: Byte; 22 PUSHEDX: Byte; 23 JMP: Byte; 24 JmpOffset: Integer; 25 end; 26 27 {See windows help on KeyboardProc or press F1 while your cursor is on 28 "KeyboardProc"} 29 TKeyboardCallback = procedure(code: Integer; wparam: WPARAM; lparam: LPARAM) of 30 object; 31 32 TKeyboardHook = class(TComponent) 33 private 34 { Private declarations } 35 FHook: HHook; 36 FThunk: TCallbackThunk; 37 FOnCallback: TKeyboardCallBack; 38 function CallBack(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT 39 stdcall; 40 procedure SetOnCallback(const Value: TKeyboardCallBack); 41 protected 42 { Protected declarations } 43 public 44 { Public declarations } 45 constructor Create(AOwner: TComponent); override; 46 destructor Destroy; override; 47 published 48 { Published declarations } 49 property OnCallback: TKeyboardCallBack read FOnCallback write SetOnCallback; 50 end; 51 52 procedure register; 53 54 implementation 55 56 procedure register; 57 begin 58 RegisterComponents('EggMisc', [TKeyboardHook]); 59 end; 60 61 { TKeyboardHook } 62 63 function TKeyboardHook.CallBack(code: Integer; wparam: WPARAM; lparam: LPARAM): 64 LRESULT; 65 begin 66 if Code < 0 then 67 Result := CallNextHookEx(FHook, Code, wparam, lparam) 68 else 69 begin 70 if Assigned(FOnCallback) then 71 FOnCallback(Code, wParam, lParam); 72 Result := 0; 73 end; 74 end; 75 76 constructor TKeyboardHook.Create(AOwner: TComponent); 77 begin 78 inherited Create(AOwner); 79 FThunk.POPEDX := $5A; 80 FThunk.MOVEAX := $B8; 81 FThunk.SelfPtr := Self; 82 FThunk.PUSHEAX := $50; 83 FThunk.PUSHEDX := $52; 84 FThunk.JMP := $E9; 85 FThunk.JmpOffset := Integer(@TKeyboardHook.Callback) - Integer(@FThunk.JMP) - 5; 86 FHook := SetWindowsHookEx(WH_KEYBOARD, TFNHookProc(@FThunk), 0, MainThreadID); 87 end; 88 89 destructor TKeyboardHook.Destroy; 90 begin 91 UnhookWindowsHookEx(FHook); 92 inherited; 93 end; 94 95 procedure TKeyboardHook.SetOnCallback(const Value: TKeyboardCallBack); 96 begin 97 FOnCallback := Value; 98 end; 99 100 end.