繁体   English   中英

在C#中处理KeyDown和KeyPress事件

[英]Handling KeyDown and KeyPress events in C#

我正在尝试制作一个“键盘记录程序” ...嗯,这不完全是一个键盘记录程序,因为它只显示按键记录,而不将它们记录到文件中。 我打算在Google+环聊中使用它,因此我仍然可以显示击键,而不必将其与视频录制软件一起使用。

private void OnKeyDown(object sender, KeyEventArgs e)
{
    lblText.Text = "";
    lblText.Visible = false;

    boxSpKey.Image = null;
    boxSpKey.Visible = false;

    boxCtrl.Visible = e.Control;
    boxAlt.Visible = e.Alt;
    boxWin.Visible = false;
    boxShift.Visible = e.Shift;

    Keys pKey = e.KeyData;
    if (btnIcons.ContainsKey(pKey))
    {
        boxSpKey.Visible = true;
        boxSpKey.Image = btnIcons[pKey];
    }

    // this part I haven't figured out either, but is irrelevant to my question.
}

private void OnKeyPress(object sender, KeyPressEventArgs e)
{
    lblText.Visible = true;
    lblText.Text = ((char)e.KeyChar).ToString();
}

[上下文: lblText是包含键文本的标签, boxSpKey是用于诸如ESC之类的特殊键的PictureBox ,为此,我将每个键都设置为图标。 boxCtrlboxAltboxWinboxShift也是PictureBox这很不言自明。

问题:

  1. 似乎e.Controle.Alte.Shift的值始终为False,因此不会显示相应的PictureBox es。

  2. 如何检查Win键的状态? 我不想使用低级的VK_*常量。

  3. OnKeyPress处理事件时,大多数情况下使用修饰键,我会得到随机字符...如何准确地从中获取原始键击? 即我想得到Ctrl+Shift+B而不是


更新 :我决定使用修饰键进行下级介绍,因此我使用了P / Invoke:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetKeyboardState(byte[] lpKeyState);

public static byte code(Keys key)
{
    return (byte)((int)key & 0xFF);
}

private void OnKeyDown(object sender, KeyEventArgs e)
{
    var array = new byte[256];
    GetKeyboardState(array);

    // ...

    if ((array[code(Keys.ControlKey)] & 0x80) != 0)
        boxCtrl.Visible = true;
    if ((array[code(Keys.LMenu)] & 0x80) != 0 || (array[code(Keys.RMenu)] & 0x80) != 0)
        boxAlt.Visible = true;
    if ((array[code(Keys.LWin)] & 0x80) != 0 || (array[code(Keys.RWin)] & 0x80) != 0)
        boxWin.Visible = true;
    if ((array[code(Keys.ShiftKey)] & 0x80) != 0)
        boxShift.Visible = true;

    // ...
}

好消息是我使CtrlWinShift键起作用了,但是Alt键却没有起作用; 除非AltLMenuRMenu 是什么赋予了?

  1. 分别按CtrlAltShift会使ControlAltShift在我的KeyDown事件处理程序中返回true 分别按这些键中的每个键都会导致在KeyUp事件处理程序中返回false 您确定不处理KeyUp事件吗?

  2. 正如@sean woodward所说, Windows键 应该映射到Keys.LWinKeys.RWin

  3. 仅当按下其中一个字符键时才会引发KeyPress事件,该事件将返回由按下的键或按下的键组合产生的字符。 Ctrl+Shift+B不是字符,因此您不能单独使用KeyChar来获取该信息。 尝试使用KeyDownKeyUp事件,并查看Modifiers属性以获取一个逗号分隔的字符串,其中按下了修饰键。 如果顺序很重要,您将需要进行跟踪,因为Modifiers总是以相同的顺序返回键,即Shift, Control, Alt即使这不是按它们的方式。

这是我使用的代码,您可以尝试使用它:


KeyDown += (o, ea) =>
{
    System.Diagnostics.Debug.WriteLine("KeyDown => CODE: " + ea.KeyCode +
        ", DATA: " + ea.KeyData +
        ", VALUE: " + ea.KeyValue +
        ", MODIFIERS: " + ea.Modifiers +
        ", CONTROL: " + ea.Control +
        ", ALT: " + ea.Alt +
        ", SHIFT: " + ea.Shift);

};

KeyUp += (o, ea) =>
{
    System.Diagnostics.Debug.WriteLine("KeyUp => CODE: " + ea.KeyCode +
        ", DATA: " + ea.KeyData +
        ", VALUE: " + ea.KeyValue +
        ", MODIFIERS: " + ea.Modifiers +
        ", CONTROL: " + ea.Control +
        ", ALT: " + ea.Alt +
        ", SHIFT: " + ea.Shift);
};

KeyPress += (o, ea) => 
{
    System.Diagnostics.Debug.WriteLine("KeyPress => CHAR: " + ea.KeyChar);
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM