I’m making a “driver” for a barcode scanner.
This particular scanner is basically a USB keyboard that generates keystrokes whenever something is scanned.
I want to find a way to distinguish these keystrokes from those keystrokes a proper keyboard sends. Unfortunately the only difference is that scanner generates keystrokes really fast, a bunch of keyups and keydowns in a fraction of a second.
The way I see it is I have to set up a global keyboard hook that intercepts all input, stores it somehow, waits for a tiny bit then either sends those keystrokes further down the hook chain or assumes they are something that scanner generated and handles them appropriately.
However, having no prior experience with hooks, I am not sure about the right way to do it. Can I just invoke CallNextHookEx() in some method other than KeyboardProc() in some other thread to pass the delayed keystroke event? Or should I rather generate a new WM_KEYPRESS message manually? Maybe there is an altogether better way to go about this thing?
Thanks.
Ok, here is my solution in case someone encounters a similar problem.
First, use
WH_KEYBOARD_LLhook instead ofWH_KEYBOARD.Second, use
SendInput()API function to pass keystrokes you don’t need to the active window.Third, low level keyboard hook’s callback function has a pointer to
KBDLLHOOKSTRUCTas one of the parameters; useLLKHF_INJECTEDbit in itsflagsbitfield to distinguish real keystrokes from the ones you’ve just generated. If you are paranoid and afraid someone else might be pulling the same trick, use thedwExtraInfomember of the structure bothSendInput()and hook callback use to distinguish keystrokes that are injected by yourself and by someone else.Fourth, be aware that Windows 7 tends to silently unhook a low-level hook if it takes too long to process the input, so either keep the hook callback as simple and possible and be sure to pump the Windows message queue as often as possible in the thread that hooked the hook; or – if you’re a bad bad boy – there is a registry key at
HKCU\Control Panel\Desktop\[DWORD]LowLevelHooksTimeout, setting it to a reasonably large value might work too.