Created
November 10, 2023 15:03
-
-
Save mrchipset/637d5b4650aa5914efca1746104642ad to your computer and use it in GitHub Desktop.
Windows read console non-blocking
This file contains 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
#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