Thread: need help for reading two keyboard inputs

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    33

    need help for reading two keyboard inputs

    I have the following code and was wandering if someone could help me in telling me how i could make the program read 2 inputs such as: 87 and 68 ('w' and 'd') instead of reading just one input at a time. In otherwords.. how could i get into the: if (check == 68) code area.

    Code:
            private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                int num = e.KeyValue;
                string w = Convert.ToString(num);
                label1.Text = w;
                switch (num)
                {
                    case 87:
                        while (num == 87)
                        {
                            label4.Text = "check 1";
                            int check = e.KeyValue;
    
                            if (check == 68)
                            {
                                label4.Text = "Works";
                            }
                            else
                            {
                                break;
                            }
                        }
                }
            }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    So why not use character constants instead of literal numbers?
    if ( check == 'd' )
    is SO much more readable.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You cannot read two inputs at a time. Windows does not work that way.

    What you can do is check to see if ALT, CTRL, or any other special key is down at the time of the keypress. Windows only sends key messages to your window on a per key basis. So if the user presses 'W' it sends a message to your window. If you override DefWndProc you can receive this message prior to the child controls of the window. If not then the control which has the focus gets sent the message.

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    33
    Hmm, ok
    Thx.

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    What you can do is create an array the keeps track of which keys are pressed and which are not.

    So on key up and key down, toggle that bit.

    c++ example:

    Code:
    char keysPressed[256] = { 0 };
    
    onKeyDown
    {
       keysPressed[key] = 1;
    }
    
    onKeyUp
    {
       keysPressed[key] = 0;
    }
    By doing this, when you check if cntrl is being pressed, you can check if the specific key you are looking for is already been triggered. If you only need to watch one combo, just keep a single bool that marks whether or not that key is down.

    Hope this helps, let me know if you have any other questions.

  6. #6
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    One problem with the above code is that nothing in the C# standard specifically guarantees that the KeyValue will be less than 256, so you'll need to do bounds checking on your KeyValue or you could potentially have a buffer overrun. The array (or a similar option, such as a Dictionary<int, bool> ) is the simplest method.

    However, you could also use the WinAPI GetAsynchKeyState() but you'll need to do some tricks to run that from managed code. See here
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  7. #7
    Registered User
    Join Date
    Aug 2007
    Posts
    33
    If I was to go with arrays how would the program know if the user intended to press a different key instead of pressing two keys... What im saying is that since c# can only read 1 input at a time, if i was to press 2 keys, it would detect the first key pressed and then change it to key up and the second key down... how would an array help me there?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Diablo02 View Post
    If I was to go with arrays how would the program know if the user intended to press a different key instead of pressing two keys... What im saying is that since c# can only read 1 input at a time, if i was to press 2 keys, it would detect the first key pressed and then change it to key up and the second key down... how would an array help me there?
    Let's first explain one thing: If you press a key on the keyboard, one out of the 8 bits of keyboard data will indicate that the key was "down". When the key is released, it will send the same information, but with a "keyup" bit.

    If you press "two keys at once", say A and B, the keyboard will first send "A" DOWN, then "B" DOWN. If you then release B, the keyboard will send "B" UP. If you then press "C", it will send "C" DOWN. Release both C and A at the same time, and will send "A" UP, "C" UP [or the other way around, but it will send one before the other].

    The same thing applies for ALL keys. CTRL, SHIFT, ALT, Window-key, Delete, Home, F1, A, B, ... Z, etc, etc, etc.

    The OS keeps track of for example CTRL, SHIFT, etc. in a bitmask [similar to an array of bool] that indicates which ones are "currently down".

    Edit: So, as a summary: The suggested solution with a "keymap" will work very well if you keep track of key-down and key-up events for any keys you are interested in, and you can detect W and B being held down at the same time, for example.

    --
    Mats
    Last edited by matsp; 12-05-2007 at 03:47 PM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    Quote Originally Posted by Cat View Post
    One problem with the above code is that nothing in the C# standard specifically guarantees that the KeyValue will be less than 256, so you'll need to do bounds checking on your KeyValue or you could potentially have a buffer overrun. The array (or a similar option, such as a Dictionary<int, bool> ) is the simplest method.

    However, you could also use the WinAPI GetAsynchKeyState() but you'll need to do some tricks to run that from managed code. See here
    Not everything needs to be 'copy and paste'-able to get a point across. But I guess instead of picking a random number, [max keys] would have been a bit more clear.

  10. #10
    Registered User
    Join Date
    Aug 2007
    Posts
    33
    hmm, i see what you mean now... So basically have an array '0' for key up and '1' for key down to act as a bool right? So if key A is pressed -'1'- and key W are pressed -'1'-, I should then have a check statement to see if '1' is currently triggered.. rite?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Diablo02 View Post
    hmm, i see what you mean now... So basically have an array '0' for key up and '1' for key down to act as a bool right? So if key A is pressed -'1'- and key W are pressed -'1'-, I should then have a check statement to see if '1' is currently triggered.. rite?
    Yes.

    To check if A is down at the same time as W, you take your "keydown code", and set the current keystate to 1. If it's either "A" or "W" then you check if BOTH of those are down, then that's it, both are down. If it's neither A or W that was pressed right now, it's obviously not changing the state of A or W, so it's no need to check if A and W are both 1.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Dec 2005
    Posts
    54
    Quote Originally Posted by Diablo02 View Post
    hmm, i see what you mean now... So basically have an array '0' for key up and '1' for key down to act as a bool right? So if key A is pressed -'1'- and key W are pressed -'1'-, I should then have a check statement to see if '1' is currently triggered.. rite?
    Yup, you got it.

    Example:

    Code:
    void OnKeyDown(eventargs e..)
    {
       keylog[e.keychar] = 1;
    
       // do special checks here..
       if(keylog['c'] && keylog['d])
         //  COMBO
    }
    
    void OnKeyUp(eventargs e...)
    {
       keylog[e.keychar] = 0;
    }
    Please keep in mind, this is not usable code, just trying to make an example.

  13. #13
    Registered User
    Join Date
    Aug 2007
    Posts
    33
    Thx for the help guys, ill try to implement this to my program and if I run into errors ... i'll let u know
    Thx very much!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Detecting keyboard and mouse in linux
    By sameer.nalwade in forum C Programming
    Replies: 3
    Last Post: 11-22-2008, 04:24 AM
  2. Keyboard Inputs
    By andreas_himself in forum C Programming
    Replies: 17
    Last Post: 08-15-2008, 10:35 PM
  3. Keyboard port using other that a keyboard
    By antoinelac in forum C++ Programming
    Replies: 4
    Last Post: 06-12-2008, 02:46 PM
  4. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  5. Child window cant receive keyboard inputs
    By Raison in forum Windows Programming
    Replies: 2
    Last Post: 11-21-2004, 09:46 AM