从不调用C++ Console app,SetWindowsHookEx,Callback

J. *_*tin 4 c++ keyboard-events embedded-v8

我有一个带有嵌入式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);
Run Code Online (Sandbox Code Playgroud)

过程:

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);
}
Run Code Online (Sandbox Code Playgroud)

这实际上是对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);
Run Code Online (Sandbox Code Playgroud)

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

任何帮助,也许指向一些教育材料将非常感激.

为了清楚起见,c:LRESULT CALLBACK中的这个函数HookProc(int nCode,WPARAM wParam,LPARAM lParam)永远不会被调用,或者永远不会看到printf,并且开头的输出说:Hook建立,所以windows报告了钩子建立.

/杰森

Han*_*ant 7

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

控制台模式应用程序不像常规Windows GUI应用程序那样抽取消息循环.从你的片段来看,添加一个也不容易.你需要创建一个线程.