我想创建一个 ConsoleKeyInfo 实例,该实例与在 PowerShell session 中键入的任何左大括号匹配(我使用 PSReadline 进行 key 处理)。为方便起见,这里是所有涉及的键的属性

PS> while($true){ [System.Console]::ReadKey($true) }

    KeyChar     Key    Modifiers
    -------     ---    ---------
          [    Oem4            0
          ]    Oem6            0
          {    Oem4        Shift
          }    Oem6        Shift

在键处理程序中,我得到了按下的“和弦”的 ConsoleKeyInfo (并且 PSReadline 进行过滤,所以我已经知道我只收到 Oem4Shift+Oem4 )。我想生成匹配的 ConsoleKeyInfo 以便我可以将打印对发送到控制台。

ConsoleKeyInfo constructor 需要
  • char
  • System.ConsoleKey
  • 分别用于 Shift、Alt 和 Control 的 bool

  • 我可以通过将其转换为 ConsoleKey 并向上移动两个来获得正确的 int ...
    PS> [System.ConsoleKey]([int]$key.Key + 2)
    Oem6
    

    我可以通过按位测试来从按下的键的 Modifiers 映射...
    PS> ($key.Modifiers -band [System.ConsoleModifiers]::Shift) -ne 0
    False
    

    但是,我不知道如何获取此控制台键的文字 char。控制台如何从键盘键中获取字符?这只能通过实时控制台/键盘来完成吗?

    我宁愿不维护 key 对的映射,也不拆分处理程序,每个“和弦”一个,并对匹配的键字符进行硬编码。 :(

    最佳答案

    您可能不需要仅为 PSReadline 创建 ConsoleKeyInfo。

    有时您可能需要将 ConsoleKeyInfo 传递给 PSConsoleReadLine 中的方法,但 PSConsoleReadLine 中接受 ConsoleKeyInfo 的大多数方法甚至不查看参数。这就是参数为 Nullable 的原因。

    但这实际上并没有回答你的问题。 JaredPar 是绝对正确的,一般来说,不可能将 ConsoleKey/ConsoleModifiers 对转换为字符。如果我们不关心完全通用性(目前 PSReadline 不关心),您可以使用类似于 PSReadline 使用的代码:

    internal static char GetCharFromConsoleKey(ConsoleKey key, ConsoleModifiers modifiers)
    {
        // default for unprintables and unhandled
        char keyChar = '\u0000';
    
        // emulate GetKeyboardState bitmap - set high order bit for relevant modifier virtual keys
        var state = new byte[256];
        state[NativeMethods.VK_SHIFT] = (byte)(((modifiers & ConsoleModifiers.Shift) != 0) ? 0x80 : 0);
        state[NativeMethods.VK_CONTROL] = (byte)(((modifiers & ConsoleModifiers.Control) != 0) ? 0x80 : 0);
        state[NativeMethods.VK_ALT] = (byte)(((modifiers & ConsoleModifiers.Alt) != 0) ? 0x80 : 0);
    
        // a ConsoleKey enum's value is a virtual key code
        uint virtualKey = (uint)key;
    
        // get corresponding scan code
        uint scanCode = NativeMethods.MapVirtualKey(virtualKey, NativeMethods.MAPVK_VK_TO_VSC);
    
        // get corresponding character  - maybe be 0, 1 or 2 in length (diacriticals)
        var chars = new char[2];
        int charCount = NativeMethods.ToUnicode(
            virtualKey, scanCode, state, chars, chars.Length, NativeMethods.MENU_IS_INACTIVE);
    
        // TODO: support diacriticals (charCount == 2)
        if (charCount == 1)
        {
            keyChar = chars[0];
        }
    
        return keyChar;
    }
    

    关于c# - 如何获得仅知道 ConsoleKey 枚举和修饰符的按键的字符?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22048596/

    10-10 12:46