0

Wondering if you can detect something like whether 'A','C' and Backspace are pressed at the same time in Windows Forms. So far what I've seen is how to check for things like 'Ctrl'+ 'T' on stack exchange, which is specific to a 'control key' being pressed.

In general, I'm looking for a way to check whether any 3 keys on the keyboard were held down at the same time. This could be Ctrl+Alt+Del, or even W+A+S+D or Up+Home+Insert.

Ð..
  • 298
  • 5
  • 18
  • Use the KeyDown event and check if the other keys are pressed. Winforms is missing a method to make that easy, but that can [easily be added](https://stackoverflow.com/a/9356006/17034). You cannot do anything with Ctrl+Alt+Del, it is special. If you want to do WASD then you'd always consider simply using the KeyDown and KeyUp events to set the direction variables for the game loop. – Hans Passant Aug 31 '17 at 15:51

1 Answers1

1

This will create a dictionary to handle it. It seems to be working well through basic testing.

Dictionary<Keys, bool> keysDict;
public Form1()
{
    InitializeComponent();
    keysDict = new Dictionary<Keys, bool>();
    this.KeyDown += Form1_KeyDown;
    this.KeyUp += Form1_KeyUp;
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
    if (keysDict.ContainsKey(e.KeyCode))
    {
        keysDict[e.KeyCode] = false;
    }
}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (!keysDict.ContainsKey(e.KeyCode))
    {
        keysDict.Add(e.KeyCode, true);
    }
    else
    {
        keysDict[e.KeyCode] = true;
    }
    if (keysDict.ContainsKey(Keys.A) && keysDict[Keys.A] && keysDict.ContainsKey(Keys.W) && keysDict[Keys.W] && keysDict.ContainsKey(Keys.S) && keysDict[Keys.S] && keysDict.ContainsKey(Keys.D) && keysDict[Keys.D])
    {
        Console.WriteLine("WASD Pressed");
    }
}

Edit If you want to see what keys are in the dictionary, simply press them, and then add a breakpoint to check what it resolved to.

In your comment, you asked about TAB, ENTER, SHIFT, and something else I believe. So, for example, I pressed enter, ctrl, shift, alt, tab, then put in a breakpoint, and I got:

{[Return, False]}
{[ControlKey, False]}
{[ShiftKey, False]}
{[Menu, False]}
{[Tab, False]}

Don't worry about them being false - it's not removing them from the dictionary when you keyup, it just sets it false, so you maintain the actual keys it recorded. The above are all keyup because I didn't have a breakpoint until after I pressed them, so they are no longer pressed when I break.

Aaron
  • 1,313
  • 16
  • 26
  • What keys can be/would be added to the dictionary with this method? Hans Passant's comment made me wonder if say TAB or ENTER or CTRL would be added, or if it would just be the alphanumeric keys. – Ð.. Aug 31 '17 at 16:10
  • Any key pressed. It's a proof of concept - you can add logic to add/check whatever you want. This will maintain all keys pressed, but that's not an enormous memory issue, if that's your concern. Make sure you look at ControlKey, not a modifier key though. The intellisense will tell you which is a modifier and which is a key. For example, ControlKey is a key, Control is the Control modifier... So, you'll still need to handle modifiers if the keys themselves aren't sufficient. – Aaron Aug 31 '17 at 16:11
  • Just press and release a key you're looking for, then put in a breakpoint and check the dictionary. It will show you what keys it contains. – Aaron Aug 31 '17 at 16:16
  • So now I am interested in checking whether any 3 keys on the keyboard are pressed simultaneously, not whether a specific 3 were pressed. Is there a way to check whether any 3 pairs in the dictionary have value "true" in an efficient manner? Naively, I would be adding a for loop that goes through the dictionary and checks if there are 3 values that are "true". This seems rather expensive if it is run at every step in the program. – Ð.. Aug 31 '17 at 17:01
  • in the original answer, where it says "if (keysDict.ContainsKey(Keys.A) && keysDict[Keys.A] && keysDict.ContainsKey(Keys.W) && keysDict[Keys.W] && keysDict.ContainsKey(Keys.S) && keysDict[Keys.S] && keysDict.ContainsKey(Keys.D) && keysDict[Keys.D]) { Console.WriteLine("WASD Pressed"); }" ... there. Since it's a boolean, keysDict[Keys.A] will only be true if it's pressed. Check for ContainsKey first to avoid errors if one of the wanted keys isn't pressed yet. – Aaron Aug 31 '17 at 17:02
  • for clarity, keysDict[Keys.A] is equal to "keysDict[Keys.A] == true" because it's a boolean value. – Aaron Aug 31 '17 at 17:04