简体   繁体   中英

Handling KeyDown and KeyPress events in C#

I'm trying to make a "keylogger"... well, it's not entirely a keylogger because it only displays the keystrokes and doesn't log them to a file. I was planning to use it on my Google+ Hangouts, so I can still show my keystrokes without having to use it with video recording software.

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();
}

[Context: lblText is a label containing the key text, boxSpKey is a PictureBox for special keys such as ESC, for which I've made each one an icon. boxCtrl , boxAlt , boxWin and boxShift are also PictureBox es are quite self-explanatory.]

Questions:

  1. It seems that the values of e.Control , e.Alt and e.Shift are always False, so the respective PictureBox es wouldn't show up.

  2. How do I check for the status of the Win key? I would prefer not to use low-level VK_* constants.

  3. When OnKeyPress handles the events, mostly with the use of the modifier keys, I get random characters... How exactly do I get the original key strokes from them? ie I want to get Ctrl+Shift+B instead of .


UPDATE : I've decided to go low-level with the modifier keys, so I used 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;

    // ...
}

The good news is that I got the Ctrl , Win and Shift keys working, but not Alt ; unless AltLMenu and RMenu . What gives?

  1. Pressing Ctrl , Alt , or Shift individually caused Control , Alt , and Shift to return true in my KeyDown event handler. Pressing each one of those keys individually resulted in false being returned in my KeyUp event handler. Are you sure you're not handling the KeyUp event?

  2. As @sean woodward said, Windows键 should map to either Keys.LWin or Keys.RWin

  3. The KeyPress event is only raised when one of the character keys is pressed and will return the character that results from the pressed key or combination of pressed keys. Ctrl+Shift+B is not a character so you can't use KeyChar alone to get that information. Try using the KeyDown or KeyUp event and looking at the Modifiers property to get a comma delimited string of which modifier keys are being pressed. If order matters you'll need to track that as Modifiers always returns the keys in the same order, ie Shift, Control, Alt even if that's not how they were pressed.

Here is the code I used, you can try playing around with it:


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);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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