在C#中处理KeyDown和KeyPress事件

时间:2013-02-17 02:34:44

标签: c# winforms keyboard-events

我正在尝试创建一个“键盘记录器”......好吧,它并不完全是一个键盘记录器,因为它只显示击键而不会将它们记录到文件中。我计划在我的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是一个PictureBox,用于特殊键,例如ESC,我已经为每个键添加了一个图标。 boxCtrlboxAltboxWinboxShift PictureBox也非常不言自明。]

问题:

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

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

  3. OnKeyPress处理事件时,主要是使用修饰键,我会得到随机字符......我究竟如何从中获取原始键击?即我想获得Ctrl+Shift+B而不是


  4. UPDATE :我决定使用修饰键进入低级别,所以我使用了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 个答案:

答案 0 :(得分:1)

  1. 分别按 Ctrl Alt Shift 导致ControlAlt和{ {1}}在我的Shift事件处理程序中返回true。分别按下这些键中的每一个键会导致KeyDown事件处理程序中返回false。您确定没有处理KeyUp事件吗?

  2. 正如@sean woodward所说, Windows Key 应映射到KeyUpKeys.LWin

  3. 仅在按下其中一个字符键时才会引发Keys.RWin事件,并且将返回按下的按键或按下的按键组合产生的字符。 KeyPress不是字符,因此您无法单独使用Ctrl+Shift+B来获取该信息。尝试使用KeyCharKeyDown事件并查看KeyUp属性以获取以逗号分隔的字符串,其中包含正在按下的修饰键。如果订单很重要,您需要跟踪,因为Modifiers始终以相同的顺序返回密钥,即Modifiers,即使这不是按下的方式。

  4. 以下是我使用的代码,您可以尝试使用它:

    Shift, Control, Alt