有时候我们需要拦截windows消息,可以通过HOO完成。安装一个HOOK过程,称为钩子过程。操作系统在消息时,将我们感兴趣的消息先传递给HOOK过程,在此函数中进行检查或者抓取消息。
下面看一个简单的示例:
//定义钩子过程函数
LRESULT CALLBACK KeyBoardProc(int code ,WPARAM wParam, LPARAM lParam)
{
if(wParam == VK_RETURN)
{
//屏蔽回车消息
return 1;
}
else
{
return CallNextHookEx(g_hkeyboard,code,wParam,lParam);
}
return 1;
}
//安装钩子过程
HHOOK g_hkeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyBoardProc, NULL, GetCurrentThreadId());//钩子只对本进程的当前线程有效
//卸载钩子
UnhookWindowsHookEx(g_hkeyboard);
上面钩子只是在当前进程的当前线程有效,如果想要对所有进程有效,则需要安装全局钩子。即安装钩子过程的代码必须放到动态链接库中去实现。
在SetWindowsHookEx函数的第三个参数指定为安装钩子过程代码所在DLL的句柄,第四个参数设置为0。
先看动态链接库的代码:
//声明导出函数
_declspec(dllexport) void SetHook(HWND hwnd);
HWND g_hwnd;
HHOOK g_hKeyBoard;
LRESULT CALLBACK KeyBoardProc(int code ,WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK KeyBoardProc(int code ,WPARAM wParam, LPARAM lParam)
{
//屏蔽所有按键消息,但如果按下F2,则发送WM_CLOSE消息到窗口,并卸载钩子
if(wParam == VK_F2)
{
SendMessage(g_hwnd, WM_CLOSE, 0, 0);
UnhookWindowsHookEx(g_hKeyBoard);
}
return 1;
}
void SetHook(HWND hwnd)
{
g_hwnd = hwnd;
g_hKeyBoard = SetWindowsHookEx(WH_KEYBOARD, KeyBoardProc, GetModuleHandle("HookDll"),0);//"HookDll"即为要生成的动态链接库名,不要后缀.dll
}
调用代码:
#pragma comment(lib, "HookDll.lib")
//声明导入函数
_declspec(dllimport) void SetHook(HWND hwnd);
SetHook(m_hWnd);//程序中调用,m_hWnd为调用窗口的句柄,目的的HOOK过程检测到F2后发送消息