5

我有一个带有嵌入式 v8 引擎的小控制台应用程序,我想添加一个挂钩来注册关键事件。这一切在我使用 Qt 和 QtScript 之前都有效,但我将其全部移植到 VC++ 2008 中的直接 C++ 中。应用程序编译并运行,但从未调用过钩子,这是相关代码:

在主()

HWND hwndC = GetConsoleWindow() ;
    HINSTANCE hInst = (HINSTANCE)GetWindowLong( hwndC, GWL_HINSTANCE );
    if (SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, hInst, NULL) == 0) {
        printf("Failed to set hook\n");
    } else {
        printf("Hook established\n");
    }
    g->RunScript(argc,argv);

和过程:

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    printf("HookProc called\n");
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) (lParam);
    if (wParam == WM_KEYDOWN) {
       keyDown(p,g);
    } else if (wParam == WM_KEYUP) {
        keyUp(p,g);
    }
    fflush(stdout);
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

这本质上是对 v8 示例代码的 shell.cc 的扩展。我想知道它是否以某种方式阻塞?我承认我并不真正知道我在这里做什么,只是玩耍和学习,但这让我难过。

在 keyDown 里面说,我有这样的事情:

    v8::Handle<v8::String> callback_name = v8::String::New("onKeyDown");
    v8::Handle<v8::Value> callback_val = g->_context->Global()->Get(callback_name);
    if (!callback_val->IsFunction()) {
        printf("No onKeyDown handler found\n");
        return;
    }
    v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(callback_val);
    const int argc = 1;
    v8::Handle<v8::Value> argv[argc] = { v8::Int32::New(char(p->vkCode)) };
    printf("Calling onKeyDown\n");
    v8::Handle<v8::Value> result = callback->Call(g->_context->Global(), argc, argv);

其中一些实际上可能最终不起作用,但是当我运行程序并定义时,它永远不会被调用: onKeyDown = function(key) {...}; 我可以看到 onKeyDown 工作得很好,我可以使用 JS 中的所有绑定 c++ 方法等,所以这件事让我很生气。

任何帮助,也许对一些教育材料的指点将不胜感激。

为了清楚起见,c 中的这个函数:LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) 永远不会被调用,或者永远不会看到 printf,并且开始时的输出显示:Hook 已建立,因此 windows 正在报告钩子成立。

/杰森

4

2 回答 2

8

像 WH_KEYBOARD_LL 这样的低级钩子要求您的应用程序泵送一个消息循环。这是 Windows 可以闯入您的线程并调用您注册的 HookProc 回调的唯一方法。

控制台模式应用程序不会像常规 Windows GUI 应用程序那样发送消息循环。从您的代码段来看,添加一个也不容易。您需要创建一个线程。

于 2011-08-07T18:23:40.163 回答
1

也许这个功能会对你有所帮助? GetAsyncKeyState

于 2011-08-07T19:16:26.033 回答