以ncurses移动窗口

时间:2018-11-23 11:06:17

标签: ncurses curses

我已经阅读了window(3NCURSES)手册页,但是我无法完全理解mvwin()函数的实际作用以及子窗口的作用。

下面的代码创建一个带有标题“ Window”和边框的窗口,它还创建一个用于打印y,x位置而不破坏父窗口边框的子窗口。然后它将父窗口移动到新位置,但结果却不是我期望的:

  1. 移动窗口后,窗口边框和文本的轮廓不会在旧位置自动删除。

  2. 移动后,将文本写入子窗口,然后在新旧位置输出文本。

  3. 移动后,父窗口具有新的y,x坐标,但子窗口仍显示旧坐标。

我对ncurses没有太多的经验,也许我错过了一些东西,但是这种行为是完全不合逻辑的。如果我必须手动擦除旧位置的窗口并手动移动所有子窗口,那么这会否定使用ncurses的好处。我期望ncurses能够自动处理这些底层细节。

我对子窗口的理解是,它们用于将一个大窗口划分为较小的非重叠区域。因此,当父窗口移动或刷新时,其所有子窗口都应自动移动或刷新。这是正确的吗?

#include <assert.h>
#include <ncurses.h>
#include <unistd.h>

int main()
{
    WINDOW *win, *swin;
    int lines, cols, y, x;

    initscr();
    keypad(stdscr, TRUE);
    noecho();

    // Create window
    lines = 10; cols  = 40;
    y = 5; x = 5;
    win = newwin(lines, cols, y, x);
    assert(win != NULL);

    // Create window border
    box(win, 0, 0);
    mvwprintw(win, 0, 2, " Window ");

    // Create subwindow
    swin = subwin(win, lines-2, cols-2, y+1, x+1);
    assert(swin != NULL);
    // Print window and subwindow y,x
    mvwprintw(swin, 0, 0, "win y,x=%d,%d  swin y,x=%d,%d\n",
        getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));

    // Refresh
    wnoutrefresh(stdscr);
    wnoutrefresh(win);
    wnoutrefresh(swin);
    doupdate();

    sleep(2);

    // Move window
    y = 20; x = 40;
    mvwin(win, y, x);
    mvwprintw(swin, 0, 0, "win y,x=%d,%d  swin y,x=%d,%d\n",
        getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));

    // Refresh
    wnoutrefresh(stdscr);
    wnoutrefresh(win);
    wnoutrefresh(swin);
    doupdate();

    wgetch(swin);

    endwin();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

显然不是:使用Solaris 10进行快速检查可以得到相同的行为。您可能会发现ncurses意外变化的某些情况,但这不是其中一种。 FAQ指出了兼容性:

  

扩展名(与SVr4诅咒的偏差)只有在它们未修改API记录/观察到的行为的情况下才允许。

Solaris manual page不清楚,因为仅提及子窗口是关于移动它们

  

mvwin()例程移动窗口,以便左上角位于位置(x,y)。如果移动会导致窗口离开屏幕,则是错误的,并且窗口不会移动。允许移动子窗口,但应避免。

Solaris source code讲述了这个故事:它对子窗口不起作用。响应用户关于差异的评论,一些重新测试一段时间(early 2006)指出ncurses错误地尝试复制子窗口。这部分是ifdef'd out(因为仅删除它太有趣了)。由于mvwin剩下的工作量不多,因此实际的代码非常相似。

X / Open对mvwin的描述过于简短和含糊,无法使用。