如何在c# winforms中显示关键字的KeyCode和KeyData

sf6xfgos  于 11个月前  发布在  C#
关注(0)|答案(2)|浏览(137)

我正在尝试显示按下的键盘键上的信息。
此代码正确显示大写字母,但按下小写字母时也会显示大写信息。
我该如何解决这个问题呢?以下是我正在尝试做的:

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 = "";
    }
}

字符串


的数据

vpfxa7rd

vpfxa7rd1#

这是因为KeyEventArgs返回的是键的详细信息,而不是字符。(大写字母和小写字母使用同一个键。)有些键不产生字符(例如Shift、F键),有些键产生的是不可打印的字符(例如Tab、Escape),而某个键所产生的字符取决于您的键盘布局。
如果您需要该字符,则可能应该使用KeyPress而不是KeyDown事件。
但如果你想做的话:
正如@乌鸦王子所说,你必须检查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://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeystate
    // If using WPF, you could use Keyboard.IsKeyDown :
    //  https://learn.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
        }
    }

字符串

wlp8pajw

wlp8pajw2#

你不必把代码写得太复杂,你只需要添加

if (e.KeyCode == Keys.[Key] && e.KeyCode != Keys.Capital)
 {
    //do whatever here
 }

字符串

相关问题