簡體   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