简体   繁体   中英

Capture multiple key downs in C#

How can I capture multiple key downs in C# when working in a Windows Forms form?

I just can't seem to get both the up arrow and right arrow at the same time.

I think you'll be best off when you use the GetKeyboardState API function.

[DllImport ("user32.dll")]
public static extern int GetKeyboardState( byte[] keystate );


private void Form1_KeyDown(object sender, KeyEventArgs e)
{
   byte[] keys = new byte[256];

   GetKeyboardState (keys);

   if ((keys[(int)Keys.Up] & keys[(int)Keys.Right] & 128 ) == 128)
   {
       Console.WriteLine ("Up Arrow key and Right Arrow key down.");
   }
}

In the KeyDown event, you just ask for the 'state' of the keyboard. The GetKeyboardState will populate the byte array that you give, and every element in this array represents the state of a key.

You can access each keystate by using the numerical value of each virtual key code. When the byte for that key is set to 129 or 128, it means that the key is down (pressed). If the value for that key is 1 or 0, the key is up (not pressed). The value 1 is meant for toggled key state (for example, caps lock state).

For details see the Microsoft documentation for GetKeyboardState .

A little proof-of-concept code for you, assuming Form1 contains label1 :

private List<Keys> pressedKeys = new List<Keys>();

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    pressedKeys.Add(e.KeyCode);

    printPressedKeys();
}

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
    pressedKeys.Remove(e.KeyCode);

    printPressedKeys();
}

private void printPressedKeys()
{
    label1.Text = string.Empty;
    foreach (var key in pressedKeys)
    {
        label1.Text += key.ToString() + Environment.NewLine;
    }
}

With

Keyboard.IsKeyDown(Key.YourKey) 

you can handle multiple keydowns.

There is a managed library MouseKeyHook as NuGet which gives you a convenience managed wrapper. Source code on GitHub .

Recently support for detecting shortcuts, key combinations and sequences was added. Here is a usage example to deal with arrows:

Hook.AppEvents().OnCombination(new Dictionary<Combination, Action>
{
    {Combination.FromString("Left"), GoWest},
    {Combination.FromString("Left+Up"), GoNorthWest},
    {Combination.FromString("Up+Left"), GoNorthWest},
    {Combination.FromString("Up"), GoNorth},
    {Combination.FromString("Up+Right"), GoNorthEast},
    {Combination.FromString("Right+Up"), GoNorthEast},
});

For more information see: Detecting Key Combinations and Sequences

Hmm, are there separate events for each key down?

You can create four booleans for each arrow. When it is pressed, set the boolean of that arrow to true. If released is fired, set the boolean of that arrow to false.

Then you can check if the up and right boolean are true and then do your action.

Use SPY++ to see how key downs are fired. Basically if multiple arrow keys are held down at the same time the first key that was hit will fire events then when the second key is hit it will begin firing and you will no longer see events for the first one. When they are released you'll see their key up events. I would suggest you implement the bool flags suggested earlier its quick and simple.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM