Hello!
I'm trying to write some MASM code that is equivalent to this C code:
int main() {
int ch;
do {
if (kbhit()) {
ch = getch();
}
} while (ch != 27);
printf("done\n");
return(0);
}
Since kbhit
(_kbhit
) and getch
(_getch
) are C runtime functions and not Win32 API functions, I had to find some Win32API equivalents for these functions.
I found this article on Microsoft's web site that contained this information:
They are:
_kbhit
is equivalent to PeekConsoleInput
; and
_getch
is equivalent to ReadConsoleInput
.
First, I wanted to test the conversion in C, just to make sure it still works:
int ReadKey(void) {
INPUT_RECORD inpR;
DWORD numRecsRead;
int ret = 0;
//Get a handle to the console
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
//Set up the console for input
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
//Here is equivalent the kbhit() call.
PeekConsoleInput(hIn, &inpR, 1, &numRecsRead);
//numRecsRead being 0 is equivalent to kbhit() returning false;
if (numRecsRead == 0) return(ret);
//Only interested in keyboard input, and when a key is pressed
if (inpR.EventType == KEY_EVENT && inpR.Event.KeyEvent.bKeyDown) {
if (inpR.Event.KeyEvent.uChar.AsciiChar != 0 &&
inpR.Event.KeyEvent.uChar.AsciiChar != 27) {
//ReadConsole() is the equivalent getch() call
ReadConsole(hIn, &ret, 1, &numRecsRead, NULL);
ret = ret & 0xFF;
} else {
//Catches other keys (like ESC, ALT, CTRS, SHIFT, etc).
ReadConsoleInput(hIn, &inpR, 1, &numRecsRead);
ret = inpR.Event.KeyEvent.uChar.AsciiChar;
}
} else {
ReadConsoleInput(hIn, &inpR, 1, &numRecsRead);
}
return(ret);
}
int main() {
int key;
do {
key = ReadKey();
} while(key != 27);
printf("done\n");
return(0);
}
No problems here.
I have two issues with the conversion over to MASM (well, one really):
1). WINDOWS.INC doesn't include everything. The two Win32 API functions mentioned above require the INPUT_RECORD structure, which I added. (Saw a discussion on this in an earlier thread, too :-)) No problem here.
2). PeekConsoleInput
almost always sets numRecsRead
to one, even if I didn't press any keys! I don't know what that's all about. Furthermore, when it does set numRecsRead
to zero, and I press a key, it's set one, but ReadConsole() and ReadConsoleInput()
do not seem to remove the last character from the input buffer like they should. That would make the next call set numRecsRead
to 0 (or the number of pending records/characters minus one).
Can anyone shed some light on this? Thanx!
I'll take a look. Something similar happens in DOS:
the device CON always returns after getting just one
byte. You can see asm source for a skeletal (but
working) console driver at www.hammick.com/hcs/computer.html