[win32] - how build a combinekeys() function?

Pages: 12
Jul 28, 2014 at 6:03pm
the AreAllKeysPressed() is for detecte if the user pressed that vector of keys(all keys) in same time. but theres more 2 variables that i must keep in mind:
1 - the user can't immediatly press the 2 or 3 keys in same time;
2 - i'm using the key down message. and that can be a problem too.. because, the AreAllKeysPressed() can be called again with a diferent vector of keys.
i understand what you mean and maybe you understand me too.
i will trying fix these problem ;)
Jul 28, 2014 at 10:38pm
Problem #2 is because you have a non-modular design. IE: you are using globals (or rather, statics). This is exactly why you should avoid doing things this way.

A more modular approach to this problem would be to keep a history of keys pressed. Currently, you are not doing this... you are only looking at the current state of the keys and looking to see if that state matches part of the given pattern. Instead, you could keep track of the key state in some kind of circular buffer (you could probably used a deque)

Problem #1 is trickier. You'll have to allow some time between key presses. IE, if another key is pressed (and being held down) within X ms of another key being pressed, then treat it as if the user pressed both at the same time. This is easier to do if you have a deque with the key history.



Do you really need the entire keyboard? This would be much easier if you restricted controls to a handful of keys. I'm assuming this is for a game. I can't imagine why any game (or really... any program) would need to monitor complex key patterns for more than 16 or so keys.
Jul 29, 2014 at 7:55am
but if i just do:
1
2
if(CombinationKeys({'A'},{'W'},{'R'}, {'O'})==true)
            MessageBox(NULL,"hi", "hello",MB_OK);

(i'm using the macro)
works perfectly, because just test 1 key at a time.
maybe in time i can do these ;)
Jul 31, 2014 at 12:15pm
cool.. now works with several keys ;)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//test if a key\combination keys is pressed
bool AreAllKeysPressed(const std::vector<int> &keys)
{
    int state = 0x8000;
    for (int key : keys)
    {
        state &= GetAsyncKeyState(key);

    }
    return (state) != 0;
}

bool CombineKeys(std::vector<std::vector<int>> const &keys)
{
    static bool PreviousKeyPressed=false;
    static DWORD StartTimer = GetTickCount();
    static DWORD AllKeysTimer = 0;
    static int i=0;

        //test if the 1st key was pressed
        if((AreAllKeysPressed(keys[0])==true) && PreviousKeyPressed==false)
        {
            i=0;
            PreviousKeyPressed=true;
            StartTimer = GetTickCount();
            AllKeysTimer=0;
            i++;
        }
        //if the last combination have only 1 key
        else if((i==(int)keys.size()-1) && (AreAllKeysPressed(keys[(int)keys.size()-1])==true) && PreviousKeyPressed==true && keys[(int)keys.size()-1].size()==1)
        {
            PreviousKeyPressed=false;
                StartTimer = 0;
                AllKeysTimer=0;
                i=0;
                return true;
        }
        //testing if the keys are pressed in same time
        //but you only have 1 second for that
        else if(GetTickCount() - AllKeysTimer <= 500 && PreviousKeyPressed==true)
        {
            if(AreAllKeysPressed(keys[i])==true && i!=(int)keys.size()-1)
            {
                PreviousKeyPressed=true;
                StartTimer = GetTickCount();
                AllKeysTimer=0;
                i++;
            }
            else if(AreAllKeysPressed(keys[(int)keys.size()-1])==true && i==(int)keys.size()-1)
            {
                PreviousKeyPressed=false;
                StartTimer = 0;
                AllKeysTimer=0;
                i=0;
                return true;
            }
        }
        //test if the StartTimer have 2 seconds
        else if ((GetTickCount() - StartTimer >= 2000))//now i put the timer here ;)
        {
            StartTimer =0;
            AllKeysTimer=0;
            PreviousKeyPressed=false;
            i=0;
        }
        //test if the last key was pressed
        else if((i==(int)keys.size()-1) && (AreAllKeysPressed(keys[(int)keys.size()-1])==true) && PreviousKeyPressed==true)
        {
            StartTimer=0;
            AllKeysTimer=GetTickCount();
        }
        //test if the next key was pressed
        else if((AreAllKeysPressed(keys[i])==true) && PreviousKeyPressed==true)
        {
            PreviousKeyPressed=true;
            StartTimer = GetTickCount();
            AllKeysTimer=0;
            i++;
        }
        else if((AreAllKeysPressed(keys[i])==false) && PreviousKeyPressed==true)
        {
            AllKeysTimer=GetTickCount();
        }

        else
        {
            PreviousKeyPressed=false;
            StartTimer = GetTickCount();
            AllKeysTimer=0;
            i=0;
        }

    return false;
}

#define CombinationKeys(...) CombineKeys({__VA_ARGS__}) 

heres 1 sample:
1
2
if(CombinationKeys({'A','S'},{'W'},{'R','T'}, {'O','P'})==true)
            MessageBox(NULL,"hi", "hello",MB_OK);

i hope the readers enjoy ;)
Jul 31, 2014 at 12:16pm
Disch thanks for all... thank you
Topic archived. No new replies allowed.
Pages: 12