2013-02-17 8 views
2

Я пытаюсь создать «кейлоггер» ... ну, это не совсем кейлоггер, потому что он отображает только нажатия клавиш и не записывает их в файл. Я планировал использовать его в своих Hangouts в Google+, поэтому я могу показать свои нажатия клавиш, не используя его с программным обеспечением для записи видео.Обработка событий KeyDown и KeyPress в C#

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, для которого я сделал каждый один значок. boxCtrl, boxAlt, boxWin и boxShift также PictureBox эс вполне очевидны]

Вопросы:.

  1. кажется, что значения e.Control, e.Alt и e.Shift всегда Ложные, поэтому соответствующие PictureBox es не появятся.

  2. Как я могу проверить статус ключа Win? Я бы предпочел не использовать низкоуровневые константы VK_*.

  3. Когда OnKeyPress обрабатывает события, в основном с использованием клавиш-модификаторов, я получаю случайные символы ... Как именно я получаю исходные штрихи от них? то есть я хочу получить Ctrl+Shift+B вместо .


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; 

    // ... 
} 

Хорошая новость заключается в том, что я получил Ctrl, Win и Shift ключи рабочие, но не Alt; если AltLMenu и RMenu. Что дает?

+0

насчет сравнения против собственности e.Modifiers с помощью клавиш, http://msdn.microsoft.com/ ан-нас/библиотека/system.windows.forms.keys.aspx? См. LWin и RWin для ключа Windows. –

+1

Нажатие клавиши «Alt» на моей клавиатуре приводит к значению 'KeyCode'' Keys.Menu' в моем обработчике. Кажется, он не проводит различия между левым и правым. К сожалению, у меня нет другой клавиатуры для тестирования. – gowansg

+0

@gowansg Odd ... Клавиши 'LMenu' и' RMenu' должны проверять клавиши 'Alt' с обеих сторон, но кажется, что работает только' Keys.Menu'. Благодаря ~ –

ответ

1
  1. Нажатие Ctrl, Alt или Сдвиг индивидуально вызвал Control, Alt и Shift вернуть true в мой обработчик KeyDown событий. Нажатие каждой из этих клавиш индивидуально приводило к возврату false в обработчик события KeyUp. Вы уверены, что не работаете с событием KeyUp?

  2. Как сказал @sean лесничий, Windows Key должно отображаться либо Keys.LWin или Keys.RWin

  3. KeyPress событие возникает только тогда, когда один из ключей символов нажимается и возвращает символ, который возникает в результате отжатый клавиши или комбинации нажатых клавиш. Ctrl+Shift+B не является персонажем, поэтому вы не можете использовать только KeyChar, чтобы получить эту информацию.Попробуйте использовать событие KeyDown или KeyUp и посмотрите на свойство 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); 
}; 
Смежные вопросы