我会尝试更好地解释我的意思,并且我也会尝试将问题从语言中解脱出来,不过如果有一种方法可以在C#中做我想做的事情而不必参考任何事情。不错。 反正。
我正在处理键盘输入,并将其转换为字符串。一切都很好。我得到了Shift和CapsLock键的状态并且EXOR它,所以我可以找出结果字符串的大小。
bool shift = KeyDown(SHIFT_KEY)
bool capslock = KeyToggled(CAPSLOCK)
bool stringCasing = shift ^ capslock //if both are true/false, the string will be lowercase. Otherwise uppercase.
foreach Key k in [list of keys passed as parameter]
char c = (char)k
if stringCasing
c = Char.ToUpper(c)
else
c = Char.ToLower(c)
end foreach
现在没有问题。如果用户在按住shift键或切换大写字母时键入“a”,则它变为“A”。
但是,如果用户决定键入“!”,即“1”加上shift,我只得到1,因为“1”大写仍为“1”。
在问这个问题之前,我在网上看了一下,但我得到的只是“自己映射密钥”。这真的是唯一的答案吗?而且,如果我映射键然后使用不同键盘布局的用户试图使用我的应用程序会发生什么? 提前谢谢。
答案 0 :(得分:7)
这可以通过Win32 ToAscii
函数(MSDN reference)来完成。我不知道包装这些函数的任何.NET框架方法,因此可能需要使用P / Invoke。
与ToAscii
一起,您可能需要引用VkKeyScan
才能将密钥转换为virtual key code。此密钥代码用作ToAscii
的参数。这些方法的简单P / Invoke声明如下:
[DllImport("user32.dll")]
static extern short VkKeyScan(char c);
[DllImport("user32.dll", SetLastError=true)]
static extern int ToAscii(
uint uVirtKey,
uint uScanCode,
byte[] lpKeyState,
out uint lpChar,
uint flags
);
注意ToAscii
的第三个参数是一个256元素的数组,它引用每个键的状态;值0x80(高位设置)表示密钥已设置。设置元素0x10(Shift的虚拟键代码)模拟 Shift 被按下。
然后我们可以定义一个辅助方法,该方法将表示键的字符作为参数,并输出 Shift 郁闷的键:
public static char GetModifiedKey(char c)
{
short vkKeyScanResult = VkKeyScan(c);
// a result of -1 indicates no key translates to input character
if (vkKeyScanResult == -1)
throw new ArgumentException("No key mapping for " + c);
// vkKeyScanResult & 0xff is the base key, without any modifiers
uint code = (uint)vkKeyScanResult & 0xff;
// set shift key pressed
byte[] b = new byte[256];
b[0x10] = 0x80;
uint r;
// return value of 1 expected (1 character copied to r)
if (1 != ToAscii(code, code, b, out r, 0))
throw new ApplicationException("Could not translate modified state");
return (char)r;
}
调用此方法将返回与输入字符的 Shift +基本键相关联的字符(其中基本键是按下以输入字符的物理键,例如 1 是!
)的基本密钥。例如,对于美国键盘,GetModifiedKey('7')
和GetModifiedKey('&')
都会返回'&'。返回值将使用加载的键盘布局;例如,在德语键盘上( Shift + 7 为/
),该方法将返回/
。