gpt4 book ai didi

c++ - Pdcurses 的 resize_term 似乎随机工作

转载 作者:行者123 更新时间:2023-11-30 02:28:51 25 4
gpt4 key购买 nike

#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 ( indicating the resizing was successful ),但在这种情况下,我的计算机上的屏幕没有调整大小。它保持与原始终端窗口相同的大小。但是,如果我将 79 增加到 80,或者将 51 减少到 50,那么我的屏幕会像正常一样调整大小。我的屏幕足够大,可以容纳这些尺寸一英里 - 即使如此,从 80 变为 79 是窗口尺寸的减小,但由于某种原因它不起作用。它似乎不喜欢低于某个纵横比。

是否有更多信息说明为什么即使这些数字远不及我的屏幕可以容纳的限制,我也可以调整大小?这是 64 位 Windows 上的 pdcurses。

最佳答案

resize_term是一个 ncurses 函数。

resize_term 函数不会改变您的终端大小;它改变了 ncurses 假设的大小

由于 curses 没有显示任何内容,并且(参见 notes in the manual page ),您的示例不显示 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描述,矩形参数是 in 参数(未修改)。通过参数,它正在获取请求的大小,并连续尝试

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

它执行两次的原因可能是因为控制台 API 中存在一些不确定的行为。代码中的注释没有任何帮助。

关于c++ - Pdcurses 的 resize_term 似乎随机工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40273563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com