Preventing Focus-able Controls from stealing Keyboard Input

北城余情 提交于 2020-01-16 03:25:08

问题


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:

  • 1) Normal KeyDown and KeyUp events of the form. (This is the way I was capturing Keyboard input before placing the buttons.)
  • 2) Overriding the Form's OnKeyDown and OnKeyUp events.
  • 3) Overriding ProcessCmdKey - Works, but cannot differentiate between KeyUp and KeyDown events, so it is inadequate for me.

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.


回答1:


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




回答2:


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



来源:https://stackoverflow.com/questions/8256914/preventing-focus-able-controls-from-stealing-keyboard-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!