首页 > 代码库 > Hooks——钩子概览
Hooks——钩子概览
(资料源于MSDN,本文仅对其进行翻译、批注。其链接为:http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959%28v=vs.85%29.aspx本文链接:http://blog.csdn.net/wlsgzl/article/details/37648721转载请注明出处并保持文章的完整性。)
Hooks Overview
A hook is a mechanism by which an application can intercept events, such as messages, mouse actions, and keystrokes. A function that intercepts a particular type of event is known as ahook procedure. A hook procedure can act on each event it receives, and then modify or discard the event.
(钩子是一种应用程序拦截事件的机制,例如:消息、鼠标活动、键盘按键。拦截特定类型事件的函数被称为钩子函数。一个钩子函数可以作用于每一个它接受到的事件,并且改变或者抛弃事件。)
The following some example uses for hooks:(下面是钩子的一些用法)
- Monitor messages for debugging purposes(为了调试而监控消息)
- Provide support for recording and playback of macros(为记录和宏重放提供支持)(不知道是什么东西)
- Provide support for a help key (F1)(为功能键F1提供支持)
- Simulate mouse and keyboard input(模拟鼠标和键盘输入)
- Implement a computer-based training (CBT) application(实现CBT应用)
Note Hooks tend to slow down the system because they increase the amount of processing the system must perform for each message. You should install a hook only when necessary, and remove it as soon as possible.(钩子会降低系统的速度,因为系统必须处理的消息增多了。你应当在需要的时候才使用它,不用时请立即取消。)(PS:想想中病毒时电脑会卡就明白了,一个意思。)
This section discusses the following:(本章节讨论下面的内容)
- Hook Chains(钩子链)
- Hook Procedures(钩子函数)
- Hook Types(钩子类型)
- WH_CALLWNDPROC and WH_CALLWNDPROCRET
- WH_CBT
- WH_DEBUG
- WH_FOREGROUNDIDLE
- WH_GETMESSAGE
- WH_JOURNALPLAYBACK
- WH_JOURNALRECORD
- WH_KEYBOARD_LL
- WH_KEYBOARD
- WH_MOUSE_LL
- WH_MOUSE
- WH_MSGFILTER and WH_SYSMSGFILTER
- WH_SHELL
Hook Chains(钩子链)
The system supports many different types of hooks; each type provides access to a different aspect of its message-handling mechanism. For example, an application can use theWH_MOUSE hook to monitor the message traffic for mouse messages.(系统提供多种不同类型的钩子;每种钩子提供了消息处理机制的不同访问方面。例如,程序可以使用WH_MOUSE钩子来监视鼠标消息的传递。)
The system maintains a separate hook chain for each type of hook. A hook chain is a list of pointers to special, application-defined callback functions calledhook procedures. When a message occurs that is associated with a particular type of hook, the system passes the message to each hook procedure referenced in the hook chain, one after the other. The action a hook procedure can take depends on the type of hook involved. The hook procedures for some types of hooks can only monitor messages; others can modify messages or stop their progress through the chain, preventing them from reaching the next hook procedure or the destination window.(系统为不同类型的钩子维护单独的钩子链。)
Hook Procedures(钩子函数)
To take advantage of a particular type of hook, the developer provides a hook procedure and uses theSetWindowsHookEx function to install it into the chain associated with the hook. A hook procedure must have the following syntax:(为了使用某种类型的钩子,开发人员要提供一个钩子函数,然后使用SetWindowsHookEx函数把它安装到该钩子类型的钩子链中。钩子函数必须符合如下的语法:)
LRESULT CALLBACK HookProc( int nCode, //钩子类型 WPARAM wParam, LPARAM lParam ) { // process event ... return CallNextHookEx(NULL, nCode, wParam, lParam);//注意最后调用了CallNextHookEx }
HookProc is a placeholder for an application-defined name.(把函数名放在HookProc的位置。)
The nCode parameter is a hook code that the hook procedure uses to determine the action to perform. The value of the hook code depends on the type of the hook; each type has its own characteristic set of hook codes. The values of the wParam and lParam parameters depend on the hook code, but they typically contain information about a message that was sent or posted.(nCode参数是钩子函数用来决定执行行为的代码。nCode的值取决于钩子的类型;不同的钩子类型有它自己的特有的钩子代码。wParam和lParam参数的值取决于nCode.但是他们通常包含的内容是发送或邮递的消息。)
The SetWindowsHookEx function always installs a hook procedure at the beginning of a hook chain. When an event occurs that is monitored by a particular type of hook, the system calls the procedure at the beginning of the hook chain associated with the hook. Each hook procedure in the chain determines whether to pass the event to the next procedure. A hook procedure passes an event to the next procedure by calling theCallNextHookEx function.(SetWindowsHookEx函数总是在钩子链的开始处安装钩子函数。当某种类型的钩子监测到了事件发生,系统会调用这种钩子链上开始位置的钩子函数。钩子链上的每个钩子函数决定了是否将事件传递给下一个钩子函数。钩子函数通过调用CallNextHookex函数将事件传递到下一个钩子函数。)
Note that the hook procedures for some types of hooks can only monitor messages. the system passes messages to each hook procedure, regardless of whether a particular procedure callsCallNextHookEx.(要注意的是:某些类型钩子的钩子函数只能监测消息。不论钩子函数是否调用CallNextHookEx函数,系统都会将消息传递到下一个钩子函数。)
A global hook monitors messages for all threads in the same desktop as the calling thread. A thread-specific hook monitors messages for only an individual thread. A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate DLL module. A thread-specific hook procedure is called only in the context of the associated thread. If an application installs a hook procedure for one of its own threads, the hook procedure can be in either the same module as the rest of the application‘s code or in a DLL. If the application installs a hook procedure for a thread of a different application, the procedure must be in a DLL. For information, seeDynamic-Link Libraries.(全局钩子作为调用线程监控同一个桌面的所有线程的消息。特定线程的钩子只监控特定现成的消息。全局钩子函数可以在同一桌面的任何程序的环境中作为调用线程来调用,所以函数必须在一个单独的dll模块中。特定线程的钩子函数只能在其线程的环境中调用。如果程序向为它自己的一个线程安装钩子,那么这个钩子可以与程序其他代码的处于同一个模块中,也可以自己单独在一个dll中。如果程序为其他程序的线程安装钩子函数,那么钩子函数必须在dll中。更多信息参见Dynamic-Link Libraries。)
Note You should use global hooks only for debugging purposes; otherwise, you should avoid them. Global hooks hurt system performance and cause conflicts with other applications that implement the same type of global hook.(你应当只在调试时使用全局钩子;不然别用了。全局钩子强烈影响系统性能,并且会和其他使用相同类型钩子的程序发生冲突。)
Hook Types(钩子类型)
Each type of hook enables an application to monitor a different aspect of the system‘s message-handling mechanism. The following sections describe the available hooks.(不同类型的钩子能够使程序监控系统消息处理机制的不同方面。下面的小节描述了可用的钩子类型。)
- WH_CALLWNDPROC and WH_CALLWNDPROCRET
- WH_CBT
- WH_DEBUG
- WH_FOREGROUNDIDLE
- WH_GETMESSAGE
- WH_JOURNALPLAYBACK
- WH_JOURNALRECORD
- WH_KEYBOARD_LL
- WH_KEYBOARD
- WH_MOUSE_LL
- WH_MOUSE
- WH_MSGFILTER and WH_SYSMSGFILTER
- WH_SHELL
下面的不全翻译,只写出部分,或者意译。
WH_CALLWNDPROC and WH_CALLWNDPROCRET
The WH_CALLWNDPROC and WH_CALLWNDPROCRET hooks enable you to monitor messages sent to window procedures. The system calls aWH_CALLWNDPROC hook procedure before passing the message to the receiving window procedure, and calls theWH_CALLWNDPROCRET hook procedure after the window procedure has processed the message.(允许监控发送到窗口过程的消息。WH_CALLWNDPROC:在传送给窗口过程之前调用。WH_CALLWNDPROCRET:在窗口过程处理完后调用。)
The WH_CALLWNDPROCRET hook passes a pointer to a CWPRETSTRUCT structure to the hook procedure. The structure contains the return value from the window procedure that processed the message, as well as the message parameters associated with the message. Subclassing the window does not work for messages set between processes.
For more information, see the CallWndProc and CallWndRetProc callback functions.
WH_CBT
The system calls a WH_CBT hook procedure before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the input focus; or before synchronizing with the system message queue. The value the hook procedure returns determines whether the system allows or prevents one of these operations. TheWH_CBT hook is intended primarily for computer-based training (CBT) applications.(通常只建议计算机辅助训练程序使用这种消息。)(比方说考Excel操作的软件。)
For more information, see the CBTProc callback function.
For information, see WinEvents.
WH_DEBUG
The system calls a WH_DEBUG hook procedure before calling hook procedures associated with any other hook in the system. You can use this hook to determine whether to allow the system to call hook procedures associated with other types of hooks.(在调用系统的其他钩子的钩子函数之前调用。你可以调用这种钩子来决定是否允许系统调用其他类型钩子的钩子函数。)
For more information, see the DebugProc callback function.
WH_FOREGROUNDIDLE
The WH_FOREGROUNDIDLE hook enables you to perform low priority tasks during times when its foreground thread is idle. The system calls aWH_FOREGROUNDIDLE hook procedure when the application‘s foreground thread is about to become idle.(可以在前台线程空闲/将要空闲的时候,将其设为低优先级。)
For more information, see the ForegroundIdleProc callback function.
WH_GETMESSAGE
The WH_GETMESSAGE hook enables an application to monitor messages about to be returned by theGetMessage or PeekMessage function. You can use the WH_GETMESSAGE hook to monitor mouse and keyboard input and other messages posted to the message queue.(允许程序监控GetMessage和 PeekMessage函数返回的消息。可以监控键盘、鼠标的输入,以及其他投递到消息队列的其他消息。)
For more information, see the GetMsgProc callback function.
WH_JOURNALPLAYBACK
The WH_JOURNALPLAYBACK hook enables an application to insert messages into the system message queue. You can use this hook to play back a series of mouse and keyboard events recorded earlier by usingWH_JOURNALRECORD. Regular mouse and keyboard input is disabled as long as a WH_JOURNALPLAYBACK hook is installed. AWH_JOURNALPLAYBACK hook is a global hook—it cannot be used as a thread-specific hook.(再现之前的鼠标或者键盘事件。当安装后,常规键盘鼠标输入将不可使用。这是一个全局钩子。)
The WH_JOURNALPLAYBACK hook returns a time-out value. This value tells the system how many milliseconds to wait before processing the current message from the playback hook. This enables the hook to control the timing of the events it plays back.
For more information, see the JournalPlaybackProc callback function.
WH_JOURNALRECORD
The WH_JOURNALRECORD hook enables you to monitor and record input events. Typically, you use this hook to record a sequence of mouse and keyboard events to play back later by usingWH_JOURNALPLAYBACK. The WH_JOURNALRECORD hook is a global hook—it cannot be used as a thread-specific hook.(记录键盘鼠标输入事件)
For more information, see the JournalRecordProc callback function.
WH_KEYBOARD_LL
The WH_KEYBOARD_LL hook enables you to monitor keyboard input events about to be posted in a thread input queue.(即将投递到线程输入队列的键盘输入事件。)(PS:这个是底层的)
For more information, see the LowLevelKeyboardProc callback function.
WH_KEYBOARD
The WH_KEYBOARD hook enables an application to monitor message traffic forWM_KEYDOWN andWM_KEYUP messages about to be returned by the GetMessage or PeekMessage function. You can use the WH_KEYBOARD hook to monitor keyboard input posted to a message queue.(监控 GetMessage 或 PeekMessage函数即将返回的WM_KEYDOWN和WM_KEYUP消息。可用于监控投递到消息队列的键盘输入。)
)
For more information, see the KeyboardProc callback function.
WH_MOUSE_LL
The WH_MOUSE_LL hook enables you to monitor mouse input events about to be posted in a thread input queue.(即将投递到线程输入队列的鼠标输入事件。)(PS:这个是底层的)
For more information, see the LowLevelMouseProc callback function.
WH_MOUSE
The WH_MOUSE hook enables you to monitor mouse messages about to be returned by theGetMessage or PeekMessage function. You can use the WH_MOUSE hook to monitor mouse input posted to a message queue.(监控 GetMessage 或 PeekMessage函数即将返回的鼠标消息。可用于监控投递到消息队列的鼠标输入。)
)
For more information, see the MouseProc callback function.
(下面的这两个没有翻译,我目前没用到,不看了。)
WH_MSGFILTER and WH_SYSMSGFILTER
The WH_MSGFILTER and WH_SYSMSGFILTER hooks enable you to monitor messages about to be processed by a menu, scroll bar, message box, or dialog box, and to detect when a different window is about to be activated as a result of the user‘s pressing the ALT+TAB or ALT+ESC key combination. The WH_MSGFILTER hook can only monitor messages passed to a menu, scroll bar, message box, or dialog box created by the application that installed the hook procedure. TheWH_SYSMSGFILTER hook monitors such messages for all applications.(WH_MSGFILTER仅监控当前已安装钩子函数的应用程序的菜单、滚动条、消息框、对话框的消息。WH_SYSMSGFILTER则监控所有的程序。)
The WH_MSGFILTER and WH_SYSMSGFILTER hooks enable you to perform message filtering during modal loops that is equivalent to the filtering done in the main message loop. For example, an application often examines a new message in the main loop between the time it retrieves the message from the queue and the time it dispatches the message, performing special processing as appropriate. However, during a modal loop, the system retrieves and dispatches messages without allowing an application the chance to filter the messages in its main message loop. If an application installs aWH_MSGFILTER orWH_SYSMSGFILTER hook procedure, the system calls the procedure during the modal loop.
An application can call the WH_MSGFILTER hook directly by calling theCallMsgFilter function. By using this function, the application can use the same code to filter messages during modal loops as it uses in the main message loop. To do so, encapsulate the filtering operations in aWH_MSGFILTER hook procedure and callCallMsgFilter between the calls to theGetMessage andDispatchMessage functions.
while (GetMessage(&msg, (HWND) NULL, 0, 0)) { if (!CallMsgFilter(&qmsg, 0)) DispatchMessage(&qmsg); }
The last argument of CallMsgFilter is simply passed to the hook procedure; you can enter any value. The hook procedure, by defining a constant such asMSGF_MAINLOOP, can use this value to determine where the procedure was called from.
For more information, see the MessageProc and SysMsgProc callback functions.
WH_SHELL
A shell application can use the WH_SHELL hook to receive important notifications. The system calls aWH_SHELL hook procedure when the shell application is about to be activated and when a top-level window is created or destroyed.
Note that custom shell applications do not receive WH_SHELL messages. Therefore, any application that registers itself as the default shell must call theSystemParametersInfo function before it (or any other application) can receiveWH_SHELL messages. This function must be called withSPI_SETMINIMIZEDMETRICS and aMINIMIZEDMETRICS structure. Set theiArrange member of this structure toARW_HIDE.
For more information, see the ShellProc callback function.