Convert character to virtual key code - c#

I have a string of values, and I want to simulate key press events in a window for each character.
I plan on sending WM_KEYDOWN, WM_CHAR, and WM_KEYUP events to the window (as that is what seems to happen whan a key is manually pressed).
Those messages require an int be sent in the wParam based on a table of virtual key codes. I can loop through the string and get each character, but how do I take that character and convert it to a value that corresponds to the virtual key code? Convert.ToInt32() does not work.

VkKeyScanEx anyone? According to MSDN it:
"Translates a character to the corresponding virtual-key code and shift state."
(You could possibly also use VkKeyScan but beware that it has been superseded by VkKeyScanEx.)

Sending WM_KEYDOWN/UP is troublesome. The application itself already translates the WM_KEYDOWN message into WM_CHAR, using the state of the modifier keys (Shift, Alt, Ctrl) and the keyboard layout. Neither of which you can control, you'll get the wrong character, randomly.
Just send WM_CHAR messages, set the wparam to the character code. No need to worry about lparam, few apps ever use it.

It looks like it takes the ASCII character and turns it into hex. For example, 'A' in hex is 41. According to your chart, A is 0x41, which is right (the 0x detonates hex).

Generally speaking, instead of sending WM_KEYDOWN, WM_CHAR and WM_KEYUP messages directly, you should use SendInput (preferred) or possibly keybd_event (deprecated).

You can use Input Simulator library which provides a high level api for simulating key presses and handles all the low level stuff.

System.Windows.Forms.SendKeys is a WinForms class with static methods for simulating keyboard input on the active window.
The catch is that .NET has no way of focusing windows in another application (the SendKeys docs talk about how to get around that).

The general solution is to use the SendMessage WinAPI function. This link describes SendMessage's signature and provides a sample import.
Oh and, to map VK codes you should use MapVirtualKey - its best to assume the mapping is arbitrary and not logical.

Related

Trap NULL key in WPF application

I am using a barcode scanner and we were looking for a way to determine if input was from a keyboard or the scanner. The input will be used in a WPF POS application. We thought we had come up with a good method by using the scanners ability to prefix reads with custom characters. The first character ideally would be non printable so we chose NULL or '\0'. We used the following code to register an event handler
EventManager.RegisterClassHandler(typeof(System.Windows.Controls.Control), System.Windows.Controls.Control.KeyUpEvent, new RoutedEventHandler(KeyUpEvent));
internal static void KeyUpEvent (object sender, RoutedEventArgs e)
{
KeyEventArgs keyEvent = e as KeyEventArgs;
if (keyEvent != null)
{
keyEvent.Key.ToString();
}
}
This however seems to not get the first NULL character and instead moves to the next char which is the length of the data.
I have also tested with a console app and just done a Console.ReadKey(). This returns me the null char as the first thing read so I know the scanner is definitely sending the correct data.
So is there any way in WPF to obtain all the data read?
Edit:
I tried using TextCompositionEventHandler but to no avail, i still only get the printable characters coming through.
KeyEventArgs.Key is not a character, it's an enum indicating which key was pressed. There is no NULL keyboard key so there is no point trying to check for the ASCII NULL (0x00) character. Moreover, most non-printable characters have no equivalent key and require the user to use a combination of keys to type them.
If you want to detect scanner codes using prefixes, try chekcing the UIElement.TextInput TextBoxBase.TextChanged events.
A better idea may be to use the scanner's SDK (if available) to send data directly to your application. More expensive models usually have an SDK to communicate with applications directly instead of emulating the keyboard.
I might be wrong, but I don't think NULL and \0 is the same in this context. Have a look at this post. They suggest using TextInput instead of KeyUp.
How to get KeyChar in WPF application

System.Windows.Forms.Keys - Lower or Uppercase?

