C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup
Asked Answered
R

3

6

I'm creating a console application in which I'd like to record key presses (like the UP ARROW). I've created a Low Level Keyboard Hook that is supposed to capture all Key Presses in any thread and invoke my callback function, but it isn't working. The program stalls for a bit when I hit a key, but never invokes the callback. I've checked the documentation but haven't found anything. I don't know whether I'm using SetWindowsHookEx() incorrectly (to my knowledge it successfully creates the hook) or my callback function is incorrect! I'm not sure whats wrong! Thanks in advance for the help.

#include "Windows.h"
#include <iostream>
using namespace std;

HHOOK hookHandle;

LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam);

int _tmain(int argc, _TCHAR* argv[]) {

 hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, keyHandler, NULL, 0);

 if(hookHandle == NULL) {
  cout << "ERROR CREATING HOOK: ";
  cout << GetLastError() << endl;
  getchar();
  return 0;
 }

 MSG message;

 while(GetMessage(&message, NULL, 0, 0) != 0) {
  TranslateMessage( &message );
  DispatchMessage( &message );
 }

 cout << "Press any key to quit...";
 getchar();

 UnhookWindowsHookEx(hookHandle);

 return 0;
}


LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam) {
 cout << "Hello!" << endl;

 // Checks whether params contain action about keystroke
 if(nCode == HC_ACTION) {
  cout << ((KBDLLHOOKSTRUCT *) lParam)->vkCode << endl;
 }

 return CallNextHookEx(hookHandle, nCode, 
            wParam, lParam);
}
Regine answered 30/1, 2010 at 2:28 Comment(1)
Please see here for a similar question, which I answered that will help you.Ledger
C
3

You can't block on a syscall (the getchar), you have to be running a window loop and processing messages before your hook gets called.

Cupboard answered 30/1, 2010 at 2:32 Comment(3)
How would I implement a window loop? I'm very unfamiliar with WinAPIs (in fact whats the purpose of a window loop?)Regine
Thanks, I'll post back in a couple minutes if I'm still having problems.Regine
So basically a Message Loop sends the application queue's messages to the appropriate hooks? I've got it working now! Thanks. The code I posted contains the fix.Regine
D
0

On Windows XP, you need, you need to pass hInstance (from WinMain) as the third argument to SetWindowsHookEx. For example:

int WINAPI WinMain
( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  LPTSTR lpCmdLine, int nCmdShow ) {

  hookHandle = SetWindowsHookEx ( WH_KEYBOARD_LL, keyHandler, hInstance, 0 );

// ...
Dunsany answered 22/2, 2014 at 6:46 Comment(0)
A
0

I suggest simle first;

// VB: Retrieve the applications instance HINSTANCE appInstance = GetModuleHandle(NULL);

and then: hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, keyHandler, appInstance, 0);

// ..., but there are another errors later, too

Apparently answered 26/10, 2014 at 8:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.