Mega Code Archive

 
Categories / Delphi / Hardware
 

Keyboard Hook

Title: Keyboard Hook Question: You want to catch keystrokes. Your main form "keypreview=true" only works when a control has focus. How do you catch keystrokes? Included below is a component you can drop on any form to catch keystrokes. Answer: Catching a keyboard stroke for your application requires a call to the windows api function SetWindowsHookEx. Using this function will allow you to specify a callback procedure for the keystrokes. You have 2 options, you can make a system wide hook or a hook for a particular thread. If you make a system wide hook or specify a thread that exists in a different process then you must use a seperate DLL. In this artical I will only provide source for your applications main thread, therefore is not a system wide hook. Install the below component, drop it on your form, then assign the OnCallback event. You can look into windows help for "KeyboardProc" and it will explain the parameters. Here is an implementation I am using in a production application that responds to the space bar: procedure TForm_LibraryImageSelect.KeyboardHook1Callback(code, wparam, lparam: Integer); begin if (wParam = VK_SPACE) and ((lparam and (1 shl 30)) 0) then SendMoveNextLibImage(dNext); end; Good luck, Here is the source for the component: ---------------------------------------- unit KeyboardHook; { By William Egge Sep 20, 2002 egge@eggcentric.com http://www.eggcentric.com This code may be used/modified however you wish. } interface uses Windows, Classes; type TCallbackThunk = packed record POPEDX: Byte; MOVEAX: Byte; SelfPtr: Pointer; PUSHEAX: Byte; PUSHEDX: Byte; JMP: Byte; JmpOffset: Integer; end; // See windows help on KeyboardProc // Or press F1 while your cursor is on "KeyboardProc" TKeyboardCallback = procedure(code: Integer; wparam: WPARAM; lparam: LPARAM) of object; TKeyboardHook = class(TComponent) private { Private declarations } FHook: HHook; FThunk: TCallbackThunk; FOnCallback: TKeyboardCallBack; function CallBack(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall; procedure SetOnCallback(const Value: TKeyboardCallBack); protected { Protected declarations } public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; published { Published declarations } property OnCallback: TKeyboardCallBack read FOnCallback write SetOnCallback; end; procedure Register; implementation procedure Register; begin RegisterComponents('EggMisc', [TKeyboardHook]); end; { TKeyboardHook } function TKeyboardHook.CallBack(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT; begin if Code Result:= CallNextHookEx(FHook, Code, wparam, lparam) else begin if Assigned(FOnCallback) then FOnCallback(Code, wParam, lParam); Result:= 0; end; end; constructor TKeyboardHook.Create(AOwner: TComponent); begin inherited Create(AOwner); FThunk.POPEDX:= $5A; FThunk.MOVEAX:= $B8; FThunk.SelfPtr:= Self; FThunk.PUSHEAX:= $50; FThunk.PUSHEDX:= $52; FThunk.JMP:= $E9; FThunk.JmpOffset:= Integer(@TKeyboardHook.Callback)-Integer(@FThunk.JMP)-5; FHook:= SetWindowsHookEx(WH_KEYBOARD, TFNHookProc(@FThunk), 0, MainThreadID); end; destructor TKeyboardHook.Destroy; begin UnhookWindowsHookEx(FHook); inherited; end; procedure TKeyboardHook.SetOnCallback(const Value: TKeyboardCallBack); begin FOnCallback := Value; end; end.