I need to get the numeric values of keyboard keys based on ASCII table .As WPF doesn\'t have built in solution I have tried several hacks:
1. This on
Look at KeyEventUtility.GetCharFromKey( e.Key )
UPDATE: sorry that was some library code of mine
public static class KeyEventUtility
{
// ReSharper disable InconsistentNaming
public enum MapType : uint
{
MAPVK_VK_TO_VSC = 0x0,
MAPVK_VSC_TO_VK = 0x1,
MAPVK_VK_TO_CHAR = 0x2,
MAPVK_VSC_TO_VK_EX = 0x3,
}
// ReSharper restore InconsistentNaming
[DllImport( "user32.dll" )]
public static extern int ToUnicode(
uint wVirtKey,
uint wScanCode,
byte[] lpKeyState,
[Out, MarshalAs( UnmanagedType.LPWStr, SizeParamIndex = 4 )]
StringBuilder pwszBuff,
int cchBuff,
uint wFlags );
[DllImport( "user32.dll" )]
public static extern bool GetKeyboardState( byte[] lpKeyState );
[DllImport( "user32.dll" )]
public static extern uint MapVirtualKey( uint uCode, MapType uMapType );
public static char GetCharFromKey( Key key )
{
char ch = ' ';
int virtualKey = KeyInterop.VirtualKeyFromKey( key );
var keyboardState = new byte[256];
GetKeyboardState( keyboardState );
uint scanCode = MapVirtualKey( (uint)virtualKey, MapType.MAPVK_VK_TO_VSC );
var stringBuilder = new StringBuilder( 2 );
int result = ToUnicode( (uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0 );
switch ( result )
{
case -1:
break;
case 0:
break;
case 1:
{
ch = stringBuilder[0];
break;
}
default:
{
ch = stringBuilder[0];
break;
}
}
return ch;
}
if (e.Key == Key.A )
Take a look at this page
Based on one of the answers mentioned here, I would suggest You to use TextInput
(or PreviewTextInput
) event to get the letter pressed. It should give You correct values for both upper and lower case letters.
In order to test it, You can use code similar to this one:
private void Window_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
Console.WriteLine(String.Format("letter: {0} (charcode: {1})", e.TextComposition.Text, (int)Convert.ToChar(e.TextComposition.Text)));
}
Let me know if this helps or if You have any problems when using this solution.
This is just not the way keyboards work. Every PC in the world has the same keyboard. Pressing a key generates a virtual key value, the same value on every keyboard in the world. The e.Key value you get in the KeyDown event.
This is where it stops for keys like the function keys, cursor keys, Shift key, etcetera. Unless the key is a typing key that produces a character. Like the letter A. Internally, the KeyDown event is processed by Windows and translated to a character. The actual character that's produced depends on the keyboard layout. Users in different countries have different keyboard layouts, favoring the glyphs that are used most often in their language. Or for that matter the personal preference of a user, a programmer often likes the Dvorak layout.
The character produced also depends on the keyboard state. Like the Shift key, hold it down to produce an A, not down to produce an a. This can get pretty convoluted on non-English keyboards, other layouts also have dead keys that, when pressed, alters the character produced by a the next keystroke. Languages that have a lot of diacritics use them.
The implication is clear, translating the virtual key you get from a KeyDown event is a very perilous undertaking. You should therefore not attempt to do this. And you don't have to, use the TextInput event.