Keyboard Hook
Description
TKeyboardCallback =
procedure(code: Integer; wparam: WPARAM; lparam: LPARAM) of object;
TKeyboardHook = class(TComponent)
{Source at bottom}
published
{ Published declarations }
property OnCallback: TKeyboardCallBack read FOnCallback write SetOnCallback;
end;
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. The provided source is 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 < 0 then
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.
|