2011-11-06 79 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; 
     } 
    }