我的 WPF 应用程序处理键盘按键,特别是 # 和 * 字符,因为它是 VoIP 电话。
我在使用国际键盘时遇到了一个错误,特别是英式英语键盘。通常我会监听 3 键,如果按下 Shift 键修饰符,我们会触发一个事件来执行操作。然而,在英式键盘上,这是“£”字符。我发现英国英语键盘有一个专门的“#”键。显然我们可以只听那个特定的键,但这并不能解决美国英语的情况,即shift-3以及所有无数其他键盘将其放在其他地方。
长话短说,我如何从按键中监听特定字符(无论是组合键还是单个键)并做出反应?
下面的函数 GetCharFromKey(Key key) 就可以解决问题。
它使用一系列 win32 调用来解码按下的键:
这个旧帖子更详细地描述了它。
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 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);
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;
}
我在这篇文章中找到了一个有用的解决方案:http://www.codewrecks.com/blog/index.php/2008/05/06/wpf-convert-systemwindowsinputkey-to-char-or-string-2/
还有另一个事件
TextInput
或 PreviewTextInput
它将字符作为字符串而不是密钥:)。
基于 @JanDotNet 答案的输入,其中链接不再指向现有网站:它使用
PreviewTextInput
事件对我有用。
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
{
// Check for forbidden characters (as negatives of the allowed characters) in the input.
if (Regex.IsMatch(e.Text, @"[^0-9^A-z^\+^\-^\=^\<^\>^\%^\[^\]]"))
{
// Prevent the character being entered into the text box.
e.Handled = true;
}
}