I have been searching around for an answer to this but I can't seem to find anything. Does anyone know if you can determine the letter casing in Keys?
For example:
if (System.Windows.Forms.Keys.A.ToString() == "A")
{
// Upper or Lower?
}
Thanks.
There is no casing, it represents a physical key on your keyboard. Do you see an 'a' and an 'A' on your keyboard?
You can check and see if a Shift key is depressed.
System.Windows.Forms.Keys.A represents the physical key A on your keyboard. It does not have a case. Thus, your question does not make sense.
If you want to check whether the user holds the Shift key on the keybord, there's also System.Windows.Forms.Keys.Shift.
There is no simple mapping between keys and characters. Keyboard layouts can work differently. One example are dead keys. And once you get to IMEs it gets even more complicated. Do not try to duplicate a keyboard layout manually in your application.
If you want to get what character a user entered, handle WM_CHAR, not WM_KEY_DOWN/UP. It's exposed as Control.KeyPress event in winforms.

Faking Input Like GlovePIE

I have been programming against Kinect, and I now want to have games react to what I am doing on the Kinect. It is real easy to send data to notepad for key presses, but much harder to send it to games.
First off, I have been using the WPF Skeleton example from Kinect and building off that for now. I could use the C++ version but my C++ is very rusty, and I would prefer not to.
So here is what I have done so far, I have tried SendKeys, SendInput, keybd_event, Post_Message. None of those make it to games like Burnout Paradise.
I do know GlovePIE input gets to games, but how? Currently my work around/hack, is to use PPJoy, which has sample code in C++ to emulate button presses. I call this via [DllImport] from my WPF app. I then pickup the joystick button presses in GlovePIE and have it convert those to Keyboard Keys. So I go around in a circle, which works but PPJoys driver is not signed, so I can't really share this code as people would have to allow test-signed drivers.
Does anyone know how GlovePIE makes their Keypresses happen? I have posted on the GlovePIE Forums, but no responses. GlovePIE has a little bit of a hack to work with the old openNI kinect drivers, but I am using the standard microsoft version recently released a few weeks ago.
Ok, not sure what the scoop is on answering your own question, but I figured out the whole proper solution and wanted to share as the Checked off Answer.
First Include this using statement
using System.Runtime.InteropServices;
Then Put this in your class this in your class
[DllImport("user32.dll", EntryPoint = "keybd_event", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern void Keybd_event(byte vk, byte scan, int flags, int extrainfo);
This will import the C method for use in C#.
Now some games / application use Virtual Keys VKey and some (Direct X aka DIKey) use Scancodes. My problem was I used the scan codes improperly so it did not work for some games. I suggest if you do not know what application wants to consume these, you call it twice one with Virtual Key and one for Direct Input Key
Here is an example of two calls for the letter 'A' using Virtual Keys then using Direct Input Keys.
KEYDOWN = 0
KEYUP = 2
//Virtual Key
Keybd_event(65, 0, KEYDOWN, 0);
//Direct Input Key
Keybd_event(0, 30, KEYDOWN, 0);
As you can tell the values for A are different from VK to DIK
Both of the links relate to the HEX values, while my samples above show Base 10 (Integers)
VKeys link http://delphi.about.com/od/objectpascalide/l/blvkc.htm
DIKeys link http://community.bistudio.com/wiki/DIK_KeyCodes
This should also work for SendInput also, but I have not fully verified that.
I don't know GlovePIE, sorry, but perhaps these might help.
PostMessage and SendMessage get different behaviour when dealing with emulating keystrokes.
Would also help to know what message your actually sending, keydown/up, keypress etc.
You may need to do something about changing the focus - maybe the wrong element is selected, or your sending to the wrong (sub)window.
Similarly if you where emulating mouse clicks there can also be checks for where the mouse is to ensure it is still on the clickable area.
Consider also holding a key down triggers a repeat mechanism sending multiple key messages, commonly in games your holding the key down to turn not just tapping it once.
While I will not say this is the best answer, I wanted to round back with the solution I am using. I have found that I can use vJoy http://headsoft.com.au/index.php?category=vjoy which is signed, so it can be used in Windows 7 64 bit. I can the call this extern keybd_event
[DllImport("user32.dll", EntryPoint = "keybd_event", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern void Keybd_event(byte vk, byte scan, int flags, int extrainfo);
From there I can Keybd_event(CKEY, SCANCODE, KEYDOWN, 0); then X frame later call Keybd_event(CKEY, SCANCODE, KEYUP, 0);
I set vJoy to read in "c" or other keys I send via keybd_event. vJoy reads this properly and then "presses" the associated button which GlovePIE picks up. So in GlovePIE my script look like
A = joystick1.Button1
Z = joystick1.Button2
Which works in the games I have tried.
It is definitely not idea, but it works and allows end user to customize the input via vJoy and GlovePIE.

Converting KBDLLHOOKSTRUCT(.NET) to KeyEvent/Char(Java), JNA

So, basically what i'm doing is using JNA to set a LowLevelKeyboardProc Keyboard hook, everything works perfectly fine, i can get the values exactly like i want them in java, but the problem i get is when trying to convert to chars, it becomes extremely ennoying handling caps locks, SHIFT keys and tons of other things like everything thats not a-z 0-9 on the keyboard, i was wondering if there is a easier way to do the conversion?
heres the details of what I'm getting from the hook every time a key is pressed
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=VS.85).aspx
, i Figured it might be best to find a way to manually generate a KeyEvent(Not char, since i need something to handle things like F keys, caps lock button, CTRL button etc etc).
Any help i can get is highly appriciated!.
The Abbot project (http://abbot.sf.net) has a system for mapping keycodes to keychars, using predefined keyboard mappings (it generates a wide variety of keystrokes and records the resulting character output). However, Java does not provide a way for "predicting" the resulting character output given a particular key code.
There may be something within the MS libraries.

WM_KEYDOWN : how to use it?

I'm trying to send a key stroke to one application, through PostMessage. I am using too Spy++ to try to understand how to send the message, as I do not fully understand its inner workings.
In this picture, the first item(selected item) was made with an actual key stroke made by myself. The one with a red elipse around it(below) was made with the following code:
WinApi.PostMessage(InsideLobbyHandle, WinApi.WM_KEYDOWN, (int)WinApi.VK_UP, 1);
I guess it must have something to do with the last PostMessage() parameter, but I can't figure out how it really works. I can see in the original key stroke the ScanCode = 48, and in mine its 0, and also fExtended is 1 and in mine is 0. How can I make it look the same?
In http://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx I cannot understand the last parameter's working.
Simulate keyboard input using SendInput, not PostMessage.
You can't simulate keyboard input with PostMessage.
There are still some caveats with respect to keyboard state/async-state:
The SendInput function does not reset
the keyboard's current state.
Therefore, if the user has any keys
pressed when you call this function,
they might interfere with the events
that this function generates. If you
are concerned about possible
interference, check the keyboard's
state with the GetAsyncKeyState
function and correct as necessary.
The lParam for the WM_KEYDOWN Notification is specified in terms of the bits of the field:
The first 16 bits are the repeat count
The next 8 bits are the scan code
The next bit is 1 for extended key, 0 otherwise
The next 4 bits are reserved and must be 0
The next bit is always 0 (for WM_KEYDOWN)
The next bit is the previous key state
The last bit is always 0 (for WM_KEYDOWN)
A warning: Any solution you build based around PostMessage is going to be very brittle.
Take a look at http://inputsimulator.codeplex.com, it wraps the SendInput method mentioned by Kevin
In Spy++ if you right click on the highlighted (logged message) entry and look at its properties, You can see the exact value of the lParam. You can then use that as your lParam to ensure that the PostMessage leads to similar effects, as the manual action did.

Categories

Resources