Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Console app, SetWindowsHookEx, Callback is never called

I have a little console application that has an embedded v8 engine, and I would like to add a hook to register key events. This all worked before when I was using Qt and QtScript, but I am porting it all over to straight C++ in VC++ 2008. The application compiles and runs, but the hook is never called, here is the relevant code:

In 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);

And the proc:

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);
}

This is essentially an expansion on shell.cc from the v8 sample code. I wonder if it is somehow blocking? I admit to not really knowing what I am doing here, just playing around and learning but this one has me stumped.

Inside of keyDown say, I have something like this:

    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);

Some of this may actually not work in the end, but it just never gets called, when I run the program, and define: onKeyDown = function(key) {...}; I can see that onKeyDown is working just fine, I can use all of my bound c++ method etc from JS, so this thing is just driving me batty.

Any help, maybe pointers to some educational materials would be much appreciated.

Just to be clear, this function in c: LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) is never getting called, or never seeing a printf, and the output at the start says: Hook established, so windows is reporting the hook is established.

/Jason

like image 632
J. Martin Avatar asked Aug 07 '11 18:08

J. Martin


2 Answers

A low-level hook, like WH_KEYBOARD_LL requires that your application pumps a message loop. That's the only way that Windows can break into your thread and make the call to the HookProc callback you registered.

A console mode app doesn't pump a message loop like regular Windows GUI apps do. Judging from your snippet, it isn't going to be easy to add one either. You'll need to create a thread.

like image 200
Hans Passant Avatar answered Nov 20 '22 19:11

Hans Passant


Maybe this function will be of help to you? GetAsyncKeyState

like image 26
James Avatar answered Nov 20 '22 19:11

James