设置WH_KEYBOARD挂钩失败,错误1428

时间:2014-01-03 04:45:03

标签: c++ visual-studio

这是我的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钩子起作用。

1 个答案:

答案 0 :(得分:1)

WH_KEYBOARD_LL挂钩总是在安装挂钩的线程的上下文中运行。钩子函数不需要在DLL中,并且钩子可以捕获来自应用程序的事件,而不管它们的位数如何。诀窍是:操作系统对您的线程消息队列执行某种特殊的“SendMessage”。这就是为什么你必须在你的挂钩线程中安装一个活动的消息循环。

WH_KEYBOARD挂钩可能在安装挂钩的线程的上下文中运行。这意味着它们也可以在钩子线程的上下文中运行。这就强加了一个位于DLL中的钩子函数。我相信(但不确定)钩子函数将“就地”执行(在钩子线程的上下文中),如果比特是相同的,并且比特度不匹配的回退依赖于使用的相同技术为WH_KEYBOARD_LL。这意味着您还必须在挂钩线程中安装一个活动的消息循环(如果不这样做,您将错过来自具有其他位数的应用程序的所有事件)

注意:在钩子线程的上下文中使用钩子函数会导致所有cout << "Hello\n"无用。你必须使用文件(或IPC)。