Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获得通过按住shift键获得的字符?_C#_Char_Ascii_Keyboard Input_Modifier Key - Fatal编程技术网

C# 如何获得通过按住shift键获得的字符?

C# 如何获得通过按住shift键获得的字符?,c#,char,ascii,keyboard-input,modifier-key,C#,Char,Ascii,Keyboard Input,Modifier Key,我会尽量更好地解释我的意思,我也会尽量让这个问题不受语言的影响,不过如果有一种方法可以在C#中实现我想要的,而不必引用任何东西,那就太好了。 无论如何 我正在处理键盘输入,并将其转换为字符串。都很好。我得到了Shift键和CapsLock键的状态,并对其进行了EXOR,这样我就可以计算出结果管柱的套管 bool shift = KeyDown(SHIFT_KEY) bool capslock = KeyToggled(CAPSLOCK) bool stringCasing = shift ^ c

我会尽量更好地解释我的意思,我也会尽量让这个问题不受语言的影响,不过如果有一种方法可以在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键或切换capslock键时键入“a”,则它将变为“a”

但是,如果用户决定键入“!”,即“1”加上shift,我只得到1,因为“1”的大写字母仍然是“1”

在问这个问题之前,我在网上浏览了一下,但我得到的只是“自己绘制钥匙图”。这真的是唯一的答案吗?还有,如果我映射了按键,然后一个键盘布局不同的用户尝试使用我的应用程序,会发生什么?
提前感谢。

这可以通过Win32
ToAscii
函数()实现。我不知道有任何.NET framework方法包装这些函数,因此可能需要使用P/Invoke

除了
ToAscii
,您可能还需要一个参考来将密钥转换为密码。此键代码用作
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+base键相关的字符(其中base键是输入字符时按下的物理键,例如,1是
的base键)。例如,对于美国键盘,
GetModifiedKey('7')
GetModifiedKey('&')
都将返回'&'。返回值将使用加载的键盘布局;例如,在德语键盘上(Shift+7是
/
),该方法将返回
/

如何处理键盘输入?KeyCode在事件处理程序中不可用吗?我正在构建XNA的输入类,它或多或少与PInvoking GetKeyState相同。基本上,我可以访问的是所有虚拟键及其相对状态的列表。例如,我有1的键码,但没有!(承认它以VK的形式存在?)这很难——这条线索可能会有帮助,但基本上你所说的就是你问题中的情况。你得自己做。不确定如何处理不同的键盘/布局。我懂了。谢谢你的回复,我想那时我得手工做了。我希望我的用户不会因为我标准化了他们的键盘语言而讨厌我。啊,非常感谢!这正是我需要的,你解释得很好。编辑:我可以得到一个关于-1转换成无符号整数的解释吗?当然,它不会编译,但可能有一些我不知道的东西。为这个错误道歉——我重构了代码的第一部分,以澄清错误检查。作为解释,
VkKeyScan
将返回-1(0xffff),如果没有转换为所提供字符的键(例如,美国键盘上的“ü”)。是的,我也这么认为。再次感谢你的回答!嘿,伙计,四年后写。我仍然爱你的回答哈哈!现在生态系统已经转向了单平台,我再次怀疑是否有多平台的替代方案。啊,我讨厌XNA和它产生的一切。