• windows钩子(转)


    1. 消息钩子

    提示: 如果要设置系统级钩子, 钩子函数必须在 DLL 中.


    SetWindowsHookEx(
      idHook: Integer;   {钩子类型}
      lpfn: TFNHookProc; {函数指针}
      hmod: HINST;       {包含钩子函数的模块(EXE、DLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0}
      dwThreadId: DWORD  {关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子}
    ): HHOOK;            {返回钩子的句柄; 0 表示失败}
    
    //钩子类型 idHook 选项:
    WH_MSGFILTER       = -1; {线程级; 截获用户与控件交互的消息}
    WH_JOURNALRECORD   = 0{系统级; 记录所有消息队列从消息队列送出的输入消息, 在消息从队列中清除时发生; 可用于宏记录}
    WH_JOURNALPLAYBACK = 1{系统级; 回放由 WH_JOURNALRECORD 记录的消息, 也就是将这些消息重新送入消息队列}
    WH_KEYBOARD        = 2{系统级或线程级; 截获键盘消息}
    WH_GETMESSAGE      = 3{系统级或线程级; 截获从消息队列送出的消息}
    WH_CALLWNDPROC     = 4{系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}
    WH_CBT             = 5{系统级或线程级; 截获系统基本消息, 譬如: 窗口的创建、激活、关闭、最大最小化、移动等等}
    WH_SYSMSGFILTER    = 6{系统级; 截获系统范围内用户与控件交互的消息}
    WH_MOUSE           = 7{系统级或线程级; 截获鼠标消息}
    WH_HARDWARE        = 8{系统级或线程级; 截获非标准硬件(非鼠标、键盘)的消息}
    WH_DEBUG           = 9{系统级或线程级; 在其他钩子调用前调用, 用于调试钩子}
    WH_SHELL           = 10; {系统级或线程级; 截获发向外壳应用程序的消息}
    WH_FOREGROUNDIDLE  = 11; {系统级或线程级; 在程序前台线程空闲时调用}
    WH_CALLWNDPROCRET  = 12; {系统级或线程级; 截获目标窗口处理完毕的消息, 在 SendMessage 调用后发生}
    

     2.事件钩子

      消息钩子能够在应用程序处理系统消息之前将其截获,提前处理并可以决定是否继续将消息往下传送,有些windows事件并没有消息对应,譬如弹出菜单,切换窗口,获得焦点,滚动条滚动等等,要截获这些事件可以使用SetWinEventHook,它的原型如下:

    HWINEVENTHOOK WINAPI SetWinEventHook(
      __in  UINT eventMin,
      __in  UINT eventMax,
      __in  HMODULE hmodWinEventProc,
      __in  WINEVENTPROC lpfnWinEventProc,
      __in  DWORD idProcess,
      __in  DWORD idThread,
      __in  UINT dwflags
    );

        详细说明见MSDN:http://msdn.microsoft.com/en-us/library/dd373640(VS.85).aspx,其中第四个参数类似消息钩子一样是一个回调函数,说明见:http://msdn.microsoft.com/en-us/library/dd373885(VS.85).aspx

        SetWinEventHook的第1,2个参数可以标识一个范围,表示截获哪个范围类的事件,因为实际上在win32里面这些事件的ID都是直接用defined直接从小到大定义的,有两个宏分别表示最小的事件ID和最大的事件ID(EVENT_MIN和EVENT_MAX),如果你分别传这两个参数给eventMin和eventMax则可以截获所有的事件,具体可以截获的事件可以去MSDN查询:http://msdn.microsoft.com/en-us/library/dd318066(VS.85).aspx

        要停止HOOK,请调用UnhookWinEvent,原型为:

    BOOL WINAPI UnhookWinEvent(
      __in  HWINEVENTHOOK hWinEventHook
    );

    3.两者区别

      (1)SetWindowsHookEx有两种钩子函数,一种是全局钩子(global hook),另一种是线程钩子(thread hook)。全局钩子能够截取所有线程的消息,但是全局钩子函数必须存在于一个dll中。线程钩子只能截取属于当前进程中的线程的消息,钩子函数不需要放 在dll中。SetWinEventHook也有两种钩子函数,一种是进程内钩子(in-context hook),另一种是进程外钩子(out-of-context hook)。进程内钩子函数必须放在dll中,将被映射到所有进程中。进程外钩子函数不会被映射到别的进程中,所以也不需要被放到dll中。不管进程内或 进程外钩子都能截取到所有进程的消息,区别仅是进程内钩子效率更高。

      (2)SetWindowsHookEx 和SetWinEventHook两种方法截取的消息的类型不一样。SetWindowsHookEx能截取所有WM_开头的消息。而 SetWinEventHook截取的消息都是EVENT_开头的,这些消息所有都是跟对象的状态相关的,所以它无法获取根鼠标键盘相关的消息。

      (3)SetWindowsHookEx设定的全局钩子必须被注入到别的进程中,所以就无法截取到一些有限制的进程的消息,比如命令行窗口(console window)。而SetWinEventHook的进程外钩子就没有这个限制。

  • 相关阅读:
    2018年秋季个人阅读计划
    java当中JDBC当中JNDI用来查找dataSource的例子
    为什么要引入激活函数?
    为什么引入神经网络来做识别,判断,预测?
    给出一个生活中的最简单的两层神经网的实际例子
    MapReduce的输入文件是两个
    hadoop在eclipse当中如何添加源码?
    MapReduce的shuffle过程详解
    hadoop WordCount例子详解。
    Hadoop的eclipse的插件是怎么安装的?
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/3344501.html
Copyright © 2020-2023  润新知