问题
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
andKeyUp
events of the form. (This is the way I was capturing Keyboard input before placing the buttons.) - 2) Overriding the Form's
OnKeyDown
andOnKeyUp
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