-1

I would like to check if a key sequence is press. Like a password, i would like that to see the message box you must type "bcqwl" in right sequenze. I tried

#include <iostream>

#include <windows.h>

using namespace std;

int main()
{
    while(true)
    {
        if(GetKeyState('B') & 0x8000)
        {
            cout<<"b has been press"<<endl;
               if(GetKeyState('C') & 0x8000)
               {
                   cout<<"c has been press"<<endl;
                   if(GetKeyState('Q') & 0x8000)
                   {
                       cout<<"Q has been press"<<endl;
                       if(GetKeyState('W') & 0x8000)
                       {
                           cout<<"W has been press"<<endl;
                           if(GetKeyState('L') & 0x8000)
                           {
                               MessageBox(NULL,"YES","YES",MB_OK);
                           }
                           else
                           {
                               continue;
                           }
                       }
                       else
                       {
                           continue;
                       }
                   }
                   else
                   {
                       continue;
                   }
               }
               else
               {
                    continue;
               }
        }
        else
        {
            continue;
        }
    }
}

But it doesn't works. He print "B has been press" ,many times but not infinitely times,if b is pressed. If after to press b I press c nothing happens. So i tired:

step:
        if(GetKeyState('B') & 0x8000)
        {
            cout<<"B has been press"<<endl;
            goto step1;
        }
        else
        {
            goto step;
        }
        step1:
        if(GetKeyState('C') & 0x8000)
        {
               MessageBox(NULL,"WORK","yes",MB_OK);
        }
        else
        {
            goto step;
        }

But doesn't work. I also tired:

#include <iostream>

#include <windows.h>

int main()
{
int progress = 0;
    while(progress<=4)
    {
        if(GetKeyState('B') & 0x8000)
        {
            std::cout<<"b has been press"<<std::endl;
            progress=1;
        }
        else
        {
            progress=0;
        }
        if(progress==1)
        {
            if(GetKeyState('C') & 0x8000)
            {
               std::cout<<"c has been press"<<std::endl;
                progress=2;
            }
            else
            {
                progress=0;
            }
        }
        if(progress==2)
        {
            if(GetKeyState('Q') & 0x8000)
            {
                std::cout<<"q has been press"<<std::endl;
                progress=3;
            }
            else
            {
                progress=0;
            }
        }
        if(progress==3)
        {
            if(GetKeyState('W') & 0x8000)
            {
                std::cout<<"w has been press"<<std::endl;
                progress=4;
            }
            else
            {
                progress=0;
            }
        }
        if(progress==4)
        {
            if(GetKeyState('L') & 0x8000)
            {
                std::cout<<"l has been press"<<std::endl;
                progress=5;
            }
            else
            {
                progress=0;
            }
        }

}
return 0;
}

But that output "b has been press" for many times but not infinitely if i press b, and after if i press c nothing is happening, praticaly after press b and the program go in if(process==1) but if i press c nothing happen

P.S. sorry for my bad english.

secon25
  • 70
  • 9

1 Answers1

2

The problem you are still having comes from the fact that you are in no way storing the progress in your key sequence.

Let's say your password is stored in a char array (for easier access to the single characters later on):

#define PWD_LEN 6 // bcqwl has a length of 5 characters but you need +1 for the '\0' (terminating character) at the end of your string
// ...
char password[PWD_LEN] = "bcqwl";

In addition you will need a counter:

#define PWD_LEN 5
// ...
char password[PWD_LEN] = "bcqwl";
int progress = 0;

while(true) { ... }

Both need to be stored before and outside the while loop because both store data that you don't want to reset in each iteration step in your loop.

The counter will be used to track the progress of the user towards completing the key sequence your password represents.

Whenever the user presses a key you will need to do the following checks:

  • Is the key allowed? - if you have a password abc but the user presses y or !, or something other then a, b or c the key is not allowed.
  • If the key is allowed take the character it represents and check if it's the same as the character in your password at index progress:

    if ( key allowed )
    {
      if (password[progress] == '<your key character here>')
      {
        ++progress;
      }
      else
      {
        // Handle incorrect key stroke relative to key sequence
      }
    }
    

Now in order to prevent the counter going bananas I would suggest doing all the checking upon key released, which unlike key pressed is a one time event. A key being pressed can also be part of key hold, in which case you will land in the else (from the code snippet above) many times, which might not be such a good idea.

If the key is ok and in terms of sequence it fits your password then you increase the progress so that in the next iteration step you can do the same check with a new released key event and a new index value for accessing your password array.

