鉤子函數
鉤子函數可以截獲并處理其他應用程序的消息。每當特定的消息發出,在沒有到達目的窗口前,鉤子程序就先捕獲該消息,亦即鉤子函數先得到控制權。這時鉤子函數即可以加工處理(改變)該消息,也可以不作處理而繼續傳遞該消息,還可以強制結束消息的傳遞。
鉤子的種類很多,每種鉤子可以截獲并處理相應的消息,如鍵盤鉤子可以截獲鍵盤消息,外殼鉤子可以截取、啟動和關閉應用程序的消息等
關于HOOK
Hooks
A hook is a point in the system message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure.
安裝一個HOOK,SetWindowsHookEx
對每種類型的鉤子由系統來維護一個鉤子鏈,最近安裝的鉤子放在鏈的開始,而最先安裝的鉤子放在最后,也就是后加入的先獲得控制權。
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.請查看MSDN獲得詳細信息
HOOKPROC lpfn, // hook procedure
HINSTANCE hMod, // handle to application instance
DWORD dwThreadId // thread identifier
);
得到控制權的鉤子函數在完成對消息的處理后,如果想要該消息繼續傳遞,那么它必須調用另外一個SDK中的API函數CallNextHookEx來傳遞它。
(對一個事件處理的hook可能有多個,它們成鏈狀,使用CallNextHookEx一級一級地調用。簡單解釋過來就是“調用下一個HOOK” )
CallNextHookEx
The CallNextHookEx function passes the hook information to the next hook procedure in the current hook chain. A hook procedure can call this function either before or after processing the hook information.
LRESULT CallNextHookEx(
HHOOK hhk, // handle to current hook
int nCode, // hook code passed to hook procedure
WPARAM wParam, // value passed to hook procedure
LPARAM lParam // value passed to hook procedure
);
hook處理函數
LRESULT CALLBACK HookProc(
int nCode,
WPARAM wParam,
LPARAM lParam
);
取消HOOK
UnhookWindowsHookEx
The UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.
BOOL UnhookWindowsHookEx(
HHOOK hhk // handle to hook procedure
);
示例:
[code]
// 監視鼠標消息
// hook處理函數聲明
LRESULT CALLBACK MyMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
static BOOL StartWatchingMouse(); // 開始監視
static void StopWatchingMouse(); // 結束
static HHOOK hHook = NULL; //hook指針
/*======================================================
*Function:StartWatchingMouse()
*Author:wuhuiran 05-7-23
*Desc:開始監視鼠標
*Record:
--------------------------------------------------------
========================================================*/
BOOL StartWatchingMouse()
{
hHook = SetWindowHookEx(WM_MOUSE, (HOOKPROC) MyMouseProc,
(HINSTANCE) NULL, GetCurrentThreadId());
if(!hHook)
{
return FALSE;
}
return TRUE;
}
/*======================================================
*Function:StartWatchingMouse()
*Author:wuhuiran 05-7-23
*Desc:取消監視鼠標
*Record:
--------------------------------------------------------
========================================================*/
void StopWatchingMouse()
{
if(hHook)
{
UnHookWindowHookEx(hHook);
hHook = NULL;
}
}
/*======================================================
*Function:StartWatchingMouse()
*Author:wuhuiran 05-7-23
*Desc:HOOK處理函數
*Record:
--------------------------------------------------------
========================================================*/
LRESULT CALLBACK MyMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
MOUSEHOOKSTRUCT *pMouseHookStruct; //鼠標HOOK結構體
pMouseHookStruct = (MOUSEHOOKSTRUCT *)lParam;
POINT pt = pMouseHookStruct->pt;
//動一下鼠標就會顯示鼠標位置
CString strMsg;
strMsg.Format("x:\t%d\ny:\t%d", pt.x, pt.y);
AfxMessageBox(strMsg);
return CallNextHookEx(myHook, nCode, wParam, lParam);
}
[/code]
注意:
hook會使系統變慢,除非必要,不要頻繁使用。在不使用的時候盡快刪除
全局鉤子必須放在DLL中
只是簡單介紹了一下鉤子函數的使用方法,具體的函數介紹請參閱MSDN和其他文章。