在Windows窗体应用程序中实现键盘快捷键的最佳方法?

我正在寻找一个最好的方法来实现常见的Windows键盘快捷键(例如Ctrl+FCtrl+N)在我的Windows窗体应用程序在c#。

应用程序有一个主表单,它承载许多子表单(一次一个)。当用户点击Ctrl+F时,我想显示一个自定义搜索表单。搜索表单将依赖于应用程序中当前打开的子表单。

我在考虑在ChildForm_KeyDown事件中使用这样的东西:

   if (e.KeyCode == Keys.F && Control.ModifierKeys == Keys.Control)
// Show search form

但这行不通。当你按下一个键时,事件甚至不会触发。解决方案是什么?

243943 次浏览

最好的方法是使用菜单助记符,也就是说,在主窗体中为菜单项分配你想要的键盘快捷键。然后其他所有事情都在内部处理,你所要做的就是实现在该菜单项的Click事件处理程序中执行的适当操作。

你可能忘记了将表单的KeyPreview属性设置为True。覆盖ProcessCmdKey ()方法是通用的解决方案:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == (Keys.Control | Keys.F)) {
MessageBox.Show("What the Ctrl+F?");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}

如果你有一个菜单,那么改变ToolStripMenuItemShortcutKeys属性就可以了。

如果不是,你可以创建一个并将其visible属性设置为false。

在主窗体上

  1. KeyPreview设置为True
  2. 使用以下代码添加KeyDown事件处理程序

    private void MainForm_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.Control && e.KeyCode == Keys.N)
    {
    SearchForm searchForm = new SearchForm();
    searchForm.Show();
    }
    }
    

汉斯的回答可以让一个新的人更容易一点,所以这是我的版本。

你不需要愚弄KeyPreview,让它设置为false。要使用下面的代码,只需将它粘贴到你的form1_load下面,并使用F5运行,看看它是否工作:

protected override void OnKeyPress(KeyPressEventArgs ex)
{
string xo = ex.KeyChar.ToString();


if (xo == "q") //You pressed "q" key on the keyboard
{
Form2 f2 = new Form2();
f2.Show();
}
}

你甚至可以试试这个例子:

public class MDIParent : System.Windows.Forms.Form
{
public bool NextTab()
{
// some code
}


public bool PreviousTab()
{
// some code
}


protected override bool ProcessCmdKey(ref Message message, Keys keys)
{
switch (keys)
{
case Keys.Control | Keys.Tab:
{
NextTab();
return true;
}
case Keys.Control | Keys.Shift | Keys.Tab:
{
PreviousTab();
return true;
}
}
return base.ProcessCmdKey(ref message, keys);
}
}


public class mySecondForm : System.Windows.Forms.Form
{
// some code...
}

从主窗体,你必须:

  • 确保将KeyPreview设置为真正的(默认为TRUE)
  • 添加MainForm_KeyDown(..) -通过它你可以在这里设置任何你想要的快捷方式。

此外,我在谷歌上找到了这个,我想把它分享给那些仍在寻找答案的人。(全球)

我认为你必须使用user32.dll

protected override void WndProc(ref Message m)
{
base.WndProc(ref m);


if (m.Msg == 0x0312)
{
/* Note that the three lines below are not needed if you only want to register one hotkey.
* The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */


Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);                  // The key of the hotkey that was pressed.
KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);       // The modifier of the hotkey that was pressed.
int id = m.WParam.ToInt32();                                        // The id of the hotkey that was pressed.




MessageBox.Show("Hotkey has been pressed!");
// do something
}
}

进一步阅读http://www.fluxbytes.com/csharp/how-to-register-a-global-hotkey-for-your-application-in-c/

在WinForm中,我们总是可以通过以下方式获得Control Key的状态:

bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;

VB。汉斯的答案。的NET版本

(Visual Studio中有一个ProcessCmdKey函数模板。)

  Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean


If (keyData = (Keys.Control Or Keys.F)) Then
' call your sub here, like
SearchDialog()
Return True
End If


Return MyBase.ProcessCmdKey(msg, keyData)
End Function


End Class