使用钩子
下列代码示例说明了如何执行下列与钩子相关的任务。
。Installing and Releasing Hook Procedures
。Monitoring System Events
设置与释放钩子程序
你可以通过SetWindowsHookEx函数设置钩子程序并指定要调用的钩子程序的钩子类型,
这样这个钩子程序将与所有和调用线程在同一桌面的线程或指定的线程相关联。和一个指向
函数入口的指针。
你必须把全局的钩子程序放在与设置钩子程序的应用程序相独立的动态连接库中,设置
钩子的应用程序在能够设置钩子程序之前必须有一个指向DLL模块的句柄,用DLL的名字调用
LoadLibrary函数。在你获得这个句柄之后,你可以调用GetProcAddress函数去重新获得指
向钩子程序的指针。最后,使用SetWindowsHookEx函数把钩子程序的地址设置到相应的钩子
链中。SetWindowsHookEx函数接受函数句柄,一个指向钩子程序入口点的指针和一个为0的
线程标识符作为参数。指明这个钩子程序将与和调用线程在同一个桌面上的所有线程相关联
。这顺序显示在下列示例中。
HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
hinstDLL = LoadLibrary((LPCTSTR) "c://windows//sysmsg.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");
hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0);
你可以通过调用UnhookwindowsHookEx函数释放一个线程特殊钩子程序,一旦释放钩子
程序你的应用程序就不再需要它了。
你可以通过调用UnhookwindowsHoosEx函数释放一个全局钩子程序,但这函数并不释放
包含钩子程序的DLL。因为全局钩子程序在每一个桌面应用程序的进程上下文中被调用,也
就是说这些进程都调用过LoadLibrary这个函数。如果调用了FreeLibrary函数这个DLL就不
能再继续为这些进程工作了。操作系统最终会在所有明确链接该DLL的进程要么终止要么调
用FreeLibrary函数并且所有的进程都恢复处理了DLL之后释放这个DLL。
一个可以替代设置全局钩子程序的方案是在DLL中与钩子程序一起提供设置函数。用这
个方案,设置钩子程序的应用程序不需要处理DLL模块,通过链接DLL,应用程序可以使用设
置函数。这个安装函数能提供DLL模块句柄和另外一些调用SetWindowsHookEx函数的详细信
息。DLL还可以包含释放全局钩子程序的函数。在结束的时候应用程序能调用这个释放函数
。
监听系统事件
下面的例子使用不同的线程特殊程序去监视系统用事件影响的线程。它说明了怎样为下
列的钩子程序类型处理事件。
。WH_CALLWNDPROC
。WH_CBT
。WH_DEBUG
。WH_GETMESSAGE
。WH_KEYBOARD
。WH_MOUSE
。WH_MSGFILTER
用户能通过菜单安装或删除钩子程序,单一个钩子程序被设置并且被它所监听的事件发
生,这个钩子程序就把事件的有关信息写到应用程序主窗口的客户区域中。
原文
Using Hooks
The following code examples demonstrate how to perform the following tasks associated with hooks.
Installing and Releasing Hook Procedures
You can install a hook procedure by calling the SetWindowsHookEx function and specifying the type of hook calling the procedure, whether the procedure should be associated with all threads in the same desktop as the calling thread or with a particular thread, and a pointer to the procedure entry point.
You must place a global hook procedure in a DLL separate from the application installing the hook procedure. The installing application must have the handle to the DLL module before it can install the hook procedure. To retrieve a handle to the DLL module, call the LoadLibrary function with the name of the DLL. After you have obtained the handle, you can call the GetProcAddress function to retrieve a pointer to the hook procedure. Finally, use SetWindowsHookEx to install the hook procedure address in the appropriate hook chain. SetWindowsHookEx passes the module handle, a pointer to the hook-procedure entry point, and 0 for the thread identifier, indicating that the hook procedure should be associated with all threads in the same desktop as the calling thread. This sequence is shown in the following example.
HOOKPROC hkprcSysMsg; static HINSTANCE hinstDLL; static HHOOK hhookSysMsg; hinstDLL = LoadLibrary((LPCTSTR) "c://windows//sysmsg.dll"); hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0);
You can release a thread-specific hook procedure (remove its address from the hook chain) by calling the UnhookWindowsHookEx function, specifying the handle to the hook procedure to release. Release a hook procedure as soon as your application no longer needs it.
You can release a global hook procedure by using UnhookWindowsHookEx, but this function does not free the DLL containing the hook procedure. This is because global hook procedures are called in the process context of every application in the desktop, causing an implicit call to the LoadLibrary function for all of those processes. Because a call to the FreeLibrary function cannot be made for another process, there is then no way to free the DLL. The system eventually frees the DLL after all processes explicitly linked to the DLL have either terminated or called FreeLibrary and all processes that called the hook procedure have resumed processing outside the DLL.
An alternative method for installing a global hook procedure is to provide an installation function in the DLL, along with the hook procedure. With this method, the installing application does not need the handle to the DLL module. By linking with the DLL, the application gains access to the installation function. The installation function can supply the DLL module handle and other details in the call to SetWindowsHookEx. The DLL can also contain a function that releases the global hook procedure; the application can call this hook-releasing function when terminating.
Monitoring System Events
The following example uses a variety of thread-specific hook procedures to monitor the system for events affecting a thread. It demonstrates how to process events for the following types of hook procedures:
- WH_CALLWNDPROC
- WH_CBT
- WH_DEBUG
- WH_GETMESSAGE
- WH_KEYBOARD
- WH_MOUSE
- WH_MSGFILTER
The user can install and remove a hook procedure by using the menu. When a hook procedure is installed and an event that is monitored by the procedure occurs, the procedure writes information about the event to the client area of the application's main window.