由于全局钩子函数必须包含在动态链接库中,所以本例由两个程序体来实现。
1.建立钩子KeyboardHook.dll
(1)选择MFC AppWizard(DLL)创建项目Mousehook;
(2)选择MFC Extension DLL(共享MFC拷贝)类型;
(3)由于VC6没有现成的钩子类,所以要在项目目录中创建KeyboardHook.h文件,在其中建立钩子类:
class AFX_EXT_CLASS CKeyboardHook : public CObject
{
public:
CKeyboardHook();//钩子类的构造函数
virtual ~CKeyboardHook();//钩子类的析构函数
public:
BOOL StartHook(); //安装钩子函数
BOOL StopHook();//卸载钩子函数
};
(4)在KeyboardHook.cpp文件的顶部加入#include "KeyboardHook.h"语句;
(5)在KeyboardHook.cpp文件的顶部加入全局共享数据变量:
#pragma data_seg("mydata")
HHOOK glhHook=NULL; //安装的鼠标勾子句柄
HINSTANCE glhInstance=NULL; //DLL实例句柄
#pragma data_seg()
(6)在DEF文件中定义段属性:
SECTIONS
mydata READ WRITE SHARED
(7)在主文件KeyboardHook.cpp的DllMain函数中加入保存DLL实例句柄的语句:
glhInstance=hInstance;//插入保存DLL实例句柄
(8)键盘钩子函数的实现:
//键盘钩子函数
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if(code==HC_ACTION)
{
DWORD keyCode;
KBDLLHOOKSTRUCT *kb=(KBDLLHOOKSTRUCT *)lParam;
if(kb->flags==LLKHF_UP) //有键被按完
{
keyCode=kb->vkCode;
switch(keyCode)
{
case VK_F12:
break;
case VK_F10:
Sleep(10);
break;
}
}
return CallNextHookEx( glhHook, nCode, wParam, lParam );
}
(9)类CKeyboardHook的成员函数的具体实现:
CKeyboardHook::CKeyboardHook()
{
}
CKeyboardHook::~CKeyboardHook()
{
if(glhHook)
UnhookWindowsHookEx(glhHook);
}
//安装钩子并设定接收显示窗口句柄
BOOL CKeyboardHook::StartHook()
{
BOOL bResult=FALSE;
glhHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0);
/*============================================================
HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId )
参数idHook表示钩子类型,它是和钩子函数类型一一对应的。
比如,WH_KEYBOARD表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等等。
Lpfn是钩子函数的地址。
HMod是钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,
该参数为钩子函数所在的DLL句柄。
dwThreadId 指定钩子所监视的线程的线程号。对于全局钩子,该参数为NULL。
SetWindowsHookEx返回所安装的钩子句柄。
值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。
线程钩子一般在当前线程或者当前线程派生的线程内,
而系统钩子必须放在独立的动态链接库中,实现起来要麻烦一些。
===========================================================*/
if(glhHook!=NULL)
bResult=TRUE;
return bResult;
}
//卸载钩子
BOOL CKeyboardHook::StopHook()
{
BOOL bResult=FALSE;
if(glhHook)
{
bResult= UnhookWindowsHookEx(glhHook);
if(bResult)
glhHook=NULL;
}
return bResult;
}
(10)编译项目生成KeyboardHook.dll。
2.创建钩子可执行程序
(1)用MFC的AppWizard(EXE)创建项目KeyHook;
(2)选择“基于对话应用”并按下“完成”键;
(3)在KeyHookDlg.h中加入包含语句#include "KeyboardHook.h";
(4)在KeyHookDlg.h中添加私有数据成员:
CKeyboardHook m_hook;//加入钩子类作为数据成员
(5)链接DLL库,即把../KeyboardHook.lib加入到项目设置链接标签中;
(6)把OK按钮ID改为ID_HOOK,写实现代码:
void CKeyHookDlg::OnHook()
{
m_hook.StartHook();
}
(7)关闭按钮实现:
void CKeyHookDlg::OnCancel()
{
m_hook.StopHook();
CDialog::OnCancel();
}
下面是附上勾子类型: