Skip to content

Instantly share code, notes, and snippets.

@mrchipset
Created November 10, 2023 15:03
Show Gist options
  • Save mrchipset/637d5b4650aa5914efca1746104642ad to your computer and use it in GitHub Desktop.
Save mrchipset/637d5b4650aa5914efca1746104642ad to your computer and use it in GitHub Desktop.
Windows read console non-blocking
#include <stdio.h>
#include <Windows.h>
COORD GetConsoleCursorPosition(HANDLE hConsoleOutput)
{
CONSOLE_SCREEN_BUFFER_INFO cbsi;
if (GetConsoleScreenBufferInfo(hConsoleOutput, &cbsi))
{
return cbsi.dwCursorPosition;
}
else
{
// The function failed. Call GetLastError() for details.
COORD invalid = { 0, 0 };
return invalid;
}
}
int main(int argc, char** argv){
printf("Hello, from term!\n");
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD dwMode;
GetConsoleMode(hStdIn, &dwMode);
// It seems both is ok under VSCode integrated terminal. But not work for other terminal.
// dwMode = ENABLE_WINDOW_INPUT | ENABLE_PROCESSED_INPUT;
dwMode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
printf("Mode: %d\t%x\n", dwMode, dwMode);
if(!SetConsoleMode(hStdIn, dwMode)) {
return -1;
}
FlushConsoleInputBuffer(hStdIn);
char buff[128];
DWORD dwRead = 0;
DWORD dwWritten;
BOOL timeout = FALSE;
while(TRUE) {
DWORD dwRet = WaitForSingleObject(hStdIn, 1000);
switch(dwRet) {
case WAIT_OBJECT_0:
ReadFile(hStdIn, buff, 128, &dwRead, NULL);
WriteFile(hStdOut, buff, dwRead, &dwWritten, NULL);
if (dwRead == 1) {
if (buff[0] == '\r') {
COORD coord = GetConsoleCursorPosition(hStdOut);
CONSOLE_SCREEN_BUFFER_INFO screen;
GetConsoleScreenBufferInfo(hStdOut, &screen);
DWORD size = screen.srWindow.Right;
for (int i = screen.srWindow.Left; i < screen.srWindow.Right; ++i) {
WriteFile(hStdOut, " ", 1, NULL, NULL);
}
SetConsoleCursorPosition(hStdOut, coord);
}
}
break;
case WAIT_TIMEOUT:
// printf("2");
timeout = TRUE;
break;
default:
break;
}
COORD coord = GetConsoleCursorPosition(hStdOut);
COORD newCoord = coord;
newCoord.Y += 2;
newCoord.X = 0;
// clear the line;
SetConsoleCursorPosition(hStdOut, newCoord);
CONSOLE_SCREEN_BUFFER_INFO screen;
GetConsoleScreenBufferInfo(hStdOut, &screen);
DWORD size = screen.srWindow.Right;
for (int i = screen.srWindow.Left; i < screen.srWindow.Right; ++i) {
WriteFile(hStdOut, " ", 1, NULL, NULL);
}
buff[dwRead] = '\0';
// write content
SetConsoleCursorPosition(hStdOut, newCoord);
if (timeout) {
printf("Timeout");
} else {
printf("Read char count: %d, buff:%s", dwRead, buff);
}
SetConsoleCursorPosition(hStdOut, coord);
dwRead = 0;
ZeroMemory(buff, 128);
timeout = FALSE;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment