Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set console window size on Windows

Tags:

c++

winapi

I know that there is a lot questions about how to set console size. But all found solutions are the same to my and my code doesn't works for me.

Ok, so for setting console window size, I need two functions. They are SetConsoleScreenBufferSize() and SetConsoleWindowInfo(). First version of my function:

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() will work not for all values. From documentation:

The specified width and height cannot be less than the width and height of the console screen buffer's window

Lets try to get current window's size and call our function. To get window size, I need GetConsoleScreenBufferInfo() function. main() test code:

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

In this case SetConsoleScreenBufferSize() works fine. Next function is SetConsoleWindowInfo(). This function will work in case:

The function fails if the specified window rectangle extends beyond the boundaries of the console screen buffer. This means that the Top and Left members of the lpConsoleWindow rectangle (or the calculated top and left coordinates, if bAbsolute is FALSE) cannot be less than zero. Similarly, the Bottom and Right members (or the calculated bottom and right coordinates) cannot be greater than (screen buffer height – 1) and (screen buffer width – 1), respectively. The function also fails if the Right member (or calculated right coordinate) is less than or equal to the Left member (or calculated left coordinate) or if the Bottom member (or calculated bottom coordinate) is less than or equal to the Top member (or calculated top coordinate).

In our case, the values of rectangle are the same (because Left and Top are zeroes) as values of info.srWindow rectangle after call of GetConsoleScreenBufferInfo(). But! SetConsoleWindowInfo() fails with next ::GetLastError()

@err,hr ERROR_INVALID_PARAMETER : The parameter is incorrect.   unsigned int

If I swap calls of this two functions:

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

then I will have the same error.

So, how can I use SetConsoleScreenBufferSize() and SetConsoleWindowInfo() correctly ?

like image 800
grisha Avatar asked Oct 22 '25 06:10

grisha


1 Answers

SetConsoleWindowInfo() does not reposition the console window on the screen. The name of this function is misleading. It rather scrolls the current visible portion inside the console window. See this sample here.

If you want to set the position of a console window that runs your programm, use code such as:

HWND hwnd = GetConsoleWindow();
RECT rect = {100, 100, 300, 500};
MoveWindow(hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,TRUE);
like image 177
RED SOFT ADAIR Avatar answered Oct 23 '25 19:10

RED SOFT ADAIR