Reputation: 21
I've rewritten my question to simplify it:
instead of calling system("mode con cols=80 lines=25"); I try to do it myself with WinApi calls.
Best code I get is this:
void screensizexy(int x, int y)
{
SMALL_RECT console_size2;
console_size2.Right = x;
console_size2.Bottom = y;
console_size2.Left = 1;
console_size2.Top = 1;
COORD console_size;
console_size.X = x;
console_size.Y = y;
SetConsoleScreenBufferSize(hStdout, console_size);
SetConsoleWindowInfo(hStdout, TRUE, &console_size2);
SetConsoleScreenBufferSize(hStdout, console_size);
SetConsoleWindowInfo(hStdout, TRUE, &console_size2);
}
First of all, why do I have to call SetConsoleScreenBufferSize & SetConsoleWindowInfo twice?
Second, if I leave ".Left = 0" and ".Top = 0" my code fails. Why?
Original Question:
I have a problem with changing windows size and buffer in a C console app. I can't figure what is wrong. I need help.
I did the following to change buffer and windows size, it worked when called from out of console, but failed when called from inside the console:
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD console_size;
console_size.X = 100;
console_size.Y = 50;
SetConsoleScreenBufferSize(hStdout, console_size);
SMALL_RECT console_size2;
console_size2.Right = 100;
console_size2.Bottom = 50;
console_size2.Left = 1;
console_size2.Top = 1;
SetConsoleWindowInfo(hStdout, TRUE, &console_size2);
If I tried to do it without scrolling, (when I get .Left and .Top = 0) it failed.
Then I tried to get other way around, but still failed. It became worse.
In the new code, if I call this program from windows (not from a console), it failed too.
This is what I do for a big fail:
HANDLE hStdout, hStdin;
int main()
{
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
hStdin = GetStdHandle(STD_INPUT_HANDLE);
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hStdout, &csbiInfo); //here I store original stuff
// here is the beginning of my program that changes console screen buffer and window size
CONSOLE_SCREEN_BUFFER_INFO console_size;
GetConsoleScreenBufferInfo(hStdout, &console_size);
console_size.dwSize.X = 100;
console_size.dwSize.Y = 50;
console_size.srWindow.Right = 100;
console_size.srWindow.Bottom = 50;
console_size.srWindow.Left = 0;
console_size.srWindow.Top = 0;
SetConsoleScreenBufferSize(hStdout, console_size.dwSize);
SetConsoleWindowInfo(hStdout, TRUE, &console_size.srWindow);
// I fail here, so i added a code to see what are current values.
CONSOLE_SCREEN_BUFFER_INFO csbiInfo2;
HANDLE hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );
GetConsoleScreenBufferInfo( hConsoleOut, &csbiInfo2 );
printf("dwCursorPosition.X = %i\n",csbiInfo2.dwCursorPosition.X);
printf("dwCursorPosition.Y = %i\n",csbiInfo2.dwCursorPosition.Y);
printf("dwSize.X = %i\n",csbiInfo2.dwSize.X);
printf("dwSize.Y = %i\n",csbiInfo2.dwSize.Y);
printf("wAttributes = %i\n", csbiInfo2.wAttributes);
printf("srWindow = %i\n", csbiInfo2.srWindow);
printf("srWindow.Top = %i\n", csbiInfo2.srWindow.Top);
printf("srWindow.Bottom = %i\n", csbiInfo2.srWindow.Bottom);
printf("srWindow.Left = %i\n", csbiInfo2.srWindow.Left);
printf("srWindow.Right = %i\n", csbiInfo2.srWindow.Right);
printf("dwMaximumWindowSize = %i\n", csbiInfo2.dwMaximumWindowSize);
printf("\n");
getch();
// Here, my program does its functions.
// stuff
// stuf
// now, at the end, I want to get back to original window size and buffer.
SetConsoleTextAttribute(hStdout, csbiInfo.wAttributes); // Restore the original text colors.
SetConsoleScreenBufferSize(hStdout, csbiInfo.dwSize); //restore buffer size
SetConsoleWindowInfo(hStdout, TRUE, &csbiInfo.srWindow); //restore window size
return 0;
}
Upvotes: 0
Views: 973
Reputation: 21
I figured out the problem: Buffer cannot be smaller than window size. If you change buffer first, you cant go smaller than old window size. If you change window first, you cant go larger than old buffer size.
void newbufwinxy(int x, int y)
{
SMALL_RECT console_size2;
console_size2.Right = x;
console_size2.Bottom = y;
console_size2.Left = 1;
console_size2.Top = 1;
COORD console_size;
console_size.X = x;
console_size.Y = y;
CONSOLE_SCREEN_BUFFER_INFO screencsbi;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &screencsbi);
//if new buffer is larger than old buffer size or at least window, go ahead
if (console_size.X >= screencsbi.dwSize.X && (console_size.Y >= screencsbi.dwSize.Y||console_size.Y >= screencsbi.srWindow.Bottom-1))
{
SetConsoleScreenBufferSize(hStdout, console_size);
SetConsoleWindowInfo(hStdout, TRUE, &console_size2);
}
//if new window is larger in widght but smaller in height, do a temporary shrink
else if (console_size2.Right >= screencsbi.srWindow.Right-1 && console_size2.Bottom <= screencsbi.srWindow.Bottom-1)
{
console_size2.Right = 20; //temporarily shrink window width...
SetConsoleWindowInfo(hStdout, TRUE, &console_size2);
SetConsoleScreenBufferSize(hStdout, console_size);
console_size2.Right = x;
SetConsoleWindowInfo(hStdout, TRUE, &console_size2);
}
//if new buffer is smaller than old window, change window first
else if (console_size.X <= screencsbi.dwSize.X && !(console_size2.Bottom >= screencsbi.dwSize.Y))
{
SetConsoleWindowInfo(hStdout, TRUE, &console_size2);
SetConsoleScreenBufferSize(hStdout, console_size);
}
else
{
printf("\nold _values_ >> new _values_ \n");
printf("dwSize.X = %i >> ",screencsbi.dwSize.X);
printf("dwSize.X = %i\n",console_size.X);
printf("dwSize.Y = %i >> ",screencsbi.dwSize.Y);
printf("dwSize.Y = %i\n",console_size.Y);
printf("srWindow.Bottom = %i >> ", screencsbi.srWindow.Bottom);
printf("srWindow.Bottom = %i\n", console_size2.Bottom);
printf("srWindow.Right = %i >> ", screencsbi.srWindow.Right);
printf("srWindow.Right = %i\n", console_size2.Right);
printf("SetConsoleWindowInfo, SetConsoleScreenBufferSize\n");
printf("Error. Cannot recognise console windows or buffer size!\n");
printf("\nProgram encountered errors and shall exit now.");
printf("\nPress any key to continue...");
getch();
ExitProcess(1);
}
}
Upvotes: 1