difficult - Keyboard hook

Hi,
I need to do the following:
A barcode scanner is connected to the PS/2 input using a split cable (so, both the keyboard and the barcode scanner are connected to the same PS/2 port). The barcode scanner uses "keyboard simulation" to send it's code to the currently active application. If you open a texteditor and you scan a barcode, the number is send to the page.

You can add a "prefix" to the barcodescanner of maximum 10 keycodes or characters (like A, #, NULL,
SOHSTXETXEOTENQACKBEL
etc...)
I want to use the barodescanner on the background, so I was planning to use a system wide keyboard hook which detects if there was a NULL-NULL send to the PS/2 input, and in this case takes the 13 following characters (I'm using EAN13 as barcode) and makes that they are send to a file, without that they are send to the active apllication (like MS Word, Outlook, ...).
Some extra information: The PC's on which it must work doesn't have either .NET1 or .NET2 .

I tried to make some demo code, but apparently this code won't work (because the NULL's aren't captured):


LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(int nCode,WPARAM wParam, 
LPARAM lParam)
{
char ch;
if (((DWORD)lParam & 0x40000000) &&(HC_ACTION==nCode))
{
if ((wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f ) &&(wParam<=0x100))
{
f1=fopen("c:\\report.txt","a+");
if (wParam==VK_RETURN)
{
ch='\n';
fwrite(&ch,1,1,f1);
}
else
{
BYTE ks[256];
GetKeyboardState(ks);

WORD w;
UINT scan=0;
ToAscii(wParam,scan,ks,&w,0);
ch = char(w);
fwrite(&ch,1,1,f1);
}
fclose(f1);
}
}

LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam );
return RetVal;
}
How should I adapt the code Can someone give me some example code
Thanks



Answer this question

difficult - Keyboard hook

  • William N

    I can read Dutch but still have a hard time figuring out your code. The cast on wParam is pretty bizarre. I'm guessing it triggers the barcode reading on the WM_SYSKEYUP message. That is not sufficiently unique, WM_SYSKEYUP is generated for any keystroke with the Alt key down, including the Alt key itself.

    You must pass non-character keys like VK_MENU (Alt), VK_CONTROL and VK_SHIFT unmodified. Not doing this would fatally confuse the application programs.


  • sroughley

    Thanks a lot. I followed your advice.
    I made some code using a
    SetWindowsHookEx (WH_KEYBOARD_LL, LowLevelKeyboardProc ,...);
    I filtered like that:
    (wParam != WM_KEYDOWN)&& (wParam != WM_KEYUP)
    which works fine.
    I do have one more question though:
    What I want to do now is, when it's a barcode which is scanned, it's not passed to the active application.
    Therefore I putted this at the end of the callback function:

    LRESULT RetVal=NULL;
    if (!wasbarcode)
    RetVal = CallNextHookEx(hKeyHook, nCode,wParam,lParam);
    return RetVal;

    But this doesn't seems to work ! I'm positively sure that the filter does what it should do.
    (the only reason I could think of is the following:
    I'm not working with a dll to hook but with a single exe (like this):

    __declspec(dllexport) LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam ) {
    bool wasbarcode=false;

    What am I doing wrong
    Should I work with a dll or is it something else I did wrong

    Thanks a lot !

  • A.Carter

    The docs are confusing due to the nCode argument. However, if you *do* use the keystroke, you need to return a non-zero value to indicate that you used the keystroke and shouldn't be passed on the application. The code you posted is returning a zero. Try this:

    LRESULT RetVal = (LRESULT)1;
    if (!wasbarcode)
    // Etc.



  • lemonsito

    Those prefix codes don't make any sense. NULL is not a valid key code. SOH, STX etc are control codes (0x01 through 0x07). Keycode 0x01 is VK_LBUTTON. Instead, the scanner may generate a Ctrl+A, Ctrl+B, etc. Possibly, NULL is Ctrl+@. You'd better take a look first without using the keyboard hook.

    You also might want to consider a hook set with WH_KEYBOARD_LL instead of WH_KEYBOARD. The latter requires Windows to inject your DLL into the process space of every running process.


  • Netoblivion

    OK. Found it. Now it works, but there's still one bug left:
    whenever a barcode is scanned, the numpad doesn't works anymore...
    Which is very annoying, because you have to unhook the application...

    Here is the code (it's a bit ugly, should clean it up once...)

    static bool wasbarcode=false;
    static bool eerstevdtwee=true;
    static int teller=0;
    static int tempcijfer;

    __declspec(dllexport) LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam ) {

    bool laatstealtweg=false;
    if ((nCode == HC_ACTION) ) {
    if ((unsigned char)wParam == 0x05) {//hier dus: barcode gedeelte
    wasbarcode=true;
    teller++;
    if(teller==26){wasbarcode=false;/*teller=0;*/}
    printf("\nteller:%i\n",teller);
    BYTE KeyState[256];

    KBDLLHOOKSTRUCT hooked = *((KBDLLHOOKSTRUCT*)lParam);

    GetKeyboardState(KeyState);

    printf("\n--flags:%x--scancode:%x--vkcode:%x--tempcijf:%i",hooked.flags,hooked.scanCode,hooked.vkCode,(int)hooked.vkCode-96);

    if(eerstevdtwee)
    {tempcijfer=(int)hooked.vkCode-96;}
    else{//dus tweede!
    tempcijfer=(10*tempcijfer +((int)hooked.vkCode-96))-48;
    printf("%i",tempcijfer);
    }
    eerstevdtwee=!eerstevdtwee;
    }//eind barcodegedeelte
    else{//hierin moet laatste ALT weggewerkt worden ! anders:
    if(teller==26){teller=0;laatstealtweg=true;}
    }
    }
    return((wasbarcode || laatstealtweg) (LRESULT)1 : CallNextHookEx(hKeyHook, nCode,wParam,lParam));
    }

  • davros51

    Check the docs, wParam doesn't contain the keycode, it contains WM_KEYDOWN/UP or WM_SYSKEYDOWN/UP. The keycode is lParam->vkCode. The key code for the ALT key is not 0x05, it is VK_MENU (0x12).


  • ehrlich

    Thanks; the problem is solved, now !

  • johnvms

    I just tried that, and it doens't works .
    It gave a very strange result:
    every barcode was send to the application as before, exept all the 7's in the barcode were replaced by .
    So, the code
    8711875929908
    Gave this in the "notepad-window":
    8 118 5929908

    I searched further but didn't found anything else...
    Thanks.

  • Dom Melino

    Isn't

    if ((nCode == HC_ACTION) ) {
    if ((unsigned char)wParam == 0x05) {

    only selecting the Alt The Control and shift use another wParam !

  • difficult - Keyboard hook