简体   繁体   English

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

[英]Best way to implement keyboard shortcuts in a Windows Forms application?

I'm looking for a best way to implement common Windows keyboard shortcuts (for example Ctrl + F , Ctrl + N ) in my Windows Forms application in C#.我正在寻找一种在 C# 中的Windows 窗体应用程序中实现常见 Windows 键盘快捷键(例如Ctrl + FCtrl + N )的最佳方法。

The application has a main form which hosts many child forms (one at a time).该应用程序有一个主窗体,它承载许多子窗体(一次一个)。 When a user hits Ctrl + F , I'd like to show a custom search form.当用户点击Ctrl + F 时,我想显示一个自定义搜索表单。 The search form would depend on the current open child form in the application.搜索表单将取决于应用程序中当前打开的子表单。

I was thinking of using something like this in the ChildForm_KeyDown event:我想在ChildForm_KeyDown事件中使用这样的东西:

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

But this doesn't work.但这不起作用。 The event doesn't even fire when you press a key.当您按下某个键时,该事件甚至不会触发。 What is the solution?解决办法是什么?

You probably forgot to set the form's KeyPreview property to True.您可能忘记将表单的KeyPreview属性设置为 True。 Overriding the ProcessCmdKey() method is the generic solution:覆盖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);
}

On your Main form在您的主表单上

  1. Set KeyPreview to TrueKeyPreview设置为 True
  2. Add KeyDown event handler with the following code使用以下代码添加 KeyDown 事件处理程序

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

The best way is to use menu mnemonics, ie to have menu entries in your main form that get assigned the keyboard shortcut you want.最好的方法是使用菜单助记符,即在你的主窗体中有菜单条目,这些条目被分配了你想要的键盘快捷键。 Then everything else is handled internally and all you have to do is to implement the appropriate action that gets executed in the Click event handler of that menu entry.然后其他一切都在内部处理,您所要做的就是实现在该菜单项的Click事件处理程序中执行的适当操作。

You can even try this example:你甚至可以试试这个例子:

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...
}

If you have a menu then changing ShortcutKeys property of the ToolStripMenuItem should do the trick.如果您有菜单,那么更改ToolStripMenuItem ShortcutKeys属性应该可以解决问题。

If not, you could create one and set its visible property to false.如果没有,您可以创建一个并将其visible属性设置为 false。

From the main Form, you have to:在主表单中,您必须:

  • Be sure you set KeyPreview to true ( TRUE by default)确保将KeyPreview设置为true (默认为 TRUE)
  • Add MainForm_KeyDown (..) - by which you can set here any shortcuts you want.添加MainForm_KeyDown (..) - 通过它您可以在此处设置您想要的任何快捷方式。

Additionally,I have found this on google and I wanted to share this to those who are still searching for answers.此外,我在谷歌上找到了这个,我想分享给那些仍在寻找答案的人。 (for global) (全球)

I think you have to be using user32.dll我认为你必须使用 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
    }
}

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

Hans's answer could be made a little easier for someone new to this, so here is my version.对于刚接触这个的人来说,汉斯的回答可能会更容易一些,所以这是我的版本。

You do not need to fool with KeyPreview , leave it set to false .您不需要欺骗KeyPreview ,将其设置为false To use the code below, just paste it below your form1_load and run with F5 to see it work:要使用下面的代码,只需将其粘贴到您的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();
    }
}

在 WinForm 中,我们始终可以通过以下方式获取 Control Key 状态:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM