2

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.

obamator
  • 478
  • 3
  • 13
  • This is basically the same as [this question](http://stackoverflow.com/questions/12885897/block-keystrokes-from-a-specific-keyboard). Unfortunately, there's only half an answer. – arx Oct 16 '12 at 16:03
  • This answer should solve your problem: http://stackoverflow.com/a/3060668/886887 – Harry Johnston Oct 17 '12 at 21:18
  • @HarryJohnston It should, unfortunately there exists such thing as a keyboard/card scanner combo that I appear to need to support; it registers as a single device but sends both regular keyboard input and scanned codes as indistinguishable keystrokes :( – obamator Oct 25 '12 at 07:26

1 Answers1

4

Ok, here is my solution in case someone encounters a similar problem.

First, use WH_KEYBOARD_LL hook instead of WH_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 KBDLLHOOKSTRUCT as one of the parameters; use LLKHF_INJECTED bit in its flags bitfield 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 the dwExtraInfo member of the structure both SendInput() 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.

obamator
  • 478
  • 3
  • 13