//*************************************************************** // From the book "Win32 System Services: The Heart of Windows 98 // and Windows 2000" // by Marshall Brain // Published by Prentice Hall // // Copyright 1995, by Prentice Hall. // // This code shows how to handle raw input from a console so that // you can retrieve input one character at a time. //*************************************************************** // raw.cpp #include #include void ErrorHandler(char *s, DWORD err) { cout << s << endl; cout << "Error number: " << err << endl; ExitProcess(err); } void ScrollOneLine(HANDLE stdout) { BOOL success; CONSOLE_SCREEN_BUFFER_INFO consoleInfo; SMALL_RECT scrollRect; CHAR_INFO consoleFill; COORD coord; // get current console size (may change) success = GetConsoleScreenBufferInfo(stdout, &consoleInfo); if (!success) ErrorHandler( "In GetConsoleScreenBufferInfo", GetLastError()); // Define the rectangle to scroll scrollRect.Top = 0; scrollRect.Left = 0; scrollRect.Bottom = consoleInfo.dwSize.Y - 1; scrollRect.Right = consoleInfo.dwSize.X - 1; // Define destination of scrolled rectangle coord.X = 0; coord.Y = -1; // Define how to fill blank line consoleFill.Attributes = consoleInfo.wAttributes; consoleFill.Char.AsciiChar = ' '; // Perform the scroll success = ScrollConsoleScreenBuffer(stdout, &scrollRect, 0, coord, &consoleFill); if (!success) ErrorHandler("In ScrollConsoleScreenBuffer", GetLastError()); } VOID HandleCR(HANDLE stdout) { CONSOLE_SCREEN_BUFFER_INFO consoleInfo; BOOL success; success = GetConsoleScreenBufferInfo(stdout, &consoleInfo); if (!success) ErrorHandler("In GetConsoleScreenBufferInfo", GetLastError()); // Move cursor to far left consoleInfo.dwCursorPosition.X = 0; // If the cursor is on the last line of // the console, then scroll the console, // else increment position if (consoleInfo.dwSize.Y - 1 == consoleInfo.dwCursorPosition.Y) ScrollOneLine(stdout); else consoleInfo.dwCursorPosition.Y += 1; // Update the console success = SetConsoleCursorPosition(stdout, consoleInfo.dwCursorPosition); if (!success) ErrorHandler("In SetConsoleCursorPosition", GetLastError()); } void ProcessIO(HANDLE stdin, HANDLE stdout) { char buffer; DWORD numRead, numWrite; do { ReadFile(stdin, &buffer, 1, &numRead, NULL); if (buffer == '\r') HandleCR(stdout); else WriteFile(stdout, &buffer, 1, &numWrite, NULL); } while (buffer != 'X'); } VOID main(void) { DWORD oldMode, newMode; BOOL success; HANDLE stdout, stdin; // Get handles for standard in and out stdin = GetStdHandle(STD_INPUT_HANDLE); stdout = GetStdHandle(STD_OUTPUT_HANDLE); if (stdin == stdout) //they must be invalid ErrorHandler("In GetStdHandle", GetLastError()); // Get current console mode so can modify it success = GetConsoleMode(stdin, &oldMode); if (!success) ErrorHandler("In GetConsoleMode", GetLastError()); newMode = oldMode & ~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT; success = SetConsoleMode(stdin, newMode); if (!success) ErrorHandler("In SetConsoleMode", GetLastError()); // Process user I/O ProcessIO(stdin, stdout); // put the old mode back success = SetConsoleMode(stdin, oldMode); if (!success) ErrorHandler("In SetConsoleMode", GetLastError()); }