1、
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。即钩子机制允许应用程序截获处理其它进程的window消息或特定事件,比如鼠标消息、键盘消息、对话框或菜单栏或滚动条中输入事件。
SetWindowsHookEx用来安装一个钩子过程。
HHOOK WINAPI SetWindowsHookEx(idHook:钩子过程的类型:
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
);
WH_CALLWNDPROC:安装一个挂钩处理过程,在系统将消息发送至目标窗口处理过程之前,对该消息进行监视,详情参见CallWndProc钩子过程.
WH_MOUSE:安装一个挂钩处理过程,对鼠标消息进行监视. 详情参见MouseProc钩子过程.
WH_KEYBOARD:安装一个挂钩处理过程对击键消息进行监视. 详情参见KeyboardProc钩子过程.
WH_MSGFILTER: 安装一个挂钩处理过程,以监视由对话框、消息框、菜单条、或滚动条中的输入事件引发的消息.详情参见MessagePorc钩子过程.
WH_CALLWNDPROCRET:安装一个挂钩处理过程,它对已被目标窗口处理过程处理过了的消息进行监视,详情参见CallWndRetProc 挂钩处理过程.
WH_CBT:安装一个挂钩处理过程,接受对CBT应用程序有用的消息,详情参见CBTProc 挂钩处理过程.
WH_DEBUG:安装一个挂钩处理过程以便对其他挂钩处理过程进行调试, 详情参见DebugProc挂钩处理过程.
WH_FOREGROUNDIDLE:安装一个挂钩处理过程,该挂钩处理过程当应用程序的前台线程即将进入空闲状态时被调用,它有助于在空闲时间内执行低优先级的任务.
WH_GETMESSAGE:安装一个挂钩处理过程对寄送至消息队列的消息进行监视,详情参见GetMsgProc 挂钩处理过程.
WH_JOURNALPLAYBACK:安装一个挂钩处理过程,对此前由WH_JOURNALRECORD 挂钩处理过程纪录的消息进行寄送.详情参见JournalPlaybackProc挂钩处理过程.
WH_JOURNALRECORD:安装一个挂钩处理过程,对寄送至系统消息队列的输入消息进行纪录.详情参见JournalRecordProc挂钩处理过程.
WH_KEYBOARD_LL:此挂钩只能在Windows NT中被安装,用来对底层的键盘输入事件进行监视.详情参见LowLevelKeyboardProc挂钩处理过程.
WH_MOUSE_LL:此挂钩只能在Windows NT中被安装,用来对底层的鼠标输入事件进行监视.详情参见LowLevelMouseProc挂钩处理过程.
WH_MSGFILTER:安装一个挂钩处理过程,以监视由对话框、消息框、菜单条、或滚动条中的输入事件引发的消息.详情参见MessageProc挂钩处理过程.
WH_SHELL:安装一个挂钩处理过程以接受对外壳应用程序有用的通知, 详情参见ShellProc挂钩处理过程.
WH_SYSMSGFILTER:安装一个挂钩处理过程,以监视由对话框、消息框、菜单条、或滚动条中的输入事件引发的消息.这个挂钩处理过程对系统中所有应用程序的这类消息都进行监视.详情参见SysMsgProc挂钩处理过程.
lpfn:函数指针,指向钩子过程,如MouseProc、CallWndProc等。
hMod:钩子过程所在的DLL的句柄。如果第四个参数dwThreadId指定的线程由当前进程创建,且钩子过程定义在当前进程相关的代码中则hMod必须为NULL。
dwThreadId:与钩子过程相关的线程ID。为0即为安装的钩子过程与桌面上运行的所有线程相关。
函数调用成功返回所安装的钩子过程的句柄,否则返回NULL。
可以安装过个钩子过程,后安装的钩子过程总是在前面。
程序退出的时候最好调用UnhookWindowsHookEx(HOOK hhk),移除安装的钩子过程,函数参数为安装的钩子过程的句柄,即SetWindowsHookEx()的返回值。
钩子过程的声明形式如下:
LRESULT CALLBACK HookProc
(
int nCode,
WPARAM wParam,
LPARAM lParam
);
在钩子过程中对消息处理完成后,可以调用CallNextHookEx()把消息传递给下一个钩子过程。
LRESULT WINAPI CallNextHookEx(HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam);
其第一个参数为当前钩子过程句柄,即SetWindowHookEx()的返回值,其余三个参数与钩子过程参数相同。
如果钩子过程返回非0值,表示已经对当前消息进行了处理,这样,这个消息就不会再传递给目标窗口了。因此,如果钩子过程中对消息进行了处理,就应返回一个非0值,否则建议调用CallNextHookEx()并返回该函数的返回值。
2、
屏蔽所有鼠标消息:
HHOOK g_hMouse = NULL;仅屏蔽ESC键:
LRESULT CALLBACK MouseProc(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
return 1;
}
BOOL CDlgDlg::OnInitDialog()
{
......
g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, NULL, GetCurrentThreadId());
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
HHOOK g_hKeyboard = NULL;屏蔽Alt+F4组合键:
LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
)
{
if(VK_ESC == wParam)
return 1;
else
return CallNextHookEx(g_hKeyboard, code, wParam, lParam);
}
BOOL CDlgDlg::OnInitDialog()
{
......
g_hKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, GetCurrentThreadId());
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
HHOOK g_hKeyboard = NULL;3、
LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
)
{
if(VK_F4==wParam && (1==(lParam>>29&1)))
return 1;
else
return CallNextHookEx(g_hKeyboard, code, wParam, lParam);
}
BOOL CDlgDlg::OnInitDialog()
{
g_hKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, GetCurrentThreadId());
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
如果想要处理其他进程的消息,即安装一个全局钩子,那么安装钩子过程的代码必须放到动态链接库(DLL)中实现,且将SetWindowsHookEx()的第三个参数指定为安装钩子过程的代码所在的DLL的句柄,将第四个参数设为0。