回调函数和钩子函数的说明

回调函数:数据结构

回调函数是应用程序提供给Windows系统DLL或其它DLL调用的函数,通常用于截获消息、获取系统信息或处理异步事件。应用程序把回调函数的地址指针告诉DLL,而DLL在适当的时候会调用该函数。回调函数必须遵照事先规定好的参数格式和传递方式,不然DLL一调用它就会引发程序或系统的崩溃。一般状况下,回调函数采用标准WindowsAPI的调用方式,即__stdcall,固然,DLL编制者能够本身定义调用方式,但客户程序也必须遵照相同的规定。在__stdcall方式下,函数的参数按从右到左的顺序压入堆栈,除了明确指明是指针或引用外,参数都按值传递,函数返回以前本身负责把参数从堆栈中弹出。异步

    简单的说就是回调函数函数不是系统定义的,而是应用程序本身定义的一个由系统来调用的函数,因此显然,它的参数必须按照约定来,即,参数是预先定义好的。函数

钩子函数:spa

WINDOWS的钩子函数能够认为是WINDOWS的主要特性之一。利用它们,您能够捕捉您本身进程或其它进程发生的事件。经过“钩挂”,您能够给WINDOWS一个处理或过滤事件的回调函数,该函数也叫作“钩子函数”,当每次发生您感兴趣的事件时,WINDOWS都将调用该函数。一共有两种类型的钩子:局部的和远程的。 线程

 

  局部钩子仅钩挂您本身进程的事件。 设计

  远程的钩子还能够将钩挂其它进程发生的事件。远程的钩子又有两种: 指针

  基于线程的 它将捕获其它进程中某一特定线程的事件。简言之,就是能够用来观察其它进程中的某一特定线程将发生的事件。 日志

  系统范围的 将捕捉系统中全部进程将发生的事件消息。 当您建立一个钩子时,WINDOWS会先在内存中建立一个数据结构,该数据结构包含了钩子的相关信息,而后把该结构体加到已经存在的钩子链表中去。新的钩子将加到老的前面。当一个事件发生时,若是您安装的是一个局部钩子,您进程中的钩子函数将被调用。若是是一个远程钩子,系统就必须把钩子函数插入到其它进程的地址空间,要作到这一点要求钩子函数必须在一个动态连接库中,因此若是您想要使用远程钩子,就必须把该钩子函数放到动态连接库中去。固然有两个例外:工做日志钩子和工做日志回放钩子。这两个钩子的钩子函数必须在安装钩子的线程中。缘由是:这两个钩子是用来监控比较底层的硬件事件的,既然是记录和回放,全部的事件就固然都是有前后次序的。因此若是把回调函数放在DLL中,输入的事件被放在几个线程中记录,因此咱们没法保证获得正确的次序。故解决的办法是:把钩子函数放到单个的线程中,譬如安装钩子的线程。 对象

 

  钩子一共有14种,如下是它们被调用的时机: 队列

 

  WH_CALLWNDPROC 当调用SendMessage时 

 

  WH_CALLWNDPROCRET 当SendMessage的调用返回时 

 

  WH_GETMESSAGE 当调用GetMessage 或 PeekMessage时 

 

  WH_KEYBOARD 当调用GetMessage 或 PeekMessage 来从消息队列中查询WM_KEYUP 或 WM_KEYDOWN 消息时 

 

  WH_MOUSE 当调用GetMessage 或 PeekMessage 来从消息队列中查询鼠标事件消息时 

 

  WH_HARDWARE 当调用GetMessage 或 PeekMessage 来从消息队列种查询非鼠标、键盘消息时 

 

  WH_MSGFILTER 当对话框、菜单或滚动条要处理一个消息时。该钩子是局部的。它时为那些有本身的消息处理过程的控件对象设计的。 

 

  WH_SYSMSGFILTER 和WH_MSGFILTER同样,只不过是系统范围的 

 

  WH_JOURNALRECORD 当WINDOWS从硬件队列中得到消息时 

 

  WH_JOURNALPLAYBACK 当一个事件从系统的硬件输入队列中被请求时 

 

  WH_SHELL 当关于WINDOWS外壳事件发生时,譬如任务条须要重画它的按钮. 

 

  WH_CBT 当基于计算机的训练(CBT)事件发生时 

 

  WH_FOREGROUNDIDLE 由WINDOWS本身使用,通常的应用程序不多使用 

 

  WH_DEBUG 用来给钩子函数除错 

相关文章
相关标签/搜索