Acidic
Acidic

Reputation: 6280

Preventing Focus-able Controls from stealing Keyboard Input

I'm currently working on a simple game that is drawn on a form by overriding the OnPaint method. The game requires Keyboard input and was working perfectly until I decided to enhance the GUI and add a few Buttons to the form.

The moment I added these Buttons, the form stopped receiving any Keyboard input, no matter how hard I tried the focus was always on the buttons. This behavior can be replicated by placing any Focus-able Control on the form. (ie. TextBox)

I don't need ANY Kayboard interaction with these buttons, I want the user to interact with them with the mouse only.

I've tried the following techniques to try and get around this problem - none of these worked:

I also tried create a MessageFilter for the application, but I couldn't force it to capture only the Keyboard keys that I needed.

I've been looking into this for many hours already and can't find a suitable solution. Help would be greatly appreciated.

Upvotes: 1

Views: 2978

Answers (2)

Jules
Jules

Reputation: 6346

Set the KeyPreview property of the form to True, and then set event.Handled = True when you handle KeyDown/KeyUp. This will ensure that the form gets a chance to handle events before its children. Because you set the handled property to true, the childen won't see the keyboard events.

More info here: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx

Upvotes: 2

João Angelo
João Angelo

Reputation: 57718

Here is a sample form with a IMessageFilter for the up and down arrow keys, hope this helps:

public partial class MainForm : Form
{
    private class MessageFilter : IMessageFilter
    {
        public MainForm Main { get; set; }
        public bool PreFilterMessage(ref Message msg)
        {
            const int WM_KEYDOWN = 0x100;
            const int WM_KEYUP = 0x101;
            if (msg.Msg == WM_KEYDOWN)
            {
                var keyData = (Keys)msg.WParam;
                if (keyData == Keys.Down || keyData == Keys.Up)
                {
                    return true; // Process keys before return
                }
            }
            else if (msg.Msg == WM_KEYUP)
            {
                var keyData = (Keys)msg.WParam;
                if (keyData == Keys.Down || keyData == Keys.Up)
                {
                    return true; // Process keys before return
                }
            }
            return false;
        }
    }
    public MainForm()
    {
        this.InitializeComponent();
        Application.AddMessageFilter(new MessageFilter { Main = this });
    }
}

For a list of possible Windows messages check:

List Of Windows Messages

Upvotes: 5

Related Questions