【问题标题】:C++ Console app, SetWindowsHookEx, Callback is never calledC++ 控制台应用程序、SetWindowsHookEx、Callback 永远不会被调用
【发布时间】:2011-08-07 18:09:17
【问题描述】:

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

在 main() 中

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 established, so windows正在报告挂钩已建立。

/杰森

【问题讨论】:

    标签: c++ keyboard-events embedded-v8


    【解决方案1】:

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

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

    【讨论】:

    • 这就是我所担心的,我只是希望不是这样。这就提出了另一个问题,您在阅读材料方面有什么建议来实现它。随着应用程序的开发,我意识到我至少需要运行 1 个额外的线程。如果你能在网上找到一篇有帮助的好文章,那也太棒了。
    【解决方案2】:

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

    【讨论】:

    • 我需要所有的键 :) 由于交互式 shell 方面,我可能仍然需要一个线程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 2019-12-14
    • 2017-02-23
    • 1970-01-01
    • 2012-10-27
    • 2013-10-12
    • 2012-03-27
    相关资源
    最近更新 更多