【问题标题】:Moving windows in ncurses在 ncurses 中移动窗口
【发布时间】:2018-11-23 11:06:16
【问题描述】:

我已阅读 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;
}

【问题讨论】:

    标签: ncurses curses


    【解决方案1】:

    显然不是:使用 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 的描述过于简短和模糊,没有任何用处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 2016-11-11
      • 1970-01-01
      相关资源
      最近更新 更多