4

ユーザーのキープレスをキャッチするために単純なループを使用しています。

while (1)
{
    for(i = 8; i <= 190; i++)
    {
       if (GetAsyncKeyState(i) == -32767){
         //Do stuff
       }
    }
}

ユーザーが特定のキーを押すと「何かを実行」しますが、明らかに無期限にループしており、C++ を初めて使用するため、単純な入力には適していない 100% の CPU を占有しています。

私は何を間違っていますか?私はSleep()関数を試しました(「forループ」に入れるとキープレスが失敗し、「whileループ」に入れるとCPUがまったく低下しません)

キープレスを同じようにキャッチする方法はありますが、CPU の使用量はそれほど多くありません。私はトリックを逃していますか?ほとんどのプログラムはキープレスをキャッチし、それらすべてが 100% 使用されているわけではありません。

どうもありがとう。

4

3 に答える 3

3

無限ループをワーカー スレッドに配置し、反復ごとに適切な間隔でスリープさせます。C++11 では、これが非常に簡単になります。

#include <thread>
#include <chrono>

std::chrono::milliseconds THREAD_WAIT = 50;

int keypress = -1;

void GetKeyPress()
{
   while (1)
   {
       for(i = 8; i <= 190; i++)
       {
          int k = GetAsyncKeyState(i);
          if (/*whatever condition needs to be satisfied*/)
              keypress = k;
       }
       if (keypress != -1) break; //Use this only if you have td.join() below
       std::this_thread::sleep_for(THREAD_WAIT);
   }
}

int main(void)
{
   ...

   std::thread td( GetKeyPress );
   td.join(); //If you want to block until the user presses a key, otherwise remove.

   //If no join(), do the rest of your program, checking in on keypress when need be

   return 0;
}
于 2012-09-30T03:40:36.097 に答える
1

サンプル コードで GetAsyncKeyState() の適切な使用法を説明する次のリンクを確認してください。 http://www.mpgh.net/forum/31-cc-programming/120656-proper-use-getasynckeystate.html

このリンクが問題の解決に役立つことを願っています

編集: GetAsyncKeyState() 関数は、あなたがしようとしていることには理想的ではありません。

キーボード上のキーの実際の現在のナノ秒位置を確認するだけです。それを行うことは、ほとんどの場合正しくありません。

代わりに、適切な入力関数を使用してコンソール入力を読み取ります。以下のサンプルコードをご覧ください。

#include <stdio.h>
#include <windows.h>

int main()
{
    DWORD        mode;          /* Preserved console mode */
    INPUT_RECORD event;         /* Input event */
    BOOL         done = FALSE;  /* Program termination flag */
    unsigned int counter = 0;   /* The number of times 'Esc' is pressed */

    /* Don't use binary for text files, OK?  ;-) */
    FILE* myfile = fopen( "example.txt", "w" );

    /* Get the console input handle */
    HANDLE hstdin = GetStdHandle( STD_INPUT_HANDLE );

    /* Preserve the original console mode */
    GetConsoleMode( hstdin, &mode );

    /* Set to no line-buffering, no echo, no special-key-processing */
    SetConsoleMode( hstdin, 0 );

    /* Give the user instructions */
    printf(
        "Press Escape as many times as you like.\n"
        "Press anything else to quit.\n\n"
        );

    while (!done)
    {
        if (WaitForSingleObject( hstdin, 0 ) == WAIT_OBJECT_0)  /* if kbhit */
        {
            DWORD count;  /* ignored */

            /* Get the input event */
            ReadConsoleInput( hstdin, &event, 1, &count );

            /* Only respond to key release events */
            if ((event.EventType == KEY_EVENT)
            &&  !event.Event.KeyEvent.bKeyDown)
                switch (event.Event.KeyEvent.wVirtualKeyCode)
                {
                    case VK_ESCAPE:
                        counter++;
                        fprintf( myfile, "Escape: %d\n", counter );
                        printf( "Button pressed!\n" );
                        break;
                    default:
                        done = TRUE;
                }
        }
    }

    /* All done! */
    printf( "You pressed the Escape key %d times\n", counter );
    fclose( myfile );
    SetConsoleMode( hstdin, mode );
    return 0;
}
于 2012-09-30T03:23:16.160 に答える
0

あなたが使用することができます

while (!kbhit());

これは役立つかもしれません。

于 2012-09-30T03:10:04.073 に答える