- To build for Windows, any compiler can be used.
- To build for MS-DOS, use Borland C++.
Last active
February 24, 2025 14:15
-
-
Save magiblot/318807a2a0f52f7fe63cf111d41504f7 to your computer and use it in GitHub Desktop.
Windows Console/MS-DOS keyboard input tester
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Program to test keyboard input in the Windows Console or MS-DOS. | |
// To build for MS-DOS, use Borland C++. | |
#include <stdlib.h> | |
#include <stdio.h> | |
const unsigned short | |
kbCtrlC = 0x2e03; | |
static void init(); | |
static void restore(); | |
static int readKey(unsigned short &keyCode, unsigned short &controlKeyState); | |
int main() | |
{ | |
init(); | |
atexit(restore); | |
puts("Press Ctrl+C to exit"); | |
unsigned long counter = 0; | |
unsigned short keyCode, controlKeyState; | |
do { | |
if (readKey(keyCode, controlKeyState)) | |
printf("Event #%lu:\t{0x%04hx, 0x%04hx}\n", ++counter, keyCode, controlKeyState); | |
} while (keyCode != kbCtrlC); | |
return 0; | |
} | |
#if defined(_WIN32) || (defined(__BORLANDC__) && defined(__FLAT__)) | |
#include <windows.h> | |
static DWORD oldConsoleMode; | |
static void init() | |
{ | |
puts("Using Win32 Console API"); | |
HANDLE console = GetStdHandle(STD_INPUT_HANDLE); | |
DWORD consoleMode; | |
if (!GetConsoleMode(console, &consoleMode)) | |
{ | |
printf("GetConsoleMode error: %lu\n", GetLastError()); | |
exit(1); | |
} | |
oldConsoleMode = consoleMode; | |
consoleMode &= ~ENABLE_PROCESSED_INPUT; // Report Ctrl+C and Shift+Arrow events. | |
consoleMode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); // Report Ctrl+S. | |
if (!SetConsoleMode(console, consoleMode)) | |
{ | |
printf("SetConsoleMode error: %lu\n", GetLastError()); | |
exit(1); | |
} | |
} | |
static void restore() | |
{ | |
HANDLE console = GetStdHandle(STD_INPUT_HANDLE); | |
if (!SetConsoleMode(console, oldConsoleMode)) | |
{ | |
printf("SetConsoleMode error: %lu\n", GetLastError()); | |
exit(1); | |
} | |
} | |
static int readKey(unsigned short &keyCode, unsigned short &controlKeyState) | |
{ | |
HANDLE console = GetStdHandle(STD_INPUT_HANDLE); | |
INPUT_RECORD irBuffer; | |
unsigned long eventsRead; | |
if (!ReadConsoleInput(console, &irBuffer, 1, &eventsRead)) | |
{ | |
printf("ReadConsoleInput error: %lu\n", GetLastError()); | |
exit(1); | |
} | |
if (irBuffer.EventType != KEY_EVENT || !irBuffer.Event.KeyEvent.bKeyDown) | |
return 0; | |
keyCode = (irBuffer.Event.KeyEvent.wVirtualScanCode << 8) | (irBuffer.Event.KeyEvent.uChar.AsciiChar); | |
controlKeyState = (unsigned short) irBuffer.Event.KeyEvent.dwControlKeyState; | |
return 1; | |
} | |
#elif defined(__BORLANDC__) && defined(__MSDOS__) | |
#include <dos.h> | |
const unsigned biosSel = 0x0040; | |
const unsigned short far * const biosKeyShiftStatus = | |
(const unsigned short far *) MK_FP(biosSel, 0x17); | |
static void init() | |
{ | |
puts("Using DOS interrupts"); | |
} | |
static void restore() | |
{ | |
} | |
int readKey(unsigned short &keyCode, unsigned short &controlKeyState) | |
{ | |
_AH = 0x10; // Get extended keystroke. | |
geninterrupt(0x16); | |
keyCode = _AX; | |
controlKeyState = *biosKeyShiftStatus; | |
return 1; | |
} | |
#else | |
#error Unknown system. MS-DOS (with Borland C++) or Win32 are supported. | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Prebuilt executables (built with Borland C++ 4.52): https://github.com/user-attachments/files/18907005/keytest.zip