Question

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

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

   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?

Was it helpful?

Solution

You probably forgot to set the form's KeyPreview property to True. Overriding the ProcessCmdKey() method is the generic solution:

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);
}

OTHER TIPS

On your Main form

  1. Set KeyPreview to True
  2. Add KeyDown event handler with the following code

    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, i.e. 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.

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.

If not, you could create one and set its visible property to false.

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. To use the code below, just paste it below your form1_load and run with F5 to see it work:

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();
    }
}

From the main Form, you have to:

  • Be sure you set KeyPreview to true( TRUE by default)
  • Add MainForm_KeyDown(..) - by which you can set here any shortcuts you want.

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

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/

In WinForm, we can always get the Control Key status by:

bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;
private void buttonCheck_Click_1(object sender, EventArgs e)
{
    bool jeElement = false;

    for (int i = 0; i < listBox1.Items.Count; i++)
    {
        if (textBox1.Text == listBox1.Items[i].ToString())
        {
            jeElement = true;
            break;
        }
    }

    if (jeElement)
    {
        label1.Text = "je element";
    }
    else
    {
        label1.Text = "ni element";
    }
    textBox1.ResetText();
    textBox1.Focus();
}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Alt == true && e.KeyCode == Keys.A)
    {
        buttonCheck.PerformClick();
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    if (radioButtonF.Checked)
    {
        progressBar1.Value++;
    }
    else
    {
        progressBar1.Value--;
    }

    if (progressBar1.Value == progressBar1.Maximum)
    {
        timer1.Stop();
        label1.Text = "End";
    }

    if (progressBar1.Value == progressBar1.Minimum)
    {
        timer1.Stop();
        label1.Text = "Begining";
    }
}

private void radioButtonF_CheckedChanged(object sender, EventArgs e)
{
    timer1.Start();
    progressBar1.Value = 0;
    progressBar1.Maximum = 100;
}

private void radioButtonB_CheckedChanged(object sender, EventArgs e)
{
    timer1.Start();
    progressBar1.Value = 100;
    progressBar1.Minimum = 0;
}

please don't delete this comment

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if(e.Alt == true && e.KeyCode == Keys.A)
    {
        button1ADD.PerformClick();
    }

    if(e.Alt == true && e.KeyCode == Keys.D)
    {
        button2DeleteaaLL.PerformClick();
    }

    if(e.Alt == true && e.KeyCode == Keys.S)
    {
        Deleteselectedbtn.PerformClick();
    }

    if(e.Alt == true && e.KeyCode == Keys.C)
    {
        button4Close.PerformClick();
    }
}

private void Form1_Shown(object sender, EventArgs e)
{
    txtInput.Focus();
}

private void button1ADD_Click(object sender, EventArgs e)
{
    if(!string.IsNullOrEmpty(txtInput.Text))
    {
        Listmylist.Items.Add(txtInput.Text);
        txtInput.Clear();
        txtInput.Focus();
    }
}

private void button2DeleteaaLL_Click(object sender, EventArgs e)
{
    Listmylist.Items.Clear();
    txtInput.Focus();
}

private void Deleteselectedbtn_Click(object sender, EventArgs e)
{
    Listmylist.Items.RemoveAt(Listmylist.SelectedIndex);
    txtInput.Focus();
}

private void button4Close_Click(object sender, EventArgs e)
{
    Application.Exit();
}

private void txtInput_TextChanged(object sender, EventArgs e)
{
    button1ADD.Enabled = true;
}
private void button1_Click(object sender, EventArgs e)
{
    if (button2.Enabled == false)
    {
        timer1.Stop();
        button2.Enabled = true;
        label1.Text = "Preteklo je " + progressBar1.Value + " desetink";

    }
    else
    {
        timer1.Start();
        button1.Enabled = false;
        progressBar1.Value = 0;
        label1.Text = "";
    }
}

private void button2_Click(object sender, EventArgs e)
{
    if (button1.Enabled == false)
    {
        timer1.Stop();
        button1.Enabled = true;
        label1.Text = "Preteklo je " + progressBar1.Value + " desetink";
    }
    else
    {
        timer1.Start();
        button2.Enabled = false;
        progressBar1.Value = 0;
        label1.Text = "";
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    if (progressBar1.Value < progressBar1.Maximum)
    {
        progressBar1.Value++;
        if (progressBar1.Value == progressBar1.Maximum)
        {
            timer1.Stop();
            button2.Enabled = true;
            button1.Enabled = true;
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top