2017-05-14 16 views
-1

キーシーケンスがプレスかどうか確認したいと思います。パスワードのように、正しい順序で "bcqwl"と入力する必要があるメッセージボックスを表示したいと思います。試しましたキーシーケンスがプレスかどうかを確認する方法は?

#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; 
     } 
    } 
} 

しかし、動作しません。 bを押すと、「Bは押されました」と印刷されますが、無限に何回も繰り返されます。 bの後に押すと、cを押すと何も起こりません。 だから私は疲れました:

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; 
     } 

しかし、動作しません。 私も疲れ:

#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; 
} 

しかし、その出力は、私はBを押すと、と私はCを押すと何もpraticalyプレスbとプログラム行く後、起こっていないされた後に無限に多くの時間のための「bがプレスされている」ではなくif(process==1)にありますが、私がcを押しても何も起こらない場合

PS私の悪い英語のために申し訳ありません。

+0

私は自分の答えを更新しました。 – rbaleksandar

+0

[namespace stdを使うのは悪い考えです](http://stackoverflow.com/q/1452721/995714)、特に '#include 'では 'min'と' max'が両方とも定義されているので非常に悪いです –

+0

Ok情報をありがとう、私は私のプログラムが動作するときに修正するつもりです。 – secon25

答えて

2

問題は、キーシーケンスの進捗状況を保存していないという事実から来ています。

のパスワードが(後で上の単一文字へのアクセスを容易にするため)char配列に格納されているとしましょう:

#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"; 

またあなたはカウンターが必要になります。

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

while(true) { ... } 

どちらの必要性いずれもループ内の各反復ステップでリセットしないデータを格納するため、whileの前後に格納する必要があります。

このカウンタは、パスワードが表すキーシーケンスを完了するまでのユーザーの進捗状況を追跡するために使用されます。ユーザーは次のチェックを実行する必要がありますキーを押すたび

は:

  • は鍵が許可されていますか? - パスワードがabcの場合、ユーザーがyまたは!、またはabまたはc以外のものを押すと、そのキーは許可されません。
  • キーが許可されている場合は、それが表す文字を取り、インデックスprogressであなたのpasswordで、それは文字と同じだかどうかを確認:

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

バナナを行くカウンターを防止するために、I の鍵をに公開しました。これはと異なり、はワンタイムイベントです。キーが押されている場合は、キーの保留の一部でもかまいません。その場合は、else(上記のコードスニペットから)に何回も着陸します。これはあまり良い考えではないかもしれません。

キーが正常でシーケンスの点でパスワードが合っている場合は、次の反復ステップで新しいリリースされたキーイベントと新しいインデックス値で同じチェックを行うことができるように進捗を増やしますパスワード配列。

progressがキーシーケンスが完了し、パスワードが構成するすべての文字が「挿入済み」であることを示す必要な値に達すると、ループが中断される可能性があります。

これは非常に基本的なものですので、指示を明確にして実装することを願っています。


(現在は廃止による問題の変化に)前の回答

他のアウトオブボックスの方法は、(私はGetKeyState()または何か他のものを使用していないことを行うことが可能な場合を除きwindows.hから)一般的に、各ボタン(structなど)のpressedの状態を保存するだけです。

あなたのループでは、現在の反復ステップ中にどのボタンが押されたかを確認するために、ifステートメントの単純なチェーンを使用することができます。既知のキー(あなたのアプリケーションが処理したい1)が押下されるたびに、あなたは自分の配列にそのボタンのそれぞれの状態を切り替える必要があり、structまたは他のどんなコンテナあなたがこの情報を格納するために使用します。

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 (...) 
    { 
    // ... 
    } 
} 

最後たりwhileの体の開始時に、あなたは、各ボタンの状態を尋ねるとも組み合わせたクエリを行うことができます。

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 
    // ... 
} 

たとえばあなたがキーの状態を保存するには、以下の構造を使用しているとしましょう:

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

Key keyA; 
keyA.pressed = false; 

単にあなたの特定のボタンが現在押されているかどうかを確認し、それぞれいくつかのアクションをトリガーする

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

を行うことができます。

キーの組み合わせについては、それほど大きな違いはありません。あなたはそれを処理するために、単純にブール論理を使用する必要があります。

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

あなたは、アレイ内のすべてのサポートされているボタンを格納しても、各ボタンへの容易なアクセスを提供するために、素敵なenumを追加することで、コードの可読性を向上させることができます。

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) 
{ 
    // ... 
} 

あなたは、たとえばSDLを見ることができます(非常に低い)特にGetKeyState()のための任意のコードを見つけることができない場合。

+0

答えに感謝しますが、私はひどく自分自身を説明しました。私は、秘密のパスワードのようにしたいと思います。MessageBoxを見るためには、 "bcqwl"とタイプする必要があります。これは、順番に入力する必要があります。私は説明します: "bcqwl"とタイプするとメッセージボックスを見ることができますが、 "b"と "a"の後ろに "b"をタイプする必要があります。今私は私の答えを編集し、私はそれをより良く説明します。 – secon25

+0

はい、そうです。あなたのコメントにあなたが書いたものは、まったく異なるものですから。 :D – rbaleksandar

+0

さて、私はそれをしました、あなたは今私を助けることができますか? – secon25

関連する問題