1

Windows 10 with latest updates installed on a Dell XPS13. US keyboard layout and US locale selected (not international). Still a call to kbhit() or _kbhit() with specific characters such as ", ~, % does not return the key hit, at least mot until a certain amount of time (~1second) and a second character has been hit. I try to use kbhit() because I need a non-waiting function. How can I detect correctly a keyboard hit on " or % with a single keystroke? In Linux using a timed-out select() on stdin works great, but doesn't seem to be OK with Windows.

Thanks, -Patrick

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
Patrick
  • 21
  • 4
  • I finally found a solution that fits my needs and fixes the issues I have with kbhit(); code below; I hope it helps others too. – Patrick Nov 01 '18 at 11:27

1 Answers1

1

I finally found a solution that fits my needs and fixes the issues I have with kbhit(); code below; I hope it helps others too.

– Patrick

    int getkey();
//
// int getkey(): returns the typed character at keyboard or NO_CHAR if no keyboard key was pressed.
// This is done in non-blocking mode; i.e. NO_CHAR is returned if no keyboard event is read from the
// console event queue.
// This works a lot better for me than the standard call to kbhit() which is generally used as kbhit()
// keeps some characters such as ", `, %, and tries to deal with them before returning them. Not easy
// the to follow-up what's really been typed in.
//
int getkey() {
    INPUT_RECORD     buf;        // interested in bKeyDown event
    DWORD            len;        // seem necessary
    int              ch;

    ch = NO_CHAR;                // default return value;
    PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &buf, 1, &len);
    if (len > 0) {
        if (buf.EventType == KEY_EVENT && buf.Event.KeyEvent.bKeyDown) {
            ch = _getche();      // set ch to input char only under right conditions
        }                        // _getche() returns char and echoes it to console out
        FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); // remove consumed events
    } else {
        Sleep(5);                // avoids too High a CPU usage when no input
    }
    return ch;
}

It is also possible to call ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &buf, 1, &len); rather than FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); in the code above, but for some unknown reason, it doesn't seem to reply/react as quickly and some character are missed when typing at the keyboard.

Patrick
  • 21
  • 4