wpf - ¿Cómo se obtiene el personaje apropiado para el evento KeyDown dado?
character-encoding (4)
¿Cómo se obtiene el personaje apropiado para el evento KeyDown dado en WPF?
No todos los eventos KeyDown corresponden a un solo carácter visible, por ejemplo, Retroceso e Intro. Deberá comparar los contenidos del evento arg con lo que desea asociar. Por ejemplo, en mi teclado QUERTY de EE. UU., La tecla de la esquina superior izquierda es una marca de retroceso, pero podría parecer algo diferente a otro teclado.
Prueba esto:
var virtualKey = (uint)KeyInterop.VirtualKeyFromKey(e.Key);
var keyCode = MapVirtualKey(virtualKey, 0);
Función de importación MapVirtualKey
[DllImport("user32.dll")]
static extern uint MapVirtualKey(uint uCode, uint uMapType);
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,
}
[DllImport("user32.dll")]
public static extern bool GetKeyboardState(byte[] lpKeyState);
[DllImport("user32.dll")]
public static extern uint MapVirtualKey(uint uCode, MapType uMapType);
[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);
public static char GetCharFromKey(Key key)
{
char ch = '' '';
int virtualKey = KeyInterop.VirtualKeyFromKey(key);
byte[] keyboardState = new byte[256];
GetKeyboardState(keyboardState);
uint scanCode = MapVirtualKey((uint)virtualKey, MapType.MAPVK_VK_TO_VSC);
StringBuilder 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;
}
private void UserControl1_KeyDown_1(object sender, KeyEventArgs e)
{
FieldInfo field = e.GetType().GetField
(
"_scanCode",
BindingFlags.NonPublic |
BindingFlags.Instance
);
Int32 scancode = (Int32)field.GetValue(e);
char c = (char)scancode;
}