有时候我们需要拦截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后发送消息