• 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的进程外钩子就没有这个限制。

  • 相关阅读:
    Codeforces 451A Game With Sticks
    POJ 3624 Charm Bracelet
    POJ 2127 Greatest Common Increasing Subsequence
    POJ 1458 Common Subsequence
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1698
    HDU 1754
    POJ 1724
    POJ 1201
    CSUOJ 1256
  • 原文地址:https://www.cnblogs.com/dsky/p/3083502.html
Copyright © 2020-2023  润新知