啥是windows的钩子?钩子故名思议就是在嵌入到正常执行程序的功能。对于windows来说,每个系统和应用程序之间的交互是使用消息机制来进行。比如点击应用程序上面的某个按钮,就是发送了事件给了应用程序。windows钩子的作用就是在事件发送给应用程序之前截获事件,先对事件做处理,然后有两个选择,可以继续抛出事件,也可以消灭时间。于是每个事件在windows上的相应都是一个事件处理链,没增加一个处理的应用程序就是给这个事件处理链增加一个链接点而已。
创建钩子
创建windows钩子就需要三个步骤:
1 创建钩子
2 相应钩子接收的事件
3 卸载钩子
window提供了钩子的几个接口:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632589(v=vs.85).aspx
其中最需要关注的是几个:
SetWindowsHookEx
UnhookWindowsHookEx
CallNextHookEx
分别是安装钩子,卸载钩子,执行下个钩子操作。执行的顺序如其名:先安装钩子,后处理事件,后调用下个钩子,最后卸载钩子。
一个个看着三个接口:
SetWindowsHookEx
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
);
返回值是个HHOOK,就是钩子的唯一标识,类型在c#中是个int型,如果安装钩子成功,返回一个int,如果安装不成功,返回NULL。
参数:
idHook
idHook是个int类型,标识的是钩子的类型,比如7代表钩子监控鼠标事件,2代表键盘事件。这里不同的事件代表捕获不同的消息,所以后面的消息处理事件也会有不同(这里说的不同不是事件的参数个数和类型不同,而是参数值的含义不同)。好了,这里有个问题,如果我要监控所有事件有办法吗?有,你可以使用4(WH_CALLWNDPROC)来捕获所有消息。
lpfn
lpfn是个注册回调事件,c#中可以使用delegate,这个事件大致是如下的接口:
LRESULT CALLBACK CallWndProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
即有三个参数和一个返回值
nCode:说明下事件如何处理消息,一般如果nCode是小于0的,那么就说明这个注册事件不能做任何处理,应该把事件传递给下个钩子。为0或者其他值根据idHook有不同的含义。
wParam:一般说明这个事件消息的类型。
lParam:一般是指向一个包含具体事件的结构。
hMod
hMod是个int类型,如果钩子的注册事件是由dll包含的话,值非零,如果是由当前进程包含的话,则设置为Intptr.Zero(NULL)
dwThreadId
dwThreadId也是说明这个钩子注册的回调事件的位置,如果是0的话,则注册的回调事件是在当前线程的。如果不是在当前的线程,则dwThreadId是非0
UnhookWindowsHookEx
BOOL WINAPI UnhookWindowsHookEx(
_In_ HHOOK hhk
);
理解了SetWindowsHookEx之后,就很好理解UnhookWindowsHookEx了。
这里的HHOOK是SetWindowsHookEx函数的返回值,钩子的唯一标识。
返回的BOOL代表卸载钩子是否成功。
CallNextHookEx
LRESULT WINAPI CallNextHookEx(
_In_opt_ HHOOK hhk,
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
这个函数是用来让事件随着钩子链继续执行下去的。一般在注册的回调事件中执行的,所以和注册的回调事件有点像。
hhk:HHOOK类型(int)代表钩子ID,但是实际上是被忽略的。
nCode,wParam,lParam具体的含义和注册回调函数是一样的。在使用的时候,只要将注册回调函数接受到的参数直接传递给CallNextHookEx就可以了。
windows钩子有什么作用?
借用msdn(http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959(v=vs.85).aspx)上说的几个用途:
1 调试使用(可以监视传递给应用的消息)
2 作为宏使用。(你可以将你在windows的任何动作录制成宏)
3 监控F1动作来提供帮助。(很多应用上F1动作都是调出帮助信息的)
4 模拟键盘和鼠标操作