hook编程

 一个标准的windows sdk程序的消息处理过程是:操作系统捕获某一窗口的消息,然后将该消息放到对应窗口的消息队列中,应用程序利用GetMessage从消息队列中取出消息,然后DespatchMessage将该消息传回给操作系统,最后操作系统调用该窗口的窗口过程来处理该消息。

所谓钩子(hook)就是当想屏蔽掉某些消息的时候,利用hook函数拦截该消息。
The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.

HHOOK SetWindowsHookEx(
  int idHook,        // hook type
  HOOKPROC lpfn,     // hook procedure
  HINSTANCE hMod,    // handle to application instance
  DWORD dwThreadId   // thread identifier
);

lpfn
[in] Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process.

注意对于钩子函数:If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the target window procedure. 所以可以通过return 1;来屏蔽某个消息。通过返回CallNextHookEx函数调用来将某个消息交给钩子链中的下一个钩子函数处理。

dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.

1、进程内钩子
    g_hhook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, GetCurrentThreadId());

    if (VK_SPACE == wParam)
    {
        return 1;  //成功屏蔽空格消息
    }
    else
    {
        return CallNextHookEx(g_hhook, code, wParam, lParam);  //将其他消息交给钩子链的下一个钩子过程处理
    }
这里注意钩子函数KeyboardProc的lParam参数有4个字节32位,每一个位(bit)都有着特定的意义,例如 29(bit) Specifies the context code. The value is 1 if the ALT key is down; otherwise, it is 0.
    if (VK_F4 == wParam && 1==((lParam>>29) & 1))  //判断键盘是否是按下Alt+F4。

UnhookWindowsHookEx移除钩子过程

2、全局钩子(dwThreadId为0或者dwThreadId是不同进程的线程标识符时,此时hook过程必须在dll中)
//Hook.cpp
#include <windows.h>

HHOOK g_hMouse;

LRESULT CALLBACK MouseProc(
                           int nCode,      // hook code
                           WPARAM wParam,  // message identifier
                           LPARAM lParam   // mouse coordinates
)
{
    return 1;
}

void SetHook()
{
    g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("Hook.dll"),0);
}


//Hook.def
LIBRARY Hook
EXPORTS
SetHook        @2

然后就可以在程序中链接Hook.dll,引入_declspec(dllimport) void SetHook();后,调用SetHook();启动全局钩子。

你可能感兴趣的:(thread,编程,application,library,hook,keyboard)