I am trying to write a simple global keyboard hook program to redirect some keys. For example, when the program is executed, I press 'a' on the keyboard, the program can disable it and simulate a 'b' click. I do not need a graphic ui, just a console is enough (keep it running)
My plan is to use global hook to catch the key input, and then use keybd_event to simulate the keyboard. But I have some problems.
The first problem is that the program can correctly block 'A' but if I hit 'A' on the keyboard once, the printf in the callback function is executed twice, as well as the keybd_event. So if i open a txt file, i click 'A' once, there are two 'B's input. why is that?
The second question is that why the hook using of WH_KEYBOARD_LL can work on other process without a dll? I thought that we had to use a dll to make a global hook until I wrote this example...
#include "stdafx.h"
#include <Windows.h>
#define _WIN32_WINNT 0x050
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
BOOL fEatKeystroke = FALSE;
if (nCode == HC_ACTION)
{
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
if (fEatKeystroke = (p->vkCode == 0x41)) { //redirect a to b
printf("Hello a\n");
keybd_event('B', 0, 0, 0);
keybd_event('B', 0, KEYEVENTF_KEYUP, 0);
break;
}
break;
}
}
return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam));
}
int main()
{
// Install the low-level keyboard & mouse hooks
HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
// Keep this app running until we're told to stop
MSG msg;
while (!GetMessage(&msg, NULL, NULL, NULL)) { //this while loop keeps the hook
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hhkLowLevelKybd);
return(0);
}
Many thanks!
hMod
, but in this case you can use any legal value, since no DLL gets injected anyway for low-level hooks. You can use, for example,GetModuleHandle("kernel32.dll")
. – user