8

How to catch keyboard events of the WinForm main form, where other controls are. So I want to catch one event Ctrl + S and doesn't matter where focus is. But without Pinvoke (hooks and such ...) Only .NET managed internal power.

Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • 1
    possible duplicate of [Best way to implement keyboard shortcuts in winforms?](http://stackoverflow.com/questions/400113/best-way-to-implement-keyboard-shortcuts-in-winforms) – Hans Passant Jul 14 '11 at 17:27

4 Answers4

12

the Form Class (System.Windows.Forms) has OnKeyDown, OnKeyPress, and OnKeyUp event methods that you can use to detect Ctrl + S

use the KeyEventArgs in those methods to determine which keys were pressed

EDIT

be sure to enable Form.KeyPreview = true; so the form will capture the events regardless of focus.

MikeM
  • 27,227
  • 4
  • 64
  • 80
11

Try this code. Use the interface IMessageFilter you can filter any ctrl+key.

public partial class Form1 : 
    Form,
    IMessageFilter
{
    public Form1()
    {
        InitializeComponent();

        Application.AddMessageFilter(this);
        this.FormClosed += new FormClosedEventHandler(this.Form1_FormClosed);
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        Application.RemoveMessageFilter(this);
    }

    public bool PreFilterMessage(ref Message m)
    {
        //here you can specify  which key you need to filter

        if (m.Msg == 0x0100 && (Keys)m.WParam.ToInt32() == Keys.S &&
            ModifierKeys == Keys.Control) 
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

I tested this and worked for me.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Asish AP
  • 4,421
  • 2
  • 28
  • 50
1

Handle the KeyDown on the form and all its controls.

private void OnFormLoad(object sender, EventArgs e)
{
    this.KeyDown += OnKeyDown;
    foreach (Control control in this.Controls)
    {
        control.KeyDown += OnKeyDown;
    }
}

private void OnKeyDown(object sender, KeyEventArgs e)
{
    if (e.Control)
    {
        if (e.KeyValue == (int)Keys.S)
        {
            Console.WriteLine("ctrl + s");
        }
    }
}
Jalal Said
  • 15,906
  • 7
  • 45
  • 68
  • Did you read: "So I want to catch one event Ctrl + S and doesn't matter where focus is". Please, read carefully. –  Jul 14 '11 at 17:32
  • @Robb: Yes I read that, but I assumed that the phase `doesn't matter where focus is` referring to the inside the form or its controls so no matter if the focus where on for example a `textBox1` or in the form. isn't that you meant? – Jalal Said Jul 14 '11 at 17:39
  • @Robb: did you notice the question on my previous comment? – Jalal Said Jul 14 '11 at 17:50
  • Jalal, yas I meant that... but if this question is only about KeyDown event, then I wouldn't ask. I used to apply P/Invoke Keyboard hook Proc before, and Asish's answer was exectly what I was looking for. –  Jul 14 '11 at 21:37
1

You may add a MenuStrip and then create a menu strip item named save and give it a short cut Ctrl + S. Add a event handler for that. This will fire even if the focus is on other control on the form. If you don't like to see the MenuStrip; you can set visible = false too. I must admit this is ugly.

Shuhel Ahmed
  • 963
  • 8
  • 14