views:

608

answers:

2

I am building an application where all the key input must be handled by the windows itself.

I set tabstop to false for each control witch could grab the focus except a panel (but I don't know if it has effect).

I set KeyPreview to true and I am handling the KeyDown event on this form.

My problem is that sometimes the arrow key aren't responsive anymore:

  • The keydown event is not fired when I pressed only an arrow key.

  • The keydown event is fired if I press an arrow key with the control modifier.

Have you an idea why my arrow key suddenly stop firing event?

+4  A: 

Derive from a control class and you can override the ProcessCmdKey method. Microsoft chose to omit these keys from KeyDown events because they affect multiple controls and move the focus, but this makes it very difficult to make an app react to these keys in any other way.

Snarfblam
It seems that ProcessCmdKey is the only way to handle the keyboard accurately.Thanks!
tinmaru
A: 

Unfortunately, it is quite difficult to accomplish this with the arrow keys, due to restrictions in KeyDown events. However, there are a few ways to get around this:

  • As @Snarfblam stated, you can override the ProcessCmdKey method, which retains the ability to parse arrow key presses.
  • As the accepted answer from this question states, XNA has a built-in method called Keyboard.GetState(), which allows you to use arrow key inputs. However, WinForms doesn't have this, but it can be done through a P/Invoke, or by using a class that helps with it.

I recommend trying to use that class. It's quite simple to do so:

var left = KeyboardInfo.GetKeyState(Keys.Left);
var right = KeyboardInfo.GetKeyState(Keys.Right);
var up = KeyboardInfo.GetKeyState(Keys.Up);
var down = KeyboardInfo.GetKeyState(Keys.Down);

if (left.IsPressed)
{
//do something...
}

//etc...

If you use this in combination with the KeyDown event, I think you can reliably accomplish your goal.

Maxim Zaslavsky