1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#include <iostream>
#include <stdexcept>
#include <Windows.h>
void SetConsoleWindowSize(int x, int y)
{
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
if (h == INVALID_HANDLE_VALUE)
throw std::runtime_error("Unable to get stdout handle.");
// If either dimension is greater than the largest console window we can have,
// there is no point in attempting the change.
{
COORD largestSize = GetLargestConsoleWindowSize(h);
if (x > largestSize.X)
throw std::invalid_argument("The x dimension is too large.");
if (y > largestSize.Y)
throw std::invalid_argument("The y dimension is too large.");
}
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
if (!GetConsoleScreenBufferInfo(h, &bufferInfo))
throw std::runtime_error("Unable to retrieve screen buffer info.");
SMALL_RECT& winInfo = bufferInfo.srWindow;
COORD windowSize = { winInfo.Right - winInfo.Left + 1, winInfo.Bottom - winInfo.Top + 1};
if (windowSize.X > x || windowSize.Y > y)
{
// window size needs to be adjusted before the buffer size can be reduced.
SMALL_RECT info =
{
0,
0,
x < windowSize.X ? x-1 : windowSize.X-1,
y < windowSize.Y ? y-1 : windowSize.Y-1
};
if (!SetConsoleWindowInfo(h, TRUE, &info))
throw std::runtime_error("Unable to resize window before resizing buffer.");
}
COORD size = { x, y };
if (!SetConsoleScreenBufferSize(h, size))
throw std::runtime_error("Unable to resize screen buffer.");
SMALL_RECT info = { 0, 0, x - 1, y - 1 };
if (!SetConsoleWindowInfo(h, TRUE, &info))
throw std::runtime_error("Unable to resize window after resizing buffer.");
}
void ShowLastSystemError()
{
LPSTR messageBuffer;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
0, // source
GetLastError(),
0, // lang
(LPSTR)&messageBuffer,
0,
NULL);
std::cerr << messageBuffer << '\n';
LocalFree(messageBuffer);
}
COORD QueryUserForConsoleSize()
{
COORD size = { 0, 0 };
std::cout << "New console size: ";
std::cin >> size.X >> size.Y;
return size;
}
int main()
{
COORD consoleSize;
std::cout << "An x or y size of 0 will terminate the program\n";
while (consoleSize = QueryUserForConsoleSize(), consoleSize.X && consoleSize.Y)
{
try {
SetConsoleWindowSize(consoleSize.X, consoleSize.Y);
}
catch (std::logic_error& ex)
{
std::cerr << ex.what() << '\n';
}
catch (std::exception& ex)
{
std::cerr << ex.what() << "\nSystem error: ";
ShowLastSystemError();
}
}
}
|