Search code examples
windowswinapivisual-c++user32

Why I am having double Multiple times When I read Arrow Keys from Console?


I am trying to get arrows keys input from console but the trouble is when I press the key once it gives output twice in a loop. I tried to clear the INPUT_RECORD variable but common methods do not seem to work.

#include <iostream>
#include <windows.h>
#include <WinUser.h>

using namespace std;

int main()
{
    HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
    DWORD NumInputs = 0;
    DWORD InputsRead = 0;
    INPUT_RECORD irInput;

    irInput.Event.KeyEvent.wVirtualKeyCode = 0;

    GetConsoleMode(hInput, &NumInputs);
    SetConsoleMode(hInput, 0);
    GetNumberOfConsoleInputEvents(hInput, &NumInputs);

    while (true)
    {
     ReadConsoleInput(hInput, &irInput, 1, &InputsRead);

     switch (irInput.Event.KeyEvent.wVirtualKeyCode)
     {    
      case VK_DOWN:
           cout << "DOWN";
           break;

       case VK_LEFT:
            cout << "LEFT";
            break;

       case VK_RETURN:
            cout << "ENTER";
            break;

       case VK_RIGHT:
            cout << "RIGHT";
            break;

       case VK_UP:
            cout << "UP";
            break;
      }
   }
}

Solution

  • This Worked for me

    int KeysInput()
    {
        HANDLE _GetStdHandle();
        WORD ReadVkCode(HANDLE InputHandle);
    
        try {
            HANDLE InputHandle = _GetStdHandle();
            WORD InputRecord = ReadVkCode(InputHandle);
    
            switch (InputRecord)
            {
             case VK_DOWN:
               cout << "DOWN";
               break;
    
           case VK_LEFT:
                cout << "LEFT";
                break;
    
           case VK_RETURN:
                cout << "ENTER";
                break;
    
           case VK_RIGHT:
                cout << "RIGHT";
                break;
    
           case VK_UP:
                cout << "UP";
                break;
            }
        }
        catch (const std::exception & ex) {
            std::cerr << ex.what();
            return 1;
        }
    }
    
    HANDLE _GetStdHandle()
    { 
       HANDLE InputHandle;
    
        if ((InputHandle = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
            throw std::runtime_error("Failed to get standard input handle.");
    
        return InputHandle;
    }
    
    WORD ReadVkCode(HANDLE InputHandle)
    {
        INPUT_RECORD InputRecord;
        DWORD InputsRead;
    
        while (ReadConsoleInput(InputHandle, &InputRecord, 1, &InputsRead) && InputsRead == 1)
            if (InputRecord.EventType == KEY_EVENT && InputRecord.Event.KeyEvent.bKeyDown)
                return InputRecord.Event.KeyEvent.wVirtualKeyCode;
    
        throw std::runtime_error("Failed to read input.");
    }
    

    you can use it as a .h file if you want.