我知道有很多关于如何设置控制台大小的问题。但是所有找到的解决方案对我来说都是一样的,我的代码对我没用。
好的,所以为了设置控制台窗口大小,我需要两个功能。它们是SetConsoleScreenBufferSize()和SetConsoleWindowInfo()。我的函数的第一个版本:
bool SetWindowSize(size_t width, size_t height)
{
HANDLE output_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
if(output_handle == INVALID_HANDLE_VALUE)
return false;
COORD coord = {};
coord.X = static_cast<SHORT>(width);
coord.Y = static_cast<SHORT>(height);
if(::SetConsoleScreenBufferSize(output_handle, coord) == FALSE)
return false;
SMALL_RECT rect = {};
rect.Bottom = coord.X - 1;
rect.Right = coord.Y - 1;
return (::SetConsoleWindowInfo(output_handle, TRUE, &rect) != FALSE);
}
SetConsoleScreenBufferSize()
不适用于所有值。来自文档:
指定的宽度和高度不能小于宽度和 控制台屏幕缓冲区窗口的高度
让我们尝试获取当前窗口的大小并调用我们的函数。要获得窗口大小,我需要GetConsoleScreenBufferInfo()函数。 main()测试代码:
HANDLE output_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
if(output_handle == INVALID_HANDLE_VALUE)
return 0;
CONSOLE_SCREEN_BUFFER_INFO info = {};
if(::GetConsoleScreenBufferInfo(output_handle, &info) == FALSE)
return 0;
size_t width = info.srWindow.Right - info.srWindow.Left;
size_t height = info.srWindow.Bottom - info.srWindow.Top;
bool suc = SetWindowSize(width + 1, height + 1);
在这种情况下SetConsoleScreenBufferSize()
可以正常工作。下一个功能是SetConsoleWindowInfo()
。此功能适用于以下情况:
如果指定的窗口矩形超出范围,则函数将失败 控制台屏幕缓冲区的边界。这意味着
Top
Left
矩形的lpConsoleWindow
成员(或计算出来的bAbsolute
成员 如果Bottom
为FALSE,则顶部和左侧坐标不能小于 零。同样,Right
和height – 1
成员(或计算出的成员) 底部和右侧坐标)不能大于(屏幕缓冲区width – 1
)和(屏幕缓冲区Right
)。功能 如果Left
成员(或计算出的右坐标)是,则也会失败 小于或等于Bottom
成员(或计算左坐标) 或者如果Top
成员(或计算的底部坐标)小于 或等于Left
成员(或计算出的顶部坐标)。
在我们的例子中,矩形的值与调用Top
后info.srWindow
矩形的值相同(因为GetConsoleScreenBufferInfo()
和SetConsoleWindowInfo()
为零)。但! ::GetLastError()
失败并显示下一个@err,hr ERROR_INVALID_PARAMETER : The parameter is incorrect. unsigned int
bool SetWindowSize(size_t width, size_t height)
{
HANDLE output_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
if(output_handle == INVALID_HANDLE_VALUE)
return false;
SMALL_RECT rect = {};
rect.Bottom = static_cast<SHORT>(width);
rect.Right = static_cast<SHORT>(height);
if(::SetConsoleWindowInfo(output_handle, TRUE, &rect) == FALSE)
return false;
COORD coord = {};
coord.X = rect.Bottom + 1;
coord.Y = rect.Right + 1;
return (::SetConsoleScreenBufferSize(output_handle, coord) != FALSE);
}
如果我交换这两个函数的调用:
SetConsoleScreenBufferSize()
然后我会有同样的错误。
那么,我如何才能正确使用SetConsoleWindowInfo()
和{{1}}?
答案 0 :(得分:3)
SetConsoleWindowInfo()不会在屏幕上重新定位控制台窗口。此功能的名称具有误导性。它宁可滚动控制台窗口内的当前可见部分。请在此处查看this sample。
如果要设置运行程序的控制台窗口的位置,请使用以下代码:
HWND hwnd = GetConsoleWindow();
RECT rect = {100, 100, 300, 500};
MoveWindow(hwnd, rect.top, rect.left, rect.bottom-rect.top, rect.right-rect.left, TRUE);
答案 1 :(得分:1)
void TDisplay::setCrtMode( ushort mode )
{
int oldr = getRows();
int oldc = getCols();
int cols = uchar(mode >> 8);
int rows = uchar(mode);
if ( cols == 0 ) cols = oldc;
if ( rows == 0 ) rows = oldr;
checksize(rows, cols);
COORD newSize = { cols, rows };
SMALL_RECT rect = { 0, 0, cols-1, rows-1 };
if ( oldr <= rows )
{
if ( oldc <= cols )
{ // increasing both dimensions
BUFWIN:
SetConsoleScreenBufferSize( TThreads::chandle[cnOutput], newSize );
SetConsoleWindowInfo( TThreads::chandle[cnOutput], True, &rect );
}
else
{ // cols--, rows+
SMALL_RECT tmp = { 0, 0, cols-1, oldr-1 };
SetConsoleWindowInfo( TThreads::chandle[cnOutput], True, &tmp );
goto BUFWIN;
}
}
else
{
if ( oldc <= cols )
{ // cols+, rows--
SMALL_RECT tmp = { 0, 0, oldc-1, rows-1 };
SetConsoleWindowInfo( TThreads::chandle[cnOutput], True, &tmp );
goto BUFWIN;
}
else
{ // cols--, rows--
SetConsoleWindowInfo( TThreads::chandle[cnOutput], True, &rect );
SetConsoleScreenBufferSize( TThreads::chandle[cnOutput], newSize );
}
}
GetConsoleScreenBufferInfo( TThreads::chandle[cnOutput], &TThreads::sbInfo );
}
ushort TDisplay::getRows()
{
GetConsoleScreenBufferInfo( TThreads::chandle[cnOutput], &TThreads::sbInfo );
return TThreads::sbInfo.dwSize.Y;
}
ushort TDisplay::getCols()
{
GetConsoleScreenBufferInfo( TThreads::chandle[cnOutput], &TThreads::sbInfo );
return TThreads::sbInfo.dwSize.X;
}