Significant refactoring with separate Console Handler.
This commit is contained in:
177
AVR Working Controller/ConsoleHandler.cpp
Normal file
177
AVR Working Controller/ConsoleHandler.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include "ConsoleHandler.h"
|
||||
|
||||
// For special cursor positioning
|
||||
static bool consoleInit = false;
|
||||
static HANDLE hStdout, hStdin;
|
||||
static CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
static WORD wOldColorAttrs; // Save the current console colors
|
||||
|
||||
static short consoleWidth = 0;
|
||||
static short consoleHeight = 0;
|
||||
static short scrollBot = 0; // set at init: consoleHeight - 1
|
||||
static short scrollTop = 0; // set at init: consoleHeight - consoleScrollHeight - 1
|
||||
|
||||
void Console_Init(short Width, short Height, short bottomScrollHeight) {
|
||||
hStdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (!GetConsoleScreenBufferInfo(hStdout, &csbi)) {
|
||||
fprintf(stderr, "Error: Unable to get console buffer info. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
consoleWidth = Width;
|
||||
consoleHeight = Height;
|
||||
|
||||
scrollBot = consoleHeight - 1;
|
||||
scrollTop = consoleHeight - bottomScrollHeight - 1;
|
||||
|
||||
// Desired size (width x height)
|
||||
COORD newSize;
|
||||
newSize.X = consoleWidth; // columns
|
||||
newSize.Y = consoleHeight; // rows
|
||||
|
||||
// Step 1: Shrink window if needed before shrinking buffer
|
||||
SMALL_RECT tempWindow = csbi.srWindow;
|
||||
tempWindow.Right = tempWindow.Left + (newSize.X - 1);
|
||||
tempWindow.Bottom = tempWindow.Top + (newSize.Y - 1);
|
||||
|
||||
if (!SetConsoleWindowInfo(hStdout, TRUE, &tempWindow)) {
|
||||
fprintf(stderr, "Error: Unable to temporarily resize window. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Step 2: Set new buffer size
|
||||
if (!SetConsoleScreenBufferSize(hStdout, newSize)) {
|
||||
fprintf(stderr, "Error: Unable to set console buffer size. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Step 3: Set final window size to match buffer
|
||||
SMALL_RECT newWindow;
|
||||
newWindow.Left = 0;
|
||||
newWindow.Top = 0;
|
||||
newWindow.Right = newSize.X - 1;
|
||||
newWindow.Bottom = newSize.Y - 1;
|
||||
|
||||
if (!SetConsoleWindowInfo(hStdout, TRUE, &newWindow)) {
|
||||
fprintf(stderr, "Error: Unable to set console window size. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
// end
|
||||
|
||||
wOldColorAttrs = csbi.wAttributes;
|
||||
//SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
}
|
||||
|
||||
void Console_Close() {
|
||||
SetConsoleTextAttribute(hStdout, wOldColorAttrs);
|
||||
}
|
||||
|
||||
void Console_Cls() {
|
||||
COORD coordScreen = { 0, 0 }; // home for the cursor
|
||||
DWORD cCharsWritten;
|
||||
DWORD dwConSize;
|
||||
|
||||
// Get the number of character cells in the current buffer.
|
||||
if (!GetConsoleScreenBufferInfo(hStdout, &csbi)) {
|
||||
return;
|
||||
}
|
||||
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
|
||||
// Fill the entire screen with blanks.
|
||||
if (!FillConsoleOutputCharacter(hStdout, // Handle to console screen buffer
|
||||
(TCHAR)' ', // Character to write to the buffer
|
||||
dwConSize, // Number of cells to write
|
||||
coordScreen, // Coordinates of first cell
|
||||
&cCharsWritten)) { // Receive number of characters written
|
||||
return;
|
||||
}
|
||||
// Get the current text attribute.
|
||||
if (!GetConsoleScreenBufferInfo(hStdout, &csbi)) {
|
||||
return;
|
||||
}
|
||||
// Set the buffer's attributes accordingly.
|
||||
if (!FillConsoleOutputAttribute(hStdout, // Handle to console screen buffer
|
||||
csbi.wAttributes, // Character attributes to use
|
||||
dwConSize, // Number of cells to set attribute
|
||||
coordScreen, // Coordinates of first cell
|
||||
&cCharsWritten)) { // Receive number of characters written
|
||||
return;
|
||||
}
|
||||
// Put the cursor at its home coordinates.
|
||||
SetConsoleCursorPosition(hStdout, coordScreen);
|
||||
}
|
||||
|
||||
void Console_Write(const char *text) {
|
||||
DWORD written;
|
||||
WriteConsole(hStdout, text, (DWORD)strlen(text), &written, nullptr);
|
||||
}
|
||||
|
||||
void Console_WriteAt(short x, short y, const char *text) {
|
||||
Console_SetCursor(x, y);
|
||||
DWORD written;
|
||||
WriteConsole(hStdout, text, (DWORD)strlen(text), &written, nullptr);
|
||||
}
|
||||
|
||||
void Console_SetCursor(short x, short y) {
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbi);
|
||||
csbi.dwCursorPosition.X = (short)((x < 0) ? csbi.srWindow.Right + x : x);
|
||||
csbi.dwCursorPosition.Y = (short)((y < 0) ? csbi.srWindow.Bottom + 1 + y : y);
|
||||
SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition);
|
||||
}
|
||||
|
||||
void Console_ScrollBottomRegion() {
|
||||
short topLine = scrollTop + 1;
|
||||
short bottomLine = scrollBot;
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbi);
|
||||
if (topLine < 0) topLine = csbi.srWindow.Bottom + topLine;
|
||||
if (bottomLine < 0) bottomLine = csbi.srWindow.Bottom + bottomLine;
|
||||
SMALL_RECT scrollRect = { 0, topLine, csbi.dwMaximumWindowSize.X - 1, bottomLine };
|
||||
COORD dest = { 0, topLine - 1 };
|
||||
CHAR_INFO fill = { ' ', { FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE } };
|
||||
ScrollConsoleScreenBuffer(hStdout, &scrollRect, &scrollRect, dest, &fill);
|
||||
_putch('\r'); // Cursor to left margin
|
||||
}
|
||||
|
||||
bool Console_AdvanceToNextLineIfNotRoomFor(short x, int scroll) {
|
||||
bool advanced = false;
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbi);
|
||||
if (csbi.dwCursorPosition.X + x > csbi.dwMaximumWindowSize.X) {
|
||||
advanced = true;
|
||||
if (scroll == 1) {
|
||||
Console_ScrollBottomRegion();
|
||||
} else {
|
||||
csbi.dwCursorPosition.Y++;
|
||||
}
|
||||
Console_SetCursor(0, csbi.dwCursorPosition.Y);
|
||||
}
|
||||
return advanced;
|
||||
}
|
||||
|
||||
// Console_SetCursorVisibility
|
||||
//
|
||||
// Set the state of the cursor and provide the prior state so it
|
||||
// can be restored
|
||||
//
|
||||
// @param[in] bool the desired state, true is visible
|
||||
// @returns the prior state, true is visible
|
||||
//
|
||||
bool Console_SetCursorVisibility(bool visible) {
|
||||
CONSOLE_CURSOR_INFO cursorInfo;
|
||||
bool priorState = true;
|
||||
|
||||
if (!GetConsoleCursorInfo(hStdout, &cursorInfo)) {
|
||||
// printf("***** Error: Unable to get cursor info.\n");
|
||||
return priorState;
|
||||
}
|
||||
priorState = cursorInfo.bVisible;
|
||||
cursorInfo.bVisible = visible; // true = show, false = hide
|
||||
if (!SetConsoleCursorInfo(hStdout, &cursorInfo)) {
|
||||
// std::cerr << "Error: Unable to set cursor info.\n";
|
||||
}
|
||||
return priorState;
|
||||
}
|
||||
Reference in New Issue
Block a user