2013-02-17 152 views
2

我試圖製作一個「鍵盤記錄器」......好吧,它不完全是一個鍵盤記錄程序,因爲它只顯示擊鍵並且不會將它們記錄到文件中。我打算在我的Google+環聊中使用它,所以我仍然可以在不用視頻錄製軟件的情況下顯示我的按鍵。在C#中處理KeyDown和KeyPress事件#

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,我已完成針對每一個圖標的PictureBoxboxCtrlboxAltboxWinboxShiftPictureBox ES是相當不言自明]

問題:

  1. 看來的e.Controle.Alte.Shift值始終是假的,所以相應的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; 

    // ... 
} 

的好消息是,我得到了Ctrl,WinShift鍵工作,但不是Alt;除非AltLMenuRMenu。是什麼賦予了?

+0

怎麼樣使用密鑰對e.Modifiers財產比較,http://msdn.microsoft.com/ EN-US /庫/ system.windows.forms.keys.aspx?請參閱LWin和RWin以獲取Windows鍵。 – 2013-02-17 02:55:01

+1

在我的鍵盤上按下'Alt'鍵會在我的處理程序中產生'Keys.Menu'的'KeyCode'值。它似乎沒有區分左側和右側。不幸的是,我沒有其他鍵盤可以測試。 – gowansg 2013-02-17 18:24:43

+0

@gowansg奇怪的......'LMenu'和'RMenu'鍵應該檢查兩側的Alt鍵,但似乎只是'Keys.Menu'工作。謝謝〜 – 2013-02-17 19:18:55

回答

1
  1. 按下Ctrl鍵Alt鍵,或單獨引起ControlAltShift在我KeyDown事件處理程序返回true。單獨按下這些鍵中的每一個導致在我的KeyUp事件處理程序中返回false。你確定你沒有處理KeyUp事件嗎?

  2. 正如@sean伍德沃德表示,Windows Key應該映射到任何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); 
};