无法使用Winapi更改C下的窗口大小和缓冲区

时间:2017-11-13 17:40:21

标签: c windows winapi

我已经重写了我的问题以简化它:

而不是呼叫系统("模式cons = 80行= 25");我尝试用WinApi调用自己做。

我得到的最佳代码是:

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);
}

首先,为什么我必须调用SetConsoleScreenBufferSize& SetConsoleWindowInfo两次?

其次,如果我离开" .Left = 0"和#34; .Top = 0"我的代码失败了。为什么呢?

原始问题:

我在C控制台应用中更改窗口大小和缓冲区时遇到问题。我无法弄清楚什么是错的。我需要帮助。

我做了以下更改缓冲区和窗口大小,它从控制台外调用时有效,但从控制台内部调用时失败:

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);

如果我在没有滚动的情况下尝试这样做(当我得到.Left和.Top = 0时)它失败了。

然后我试图通过其他方式,但仍然失败了。情况变得更糟。

在新代码中,如果我从Windows(而不是从控制台)调用此程序,它也会失败。

这就是我为大失败所做的事情:

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;

}

1 个答案:

答案 0 :(得分:1)

我发现了问题:缓冲区不能小于窗口大小。如果先更改缓冲区,则不能小于旧窗口大小。如果先更改窗口,则不能大于旧的缓冲区大小。

    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);
}
}