When your progress reaches the required value indicating that the key sequence is completed and that all the characters your password consists of have been "inserted" you can break the loop.

This is very basic so I hope that the instructions are clear enough for you to implement.


PREVIOUS ANSWER (now obsolete due to change in the question)

Unless other out-of-the-box way is available to do that (I haven't used GetKeyState() or anything else from windows.h) the general practice is to simply store the pressed state of each button (in an array, a struct etc.).

In your loop you can use a simple chain of if statements (but not nested like you do it!) to check which button is pressed during the current iteration step. Whenever a known key (one that you application wants to process) is pressed, you just need to toggle the respective state of that button in your array, struct or whatever other container you use to store this information:

while(true)
{
  // Check state of supported buttons
  if(GetKeyState('A') & 0x8000)
  {
    // store change of state of key A
  }
  if(GetKeyState('B') & 0x8000)
  {
    // store change of state of key B
  }
  if (...)
  {
    // ...
  }
}

At the end or beginning of your while's body you can then ask for the state of each button and also make combined queries:

while(true)
{
  // Check state of supported buttons
  if(GetKeyState('A') & 0x8000)
  {
    // store change of state of key A
  }
  if(GetKeyState('B') & 0x8000)
  {
    // store change of state of key B
  }
  if (...)
  {
    // ...
  }


  // Do something


  // Check for states of buttons
  // ...
}

For example let's say you are using the following structure to store the key's state:

typedef struct Key
{
  char keyCode;
  bool pressed;
} Key;

Key keyA;
keyA.pressed = false;

you can simply do

if (keyA.pressed)
{
  // Trigger some change that key 'A' controls
}

to check if your specific button is currently pressed and respectively trigger some action.

For key combinations things are not much different. You just need to use simply boolean logic to handle it:

if (keyA.pressed && keyB.pressed)
{
  // Both key 'A' and 'B' are pressed - we have a key combo!
}

You can improve the readability of your code by storing all supported buttons in an array and even adding a nice enum to provide easy access to each button:

enum KeyCode
{
  A,
  B,
  ...
};

 Key keys[n]; //with n being the number of keys you want to support and also the number of elements your enum has

// Access with an improved readability
if (keys[A].pressed && keys[B].pressed)
{
  // ...
}

If you can't find any code for GetKeyState() in particular (highly unlikely) you can look at SDL for example.

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161
  • thanks for answer, but I badly explained myself. I would like to do like a secret password, that for to see the MessageBox you must type "bcqwl" and this must type in sequence. I'll explain: if you type "bcqwl" you can to see the message box, but if you type "b" and after "a" you need to retype "b". Now i'll edit my answer and I'll explain it better. – secon25 May 14 '17 at 11:55
  • Yes, do that. Because what you wrote in your comment is something completely different. :D – rbaleksandar May 14 '17 at 12:20
  • Ok, i did it, can you help me now? – secon25 May 14 '17 at 12:37
  • i get error in: char password[PWD_LEN] = "bcqwl" the output is: initializer-string for array of chars is too long [-fpermissive]| – secon25 May 14 '17 at 13:55
  • I forgot the `\0` (terminating character) at the end. Will edit my answer. You need 5+1 (for the `\0`) characters for your password. But you only need to got through the first 5 characters (since these are the actual characters your password is made out of). – rbaleksandar May 14 '17 at 14:38
  • I read many times your answer but i still don't undestand how to type the password for straight. I would like that if users press b, and after he press something of different he must rewrite b. That is the problem. – secon25 May 14 '17 at 15:06
  • If you want to reset the project just recent the `progress` counter. You can place `progress = 0` inside the `else` statement where I wrote "Handle incorrect key stroke relative to key sequence". When you reset the counter, the user will have to start over. – rbaleksandar May 14 '17 at 15:09
  • I edit my quest and add one more code but doesn't work – secon25 May 14 '17 at 15:33
  • You `while` needs only to check if `progress` has reached a certain value. What I see in your edit is pseudo code with some other thing that I don't get why you've put in there. – rbaleksandar May 14 '17 at 15:35
  • I edit and i'm trying to use while(process<=4) but the problem is that after press b and the program go in if(process==1) but if i press c nothing happen. – secon25 May 14 '17 at 17:42
  • You may want to go for an `if ... else if ... else` or `switch`. With the `if` you can put reset of the counter in the `else` (the rest is a bunch of `if ... else if ...` statements for all the keys you need to support. With the `switch` you can place the resetting inside the `default` case. – rbaleksandar May 14 '17 at 18:12