extern "C" int __cdecl _kbhit_nolock() { // If a character has been pushed back, return TRUE: if (chbuf != -1) return TRUE; if (__dcrt_lowio_console_input_handle == -2) __dcrt_lowio_initialize_console_input(); if (__dcrt_lowio_console_input_handle == -1) return FALSE; HANDLE const console_handle = reinterpret_cast<HANDLE>(__dcrt_lowio_console_input_handle); // Peek at all pending console events: DWORD num_pending; if (GetNumberOfConsoleInputEvents(console_handle, &num_pending) == 0) return FALSE; if (num_pending == 0) return FALSE; __crt_scoped_stack_ptr<INPUT_RECORD> const input_buffer(_malloca_crt_t(INPUT_RECORD, num_pending)); if (input_buffer.get() == nullptr) return FALSE; DWORD num_peeked; if (PeekConsoleInput(console_handle, input_buffer.get(), num_pending, &num_peeked) == 0) return FALSE; if (num_peeked == 0 || num_peeked > num_pending) return FALSE; // Scan all of the peeked events to determine if any is a key event // that should be recognized: for (INPUT_RECORD* p = input_buffer.get(); num_peeked > 0; --num_peeked, ++p) { if (p->EventType != KEY_EVENT) continue; if (!p->Event.KeyEvent.bKeyDown) continue; if (p->Event.KeyEvent.uChar.AsciiChar == 0 && _getextendedkeycode(&p->Event.KeyEvent) == nullptr) continue; return TRUE; } return FALSE; }
int __cdecl _kbhit_nolock ( void ) { DWORD NumPending; DWORD NumPeeked; int ret = FALSE; PINPUT_RECORD pIRBuf=NULL; /* * if a character has been pushed back, return TRUE */ if ( chbuf != -1 ) return TRUE; /* * _coninpfh, the handle to the console input, is created the first * time that either _getch() or _cgets() or _kbhit() is called. */ if ( _coninpfh == -2 ) __initconin(); /* * Peek all pending console events */ if ( (_coninpfh == -1) || !GetNumberOfConsoleInputEvents((HANDLE)_coninpfh, &NumPending) || (NumPending == 0)) { return FALSE; } pIRBuf=(PINPUT_RECORD)_calloca(NumPending, sizeof(INPUT_RECORD)); if ( pIRBuf == NULL ) { return FALSE; } if ( PeekConsoleInput( (HANDLE)_coninpfh, pIRBuf, NumPending, &NumPeeked ) && (NumPeeked != 0L) && (NumPeeked <= NumPending) ) { /* * Scan all of the peeked events to determine if any is a key event * which should be recognized. */ PINPUT_RECORD pIR; for ( pIR = pIRBuf ; NumPeeked > 0 ; NumPeeked--, pIR++ ) { if ( (pIR->EventType == KEY_EVENT) && (pIR->Event.KeyEvent.bKeyDown) && ( pIR->Event.KeyEvent.uChar.AsciiChar || _getextendedkeycode( &(pIR->Event.KeyEvent) ) ) ) { /* * Key event corresponding to an ASCII character or an * extended code. In either case, success! */ ret = TRUE; } } } _freea( pIRBuf ); return ret; }
extern "C" int __cdecl _getch_nolock() { // Check the pushback buffer for a character. If one is present, return it: if (chbuf != EOF) { int const c = static_cast<unsigned char>(chbuf & 0xff); chbuf = EOF; return c; } if (__dcrt_lowio_console_input_handle == -2) __dcrt_lowio_initialize_console_input(); if (__dcrt_lowio_console_input_handle == -1) return EOF; HANDLE const console_handle = reinterpret_cast<HANDLE>(__dcrt_lowio_console_input_handle); // Switch console to raw mode: DWORD old_console_mode; GetConsoleMode(console_handle, &old_console_mode); SetConsoleMode(console_handle, 0); int result = 0; __try { for ( ; ; ) { // Get a console input event: INPUT_RECORD input_record; DWORD num_read; if (!ReadConsoleInput(console_handle, &input_record, 1, &num_read) || num_read == 0) { result = EOF; __leave; } // Look for, and decipher, key events. if (input_record.EventType == KEY_EVENT && input_record.Event.KeyEvent.bKeyDown) { // Easy case: if UnicodeChar is non-zero, we can just return it: unsigned char const c = static_cast<unsigned char>(input_record.Event.KeyEvent.uChar.AsciiChar); if (c != 0) { result = c; __leave; } // Hard case: either it is an extended code or an event which // should not be recognized. Let _getextendedkeycode do the work: CharPair const* const cp = _getextendedkeycode(&input_record.Event.KeyEvent); if (cp != nullptr) { chbuf = cp->SecondChar; result = cp->LeadChar; __leave; } } } } __finally { // Restore the previous console mode: SetConsoleMode(console_handle, old_console_mode); } return result; }
int __cdecl _getch_nolock ( void ) { INPUT_RECORD ConInpRec; DWORD NumRead; const CharPair *pCP; int ch = 0; /* single character buffer */ DWORD oldstate; /* * check pushback buffer (chbuf) a for character */ if ( chbuf != EOF ) { /* * something there, clear buffer and return the character. */ ch = (unsigned char)(chbuf & 0xFF); chbuf = EOF; return ch; } /* * _coninpfh, the handle to the console input, is created the first * time that either _getch() or _cgets() or _kbhit() is called. */ if ( _coninpfh == -2 ) __initconin(); if (_coninpfh == -1) return EOF; /* * Switch to raw mode (no line input, no echo input) */ GetConsoleMode( (HANDLE)_coninpfh, &oldstate ); SetConsoleMode( (HANDLE)_coninpfh, 0L ); for ( ; ; ) { /* * Get a console input event. */ if ( !ReadConsoleInput( (HANDLE)_coninpfh, &ConInpRec, 1L, &NumRead ) || (NumRead == 0L) ) { ch = EOF; break; } /* * Look for, and decipher, key events. */ if ( (ConInpRec.EventType == KEY_EVENT) && ConInpRec.Event.KeyEvent.bKeyDown ) { /* * Easy case: if uChar.AsciiChar is non-zero, just stuff it * into ch and quit. */ if ( ch = (unsigned char)ConInpRec.Event.KeyEvent.uChar.AsciiChar ) break; /* * Hard case: either an extended code or an event which should * not be recognized. let _getextendedkeycode() do the work... */ if ( pCP = _getextendedkeycode( &(ConInpRec.Event.KeyEvent) ) ) { ch = pCP->LeadChar; chbuf = pCP->SecondChar; break; } } } /* * Restore previous console mode. */ SetConsoleMode( (HANDLE)_coninpfh, oldstate ); return ch; }