2014-09-18 2 views
2

Я знаю, что есть много вопросов о том, как установить размер консоли. Но все найденные решения одинаковы для моего, и мой код не работает для меня.Установить размер окна консоли на Windows

Хорошо, поэтому для установки размера окна консоли мне нужны две функции. Это 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(). основной (код) испытания:

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 и 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()?

+0

'станд :: min' и' станд :: max' славные функции. вы можете использовать их для вычисления соответствующего промежуточного размера буфера и/или окна. не забудьте указать 'NOMINMAX' перед включением' '. –

+0

@ Cheersandhth.-Alf, ваш комментарий не поможет. Я знаю, как использовать функции min и max. Скажите мне, как вычислить соответствующий промежуточный размер буфера и/или окна для использования обеих функций для установки размера буфера экрана и размера окна. – grisha

+0

@userblahblah: re «не полезно», прекратите * ныть * и пойдете. Я делал это несколько раз. поэтому я знаю, что это тривиально, это просто работа. поэтому, чтобы повторить, перестань ныть. продолжай. –

ответ

1

От TurboVision port:

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; 
} 
+0

Задайте размер окна перед буфером, чтобы вы не делали буфер меньше окна, что приводило к сбою функции. – Krii

1

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); 
Смежные вопросы