我正在做的项目需要在键盘上记录全局击键,并使用不同的键组合,并按住哪个控制键(左键或右键)。似乎唯一可能的方法是使用KeyDown和KeyUp事件而不是KeyPress。但是,我还需要记录输入哪个字符。
我理解如果我使用KeyPress事件,我将始终得到正确的字符,但是对于KeyDown和KeyUp事件,它只会给出KeyCode,而不管键组合如何。其中一种解决方案是使用Dictionary来映射移位键,但它对国际环境并不友好,因为不同的本地化键盘有不同的符号。例如,Shift-2在美国键盘上给出了一个@符号,在英国键盘上给出了一个"符号。
我想知道是否有任何方法可以自动转换组合,而无需手动映射所有键盘布局?
一个稍微复杂但离题的问题是,如果用户使用一些软件键映射程序来给键提供不同的输出,情况如何?例如,交换a和s键的定义,即输入a时它输出s,反之亦然。全球挂钩会发生什么?我没有安装这种软件,所以我不能测试它,有人有处理它的经验吗?
发布于 2017-06-01 13:42:09
有趣的问题。我设法从这里得到了正确的移位值:Keyboard Mapping in .NET
using System.Runtime.InteropServices;
public static class User32Interop
{
public static char ToAscii(Keys key, Keys modifiers)
{
var outputBuilder = new StringBuilder(2);
int result = ToAscii((uint)key, 0, GetKeyState(modifiers),
outputBuilder, 0);
if (result == 1)
return outputBuilder[0];
else
throw new Exception("Invalid key");
}
private const byte HighBit = 0x80;
private static byte[] GetKeyState(Keys modifiers)
{
var keyState = new byte[256];
foreach (Keys key in Enum.GetValues(typeof(Keys)))
{
if ((modifiers & key) == key)
{
try
{
keyState[(int) key] = HighBit;
}
catch { }
}
}
return keyState;
}
[DllImport("user32.dll")]
private static extern int ToAscii(uint uVirtKey, uint uScanCode,
byte[] lpKeyState,
[Out] StringBuilder lpChar,
uint uFlags);
}然后在KeyDown事件中这样使用它:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode != Keys.ShiftKey)
{
if (e.Modifiers.ToString() == "Shift")
{
var c = User32Interop.ToAscii(e.KeyCode, Keys.ShiftKey);
MessageBox.Show(c.ToString());
}
}
}与德国键盘布局,这产生了“而美国键盘布局我得到”。所以,几乎所有你需要的东西,我猜。
我不能用第三方密钥映射器来测试这个,所以您只需尝试一下。
https://stackoverflow.com/questions/44306961
复制相似问题