【问题标题】:How can I display KeyCode and KeyData for lowercase letters in c# winforms如何在 c# winforms 中显示小写字母的 KeyCode 和 KeyData
【发布时间】:2023-03-12 13:55:01
【问题描述】:

我正在尝试显示有关按下的键盘键的信息。
此代码正确显示大写字母,但按下小写字母时也会显示大写信息。

我该如何解决这个问题? 这是我想要做的:

public partial class keyDemo : Form
{
    private void keyDemo_KeyPress(object sender, KeyPressEventArgs e)
    {
        charLabel.Text = $"Key pressed: {e.KeyChar}";
    }

    private void keyDemo_KeyDown(object sender, KeyEventArgs e)
    {
        keyInfoLabel.Text =
            $"Alt: {(e.Alt ? "Yes" : "No")}\n" +
            $"Shift: {(e.Shift ? "Yes" : "No")}\n" +
            $"Ctrl: {(e.Control ? "Yes" : "No")}\n" +
            $"KeyCode: {e.KeyCode}\n" +
            $"KeyData: {e.KeyData}\n" +
            $"KeyValue: {e.KeyValue}";
    }

    private void keyDemo_KeyUp(object sender, KeyEventArgs e)
    {
        charLabel.Text = "";
        keyInfoLabel.Text = "";
    }
}

【问题讨论】:

  • 如您所见,Keys.[Key] 没有小写字母。大写/小写由 Shift 和/或 CapsLock 的状态决定。
  • 你也注意到了,KeyPressEventArgs 为字母 Keys 返回一个已经处理的值,包括小写表示。
  • KeyDown 和 KeyUp 事件提供了 virtual 键码。它在世界任何地方都是一样的,并且与 Keys 枚举类型匹配。它们产生的字符(如果有的话)取决于活动的键盘布局和修饰键的状态。像 Shift、Ctrl、Alt。具有 AltGr 键的键盘的额外复杂性。你知道那个角色会是什么,KeyPress 事件会传递它。

标签: c# winforms keypress keydown


【解决方案1】:

原因是KeyEventArgs 返回的是键的详细信息,而不是字符。 (大写和小写字母使用相同的键。) 有些键不会产生字符(例如 Shift、F 键),有些会产生不可打印的字符(例如 Tab、Escape),而某个击键产生的字符取决于您的键盘布局。

如果你想要这个角色,你可能应该使用KeyPress 而不是KeyDown 事件。

但如果你想这样做:

正如@PrinceOfRavens 所说,您必须检查 Caps Lock 键的状态。

您可以这样做,但这仍然不处理字母以外的键,并且不处理 Alt Gr(用于重音字母)。要将击键完全转换为字符,您必须将大多数键盘上的Keys.Add(数字键盘'+')和Shift'='转换为“+”,通常将Shift'1'转换为“!” (取决于您的键盘布局)。

您可以通过替换 KeyToLetter 中的 return null 来扩展它,但这不是输入字符的推荐方法

(我在输出中添加了两项。)

    using System.Runtime.InteropServices;   // for GetKeyState

    ...


    private void keyDemo_KeyDown(object sender, KeyEventArgs e)
    {
        keyInfoLabel.Text =
            $"Alt: {(e.Alt ? "Yes" : "No")}\n" +
            $"Shift: {(e.Shift ? "Yes" : "No")}\n" +
            $"Ctrl: {(e.Control ? "Yes" : "No")}\n" +
            $"KeyCode: {e.KeyCode}\n" +
            $"KeyData: {e.KeyData}\n" +
            $"KeyValue: {e.KeyValue}\n" +
            $"CapsLock: {(CapsLockState ? "Yes" : "No")}\n" +
            $"Letter: {KeyToLetter(e.KeyData, CapsLockState)}";
    }

    // Import the DLL to use a Win32 API call.
    // See https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeystate
    // If using WPF, you could use Keyboard.IsKeyDown :
    //  https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.keyboard.iskeydown?view=netframework-4.7.2
    [DllImport("user32.dll")]
    public static extern short GetKeyState(Keys nVirtKey);

    /// <summary>
    /// true if Caps Lock is on, otherwise false.
    /// </summary>
    public bool CapsLockState 
        => (GetKeyState(Keys.CapsLock) & 1) == 1;

    /// <summary/>
    /// <param name="key">A base key (no modifiers).</param>
    /// <returns>true if and only if the given key represents a letter.</returns>
    public static bool IsLetterKey(Keys key)
        => key >= Keys.A && key <= Keys.Z;

    /// <summary>
    /// Given a keystroke that produces a letter, this returns the letter.
    /// </summary>
    /// <param name="key"></param>
    /// <param name="capsLockState"></param>
    /// <returns>the letter, or null if the given keystroke does not produce a letter.</returns>
    public static char? KeyToLetter(Keys key, bool capsLockState)
    {
        Keys baseKey = key & ~Keys.Modifiers;  // remove modifier keys
        if (IsLetterKey(baseKey) && !key.HasFlag(Keys.Control))    // if a letter
        {
            bool shiftPressed = key.HasFlag(Keys.Shift);   // check whether Shift was pressed
            bool capital = capsLockState ^ shiftPressed;   // if it should be capital
            if (capital)
                return (char)baseKey;
            else
                return Char.ToLower((char)baseKey);
        }
        else
        {
            return null;  // not a letter
        }
    }

【讨论】:

  • 感谢您的重播,但您的解决方案是否包括 KeyCode、KeyData ?因为除了 KeyChar 之外,它们没有出现在 KeyPress 事件中。
  • @HashimAl-Mansouri KeyPress 返回键入的字符,而不是密钥,因此它不提供密钥代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 2010-09-24
  • 1970-01-01
  • 2013-02-04
  • 2018-03-29
  • 1970-01-01
  • 2015-07-28
相关资源
最近更新 更多