1
#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 是窗口大小的减小,但由于某种原因它不起作用。似乎它不喜欢低于某个宽高比。

是否有更多信息说明为什么我可以做的调整大小似乎受到限制,即使这些数字远未接近我的屏幕可以容纳的限制?这是 64 位 Windows 上的 pdcurses。

4

1 回答 1

3

resize_term是一个 ncurses 函数。

resize_term功能不会改变终端的大小;它改变了ncurses 假定的大小。

由于 curses 没有显示任何内容,并且(请参阅手册页中的注释),您的示例没有getch显示任何内容,curses 没有任何内容可以显示为更改。

有趣的是,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>来表示它与curses(或ncurses)的区别。我认为问题是关于 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;
}

代码看起来......很奇怪,除了两次做同样的事情。参考SetConsoleWindowInfo的 MSDN 描述, rectangle 参数是一个in参数(未修改)。按照参数通过,它正在获取请求的大小,并连续尝试

  1. 设置请求的大小,或
  2. 设置请求的行,同时将列减少到初始大小的一半,或者
  3. 设置请求的列,同时将行减少到初始大小的一半。

也许它这样做两次的原因是因为控制台 API 中有一些不确定的行为。代码中的注释没有帮助。

于 2016-10-27T08:47:24.570 回答