题记:Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的。而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。
最近的项目中有一个屏蔽键盘的需求,于是借鉴网上的教程写了个简单的钩子应用:
unit unt_KHook;
interface
uses Windows,SysUtils;
var
KHook:HHOOK = 0;
function setkhook(B:Integer):Boolean;stdcall;
function unsetkhook:Boolean;stdcall;
implementation
//回调函数
function MyKeyBoard(code: integer; w: Cardinal; l: Cardinal): Cardinal; stdcall;
label CallNext;
begin
if code<0 then
goto CallNext;
if code = HC_Action then //如果有按键
begin
Result := 1; //返回1并退出即屏蔽了键盘事件
Exit;
{ //这里可以按照自己的需求编写相应代码,如记录键盘键值到txt、弹出提示框等
if (w = VK_F11) then //F11
...
}
end;
CallNext:
Result:=CallNextHookEx(KHook,code,w,l);
end;
//装钩子
function setkhook(B:Integer):Boolean;
begin
//如果没有传句柄(参数传0)进来则获取当前进程ID
if B = 0 then B := GetCurrentThreadID;
KHook:=SetWindowsHookEx(WH_KEYBOARD,@MyKeyBoard,HInstance,B);
Result:=KHook<>0;
end;
//卸载钩子
function unsetkhook:Boolean;
begin
Result:=UnhookWindowsHookEx(KHook);
end;
end.
如果需要编译成动态库,则参照下面代码:
library kbhook;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
unt_KHook in 'unt_KHook.pas';
{$R *.res}
exports setkhook,unsetkhook;
begin
end.
调用方法:
procedure TForm1.Button1Click(Sender: TObject);
var
h:Cardinal;
p:Cardinal;
begin
//找到要注入的窗体
h:=FindWindow('TForm1',nil);
if h=0 then
Exit;
//得到线程ID
p:=GetWindowThreadProcessId(h,nil);
if SetKHook(p) then
ShowMessage('已加载键盘钩子');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
UnSetKHook;//卸载键盘钩子
end;
上面是我项目中对钩子的简单应用,抛砖引玉,希望初次接触钩子的人通过文章能够对其有个初步的了解。