这是我的C ++代码:
#include <iostream>
#include <windows.h>
HHOOK hook;
LRESULT CALLBACK keyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
std::cout << "Hook callback" << std::endl;
return CallNextHookEx(hook, nCode, wParam, lParam);
}
int main(int argc, char **argv)
{
hook = SetWindowsHookEx(WH_KEYBOARD, keyboardHook, NULL, NULL);
if (hook == NULL) {
std::cout << "Error " << GetLastError() << std::endl;
return 1;
}
std::cout << "Hook set" << std::endl;
}
我使用Visual Studio编译它,如下所示:
cl /D_WIN32_WINNT=0x0401 foo.cc /link user32.lib
当我运行它时,我收到错误1428.
C:\>foo.exe
Error 1428
这是错误1428的含义。
C:\nocaps>net helpmsg 1428
Cannot set nonlocal hook without a module handle.
您能否帮我理解这个错误并让这段代码正常工作?如果你能为我提供一个可以工作并调用回调的工作代码会很棒吗?
我看到如果我使用WH_KEYBOARD_LL钩子,它可以正常工作。但我需要了解如何使WH_KEYBOARD钩子起作用。
答案 0 :(得分:1)
WH_KEYBOARD_LL
挂钩总是在安装挂钩的线程的上下文中运行。钩子函数不需要在DLL中,并且钩子可以捕获来自应用程序的事件,而不管它们的位数如何。诀窍是:操作系统对您的线程消息队列执行某种特殊的“SendMessage”。这就是为什么你必须在你的挂钩线程中安装一个活动的消息循环。
WH_KEYBOARD
挂钩可能在安装挂钩的线程的上下文中运行。这意味着它们也可以在钩子线程的上下文中运行。这就强加了一个位于DLL中的钩子函数。我相信(但不确定)钩子函数将“就地”执行(在钩子线程的上下文中),如果比特是相同的,并且比特度不匹配的回退依赖于使用的相同技术为WH_KEYBOARD_LL。这意味着您还必须在挂钩线程中安装一个活动的消息循环(如果不这样做,您将错过来自具有其他位数的应用程序的所有事件)
注意:在钩子线程的上下文中使用钩子函数会导致所有cout << "Hello\n"
无用。你必须使用文件(或IPC)。