不知道你有没有在写Windows桌面软件时遇到钩子(Hook)这个词,反正每次只要我重拾C#,开始写些桌面软件,都会遇到它。而且每次遇到它,我都是先百度一下,大概了解到它就是事件处理程序一样的东西就好了。所以现在,我脑中就是 钩子=handler。
但是这次遇到这个词之后,我又百度了它。我意识到我不能再这么折磨自己了,应该对这个概念有个更系统的理解。
于是,我又打开了百度,与以往不同的是,我这次打算记录一下各种说法(微软文档、百度词条),并结合我的理解对它进行整理。
钩子是windows提供的一种消息处理机制平台,是在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不做处理而继续传递该消息,还可以强制结束消息的传递(return)。
度娘的这段话,细细读一下,其实已经把钩子的特点都描述的差不多了。


钩子是一种机制——应用程序能通过钩子截获事件,例如消息、鼠标动作或者按下键盘。拦截特定类型事件的函数被称为钩子函数(程序)。钩子函数可以处理它收到的每个事件,然后修改或者丢弃。
官方文档的描述与度娘意思差不多。而这里用到了一个词截获(Intercept)则更形象地描述了钩子。
同时文档还给出了一些钩子使用的例子:
需要注意的是,钩子往往会使系统变慢,因为它增加了系统为每个消息执行的处理量。所以非必要时就不要使用钩子了。
这边择几个以上应用场景简单分析一下(只是个人的猜测):
说了那么多,那使用起来难不难。
有点难,因为原始的钩子是比较底层的东西,它是user32.dll库中的内容。
通常用法如下,
// 从库中导出
[DllImport("user32.dll")]
// 安装 调用 卸载
...
当然现在NuGet上有各种封装过的钩子库,使用起来会简单许多。
比如键鼠类的操作,搜索KeyMouseHook,可以出现一大堆库,用起来基本上只有几条语句。
所以钩子就是可以截获到达用户程序之前的消息的处理函数。