2011-11-06 202 views
2

拾取擊鍵組合的「正確/最佳」方法是什麼?有問題的鍵是Ctrl + Alt + Q,我希望用戶同時按下它們,在這一點上,我打開一個窗口。我目前正在做一個陣列,然後逐個捕獲每個擊鍵,但是我的結果並不一致,特別是在戴爾筆記本電腦/ Windows 7組合的特定組合上,但這是另一回事。拾取鍵擊Ctrl-Alt-Q

所以花了5分鐘的谷歌後,這只是一個粗略的版本後,看着msdn,但正如我前面說的是這個版本(未經測試)的正確/最好的方式做到這一點?

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)  
{ 
    const int WM_KEYDOWN = 0x100; 
    const int WM_SYSKEYDOWN = 0x104; 

    if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN)) 
    { 
     switch(keyData) 
     { 
      case Keys.Control | Keys.Alt | Keys.Q: 
      this.Parent.Text="<CTRL> + Alt + Q Captured"; 
      break; 
     }    
    } 

    return base.ProcessCmdKey(ref msg,keyData); 
} 

回答

6

忽略msg.Msg,只看看keyData。如果使用擊鍵,則返回true而不調用base。它簡化爲:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)  
{ 
    if (keyData == (Keys.Control | Keys.Alt | Keys.Q)) { 
     this.Parent.Text="<CTRL> + Alt + Q Captured"; 
     return true; 
    } 
    return base.ProcessCmdKey(ref msg,keyData); 
} 

這也許應該是形式的方法的重寫,所以你不依賴於具有聚焦的控制。你會使用this.Text來代替。

+0

謝謝,工作很好。 – flavour404

+0

哦,是的,它的形式,而不是控制。 – flavour404

1

是,那是,如果我想監聽按鍵事件全球我會怎麼做。

但是,如果你有興趣的鍵盤輸入,只有當你的程序是焦點窗口(在Windows的前面),您可能需要使用KeyDown事件:

private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) 
{ 
// your code goes here 
} 
+0

從KeyDown事件捕獲將不是好主意 –

1

根據System.Windows.Forms.Keys的文檔,您不能使用按位「或」來檢查組合鍵。該文檔指出:「爲了更好地控制,請使用在user32.dll中定義的Win32 API函數GetKeyState,GetAsyncKeyState或GetKeyboardState ...」。但似乎Shift,Alt和Control可以用作按位標誌。

+0

不,您正在引用Keys.ControlKey和Keys.Menu的值。 Keys.Control和Keys.Alt具有非常不同的值(0x20000,0x40000)。他們是位旗。您的答案是無緣無故地將用戶帶入一個兔子洞。 –

+0

謝謝漢斯,你救了我一些時間:) – flavour404

0

對於那些想要打開一個窗口或使用三個鍵(兩個修飾符)組合來顯示/隱藏的@Hans Passant,我終於找到了對我的問題的答案。我當時提防|操作數,而不是& &操作數不起作用。它可以被分配到Keydown的WFA屬性

private void ShowHidden_Click(object sender, KeyEventArgs e) 
    { 
     if (e.KeyData == (Keys.Control | Keys.Alt | Keys.M)) 
     { 
      OldBisProdId.Visible = true; 
      OldGanProdId.Visible = true; 
     } 
     if (e.KeyData == (Keys.Control | Keys.Alt | Keys.C)) 
     { 
      OldBisProdId.Visible = false; 
      OldGanProdId.Visible = false; 
     } 
    }