关于c ++:设置WH_KEYBOARD挂钩失败,错误1428

Setting WH_KEYBOARD hook fails with error 1428

这是我的C ++代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#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像这样编译它:

1
cl /D_WIN32_WINNT=0x0401 foo.cc /link user32.lib

运行它时,出现错误1428。

1
2
C:\\>foo.exe
Error 1428

这是错误1428的含义。

1
2
3
4
C:\
ocaps>net helpmsg 1428

Cannot set nonlocal hook without a module handle.

您能否帮助我理解此错误并使此代码正常工作? 如果您能为我提供一个可以正常工作并调用回调的代码,那就太好了吗?

我看到如果我改用WH_KEYBOARD_LL钩子,则可以正常工作。 但是我需要了解如何使WH_KEYBOARD挂钩正常工作。


WH_KEYBOARD_LL挂钩始终在安装挂钩的线程的上下文中运行。挂钩函数不必位于DLL中,并且挂钩可以捕获来自应用程序的事件,无论它们的位数如何。诀窍是:OS对线程消息队列执行某种特殊的" SendMessage"。这就是为什么您必须在挂钩线程中安装活动消息循环的原因。

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

注意:在钩子线程的上下文中执行的钩子函数使所有cout <<"Hello\ "无效。您必须使用文件(或IPC)。