Resize_term в pdcurses работает случайно

#include <iostream>
#include <curses.h>
#include "SourceFiles/generalFunc.h"
int main()
{

initscr();
int x = resize_term(51, 79);
sleepMilli(5000); //sleep for 5 seconds
endwin();
std::cout << x << " " << int(ERR) << " " << int(OK);

}

Размер экрана на моем компьютере не изменяется в этом случае, несмотря на то, что x возвращается назад 0 (указывая, что изменение размера прошло успешно). Он остается того же размера, что и исходное окно терминала. Однако, если я увеличу 79 до 80 или уменьшу с 51 до 50, размер экрана на моем экране изменится, как обычно. Мой экран достаточно большой, чтобы вмещать эти размеры на милю — даже если изменить размер окна с 80 на 79 — это УМЕНЬШЕНИЕ размера окна, но по какой-то причине он не работает. Кажется, что не нравится опускаться ниже определенного соотношения сторон.

Есть ли какая-либо дополнительная информация о том, почему, по-видимому, существует ограничение на изменение размера, которое я могу сделать, даже если эти цифры не приближаются к пределу, который может удерживать мой экран? Это pdcurses на 64-битной Windows.

1

Решение

resize_term является функцией ncurses.

resize_term функция не меняет ваш терминала размер; это меняет размер, который нкурс предполагает.

Поскольку проклятиями ничего не отображается, а (см. примечания на странице руководства), ваш пример не getch, нечего показывать проклятиями как изменение.

Интересно, что PDCurses реализовали функцию с тем же именем (вдохновлено ncurses: их несколько), которая описана по-другому. Цитирование из комментариев в pdcurses/initscr.c:

    resize_term() is effectively two functions: When called with
nonzero values for nlines and ncols, it attempts to resize the
screen to the given size. When called with (0, 0), it merely
adjusts the internal structures to match the current size after
the screen is resized by the user. On the currently supported
platforms, this functionality is mutually exclusive: X11 allows
user resizing, while DOS, OS/2 and Win32 allow programmatic
resizing. If you want to support user resizing, you should check
for getch() returning KEY_RESIZE, and/or call is_termresized()
at appropriate times; if either condition occurs, call
resize_term(0, 0). Then, with either user or programmatic
resizing, you'll have to resize any windows you've created, as
appropriate; resize_term() only handles stdscr and curscr.

и функция начинается с этого:

int resize_term(int nlines, int ncols)
{
PDC_LOG(("resize_term() - called: nlines %d\n", nlines));

if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR)
return ERR;

SP->lines = PDC_get_rows();
LINES = SP->lines - SP->linesrippedoff - SP->slklines;
SP->cols = COLS = PDC_get_columns();

что в свою очередь вызывает это для консоли Windows:

int PDC_resize_screen(int nlines, int ncols)
{
SMALL_RECT rect;
COORD size, max;

if (nlines < 2 || ncols < 2)
return ERR;

max = GetLargestConsoleWindowSize(pdc_con_out);

rect.Left = rect.Top = 0;
rect.Right = ncols - 1;

if (rect.Right > max.X)
rect.Right = max.X;

rect.Bottom = nlines - 1;

if (rect.Bottom > max.Y)
rect.Bottom = max.Y;

size.X = rect.Right + 1;
size.Y = rect.Bottom + 1;

_fit_console_window(pdc_con_out, &rect);
SetConsoleScreenBufferSize(pdc_con_out, size);
_fit_console_window(pdc_con_out, &rect);
SetConsoleScreenBufferSize(pdc_con_out, size);
SetConsoleActiveScreenBuffer(pdc_con_out);

return OK;
}

так что вы можете увидеть результат несовместимой функции. (Есть порт для SDL, который похож). Есть несколько вопросов, связанных с поведением PDCurses:

Тем не менее, PDCurses обычно устанавливает свой заголовочный файл как <xcurses.h> обозначать его отличия от проклятий (или курсов). Я предположил, что вопрос был о ncurses, и проблема в том, что функция библиотеки делает путаницу:

Возвращаясь к PDCurses, странно, что он делает те же два вызова дважды. Функция PDCurses делает несколько попыток, уменьшая заданные значения, пока они не подойдут — или нет:

 /* Calls SetConsoleWindowInfo with the given parameters, but fits them
if a scoll bar shrinks the maximum possible value. The rectangle
must at least fit in a half-sized window. */

static BOOL _fit_console_window(HANDLE con_out, CONST SMALL_RECT *rect)
{
SMALL_RECT run;
SHORT mx, my;

if (SetConsoleWindowInfo(con_out, TRUE, rect))
return TRUE;

run = *rect;
run.Right /= 2;
run.Bottom /= 2;

mx = run.Right;
my = run.Bottom;

if (!SetConsoleWindowInfo(con_out, TRUE, &run))
return FALSE;

for (run.Right = rect->Right; run.Right >= mx; run.Right--)
if (SetConsoleWindowInfo(con_out, TRUE, &run))
break;

if (run.Right < mx)
return FALSE;

for (run.Bottom = rect->Bottom; run.Bottom >= my; run.Bottom--)
if (SetConsoleWindowInfo(con_out, TRUE, &run))
return TRUE;

return FALSE;
}

Код выглядит … странно, кроме того, что делает одно и то же дважды. Ссылаясь на описание MSDN SetConsoleWindowInfo, параметр прямоугольника является в параметр (без изменений). После прохождения параметров он принимает запрошенный размер и пытается последовательно

  1. установить требуемый размер или
  2. установить запрошенные строки при уменьшении столбцов до половины исходного размера, или
  3. установите запрошенные столбцы, уменьшив количество строк до половины исходного размера.

Возможно, причина, по которой он делает это дважды, заключается в том, что в консольном API есть некоторое неопределенное поведение. Комментарии в коде не помогают.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]