钩子的本质是一段用以处理系统消息程序,通过系统调用把它挂入系统。钩子种类很 多,每种钩 子可以截获并处理相应的消息当特定发出在到达目窗口之前,每种钩子可以截获并处理相应的消息,每当特定消息发出,在到达目窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。此时钩函数可以对截获的消息进加工处理,甚至可以强制结束消息的传递。这有点类似与 MFC中的 PreTranslateMessage函数数,所不同的是该函数只能用于拦截本进程中消息,而对系统则无为力。
钩子分为全局的钩子和局部的钩子。局部的钩子在程序中写钩子的过程函数就可以了。全局的钩子,则需要在dll中写出过程函数,然后在程序中进行连接使用。
1.用SetWindowsHookEx安装钩子
HHOOK WINAPI SetWindowsHookEx(
__in int idHook, \钩子类型,例如WH_MOUS、 WH_KEYBOARDWH_KEYBOARD
__in HOOKPROC lpfn, \回调函数地址,当钩子钩到任何消息后便调用这个函数;
__in HINSTANCE hMod, \实例句柄,钩子所在模块的句柄
__in DWORD dwThreadId); \线程ID,指定想让钩子去哪个线程,为 0则拦截整个系统消息此为全局钩子。如果指定确定的线程,即为专用钩子
2.定义钩子函数
LRESULT WINAPI MyHookProc(
int nCode , // 指定是否需要处理该消息
WPARAM wParam, // 包含该消息的附加消息
LPARAM lParam // 包含该消息的附加消息
)
钩子监视的特定事件发生后,系统会调用钩子函数进行处理。不同事件的钩子函数的形式是各不相同的。参数wParam和lParam包含所钩消息的信息,比如鼠标位置、状态,键盘按键等。nCode包含有关消息本身的信息,比如是否从消息队列中移出。
得到控制权的钩子函数在处理完消息后,可以调用另外一个API函数 CallNextHookEx来继续传递该消息,也可以通过直接返回 TRUE来丢弃该消息,阻止该消息继续传递。
3.调用CallNextHookEx把钩子信息传递给钩子链的下一个钩子函数。原型如下:
LRESULT CallNextHookEx(
HHOOK hhk, //传递给的钩子句柄
int nCode, //下一个钩子程序使用此代码,以确定如何处理钩的信息
WPARAM wParam, //要传递的参数
LPARAM lParam //要传递的参数
)
当然也可以通过直接返回TRUE来丢弃该消息,就阻止了该消息的传递。
4.用UnhookWindowsHookEx卸载钩子
UnhookWindowsHookEx
(
HHOOK hhk; //要卸载的钩子
);
函数成功返回TRUE,否则返回FALSE。
例子:
实现一个线程级的鼠标钩子。钩子跟踪当前窗口鼠标移动的位置变化信息。并输出到窗口。
(1)在VC中利用MFC APPWizard生成一个不使用文档/视结构的单文档应用mousehook。打开childview.cpp文件,加入全局变量:
HHOOK hHook;//鼠标钩子句柄
CPoint point;//鼠标位置信息
CChildView*pView;//鼠标钩子函数用到的输出窗口指针
在CChildView::OnPaint()添加如下代码:
CPaintDCdc(this);
charstr[256];
sprintf(str,“x=%d,y=%d",point.x,point.y);//构造字符串
dc.TextOut(0,0,str);//显示字符串
(2)childview.cpp文件中定义全局的鼠标钩子函数。
LRESULT CALLBACK MouseProc( intnCode,WPARAMwParam,LPARAMlParam)
{
//是鼠标移动消息
if(wParam==WM_MOUSEMOVE||wParam==WM_NCMOUSEMOVE)
{
point=((MOUSEHOOKSTRUCT*)lParam)->pt;//取鼠标信息
pView->Invalidate();//窗口重画
}
//传递钩子信息
return CallNextHookEx(hHook,nCode,wParam,lParam);
}
(3)CChildView类的构造函数中安装钩子。
CChildView::CChildView(){
pView=this;//获得输出窗口指针
hHook=SetWindowsHookEx(WH_MOUSE,MouseProc,0,GetCurrentThreadId());
}
(4)CChildView类的析构函数中卸载钩子。
CChildView::~CChildView()
{
if(hHook)
UnhookWindowsHookEx(hHook);
}
版权声明: