views:

695

answers:

2

The only keyboard hook supported for .NET managed code is a low-level keyboard hook (WH_KEYBOARD_LL).

See http://stackoverflow.com/questions/1639331/using-global-keyboard-hook-whkeyboardll-in-wpf-c

I have the above code working in my application at the moment so that when you swipe your card you will get a list of all the keystrokes. The problem is for typing delimiter characters such as "%" and ";" it will send me Alt+Numpad+? WPF Key objects corresponding to these symbols.

My question: Is there some way to make this behave more high-level, that is, to capture a string generated from all keyboard commands?

Cheers!

A: 

Not sure what's going on, but getting a character like % out of a keyboard hook is very untrivial. The hook only notifies you of virtual keys. But % is a typing key, produced by pressing Shift + 5 on my keyboard (a US layout). Windows normally produces these characters by processing the WM_KEYDOWN/UP messages, generating a WM_CHAR message for the typing key. That's not happening in your case. The low-level Windows function that does this is ToUnicodeEx().

Hans Passant
Thanks for your help nobugz, i'll take a look at ToUnicodeEx(). Found a question on so about how to acheive this http://stackoverflow.com/questions/370754/convert-a-keycode-to-the-relevant-display-character
reckoner
A: 

I would guess if you are swiping the card, there's an input somewhere on the wpf form, like a textbox for example? Then I would be inclined to add an event, perhaps a KeyUp Event handler, (The keyboard wedge card scanner does send an end-of-processing signal such as ENTER to indicate the swipe was successful yes?), In the KeyUp Event Handler, build up a string using StringBuilder, and when the end-of-processing signal such as ENTER is caught, you can then remove the "%" and ";" from the StringBuilder instance and do whatever you have to do with it.

It might be easier to use a state system, when the KeyUp event handler receives a "%", then enter another state where the end expected state would be a ";"

static bool StartState = false;
StringBuilder sbInput = new StringBuilder();
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
   if (!StartState){
    if (e.KeyCode == Keys.D5) StartState = true;
    sbInput.Append((char)e.KeyValue);
   }else{
    if (e.KeyCode == Keys.OemSemicolon){
       StartState = false;
       // sbInput will contain the data from the scanner,
       // copy it somewhere else and reset sbInput
       // sbInput.Remove(0, sbInput.Length); 
    }
    sbInput.Append((char)e.KeyValue);
   }
   e.Handled = true;
}

Hope this helps, Best regards, Tom.

tommieb75
There is not an input on my form. To prevent problems with the textbox or application losing focus I am using a keyboard hook that should perform this task invisibly to the user.
reckoner
@reckoner: Hmmm...and where does the swiped data go to? Surely you have something on the form that says something like 'Please swipe' yes? And what did you mean by 'prevent problems with the textbox or application losing focus'? Are you using a third-party program (probably supplied with the scanner) to read the swiped data?
tommieb75
@tommieb75: The interface is going to be a touch screen where users navigate through pages of information in all the coolness of WPF. The swiped data is intercepted and stored in a database and will display an unobtrusive notification. It is for taking event attendance.
reckoner