我正在尝试显示按下的键盘按键上的信息。
此代码正确显示大写字母,但按下小写字母时也会显示大写信息。
如何解决这个问题?
这就是我正在尝试做的事情:
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 = "";
}
}
这样做的原因是
KeyEventArgs
返回键的详细信息,而不是字符。 (大写和小写字母使用相同的键。)
有些键不产生字符(例如 Shift、F 键),有些键产生不可打印的字符(例如 Tab、Escape),并且某个击键产生的字符取决于您的键盘布局。
如果您想要该角色,您可能应该使用
KeyPress
而不是 KeyDown
事件。
但是如果你想这样做:
正如 @PrinceOfRavens 所说,您必须检查 Caps Lock 键的状态。
你可以这样做,但这仍然不能处理字母以外的键,并且不能处理 Alt Gr (对于重音字母)。要将击键完全转换为字符,您必须将大多数键盘上的
Keys.Add
(数字键盘“+”)和 Shift“=”转换为“+”,并将 Shift“1”通常转换为“!” (取决于您的键盘布局)。
您可以通过替换
return null
中的 KeyToLetter
来扩展它,但这不是推荐的输入字符的方法。
(我已在输出中添加了两项。)
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
}
}
代码不必太复杂,添加即可
if (e.KeyCode == Keys.[Key] && e.KeyCode != Keys.Capital)
{
//do whatever here
}