我已经阅读了window(3NCURSES)
手册页,但是我无法完全理解mvwin()
函数的实际作用以及子窗口的作用。
下面的代码创建一个带有标题“ Window”和边框的窗口,它还创建一个用于打印y,x位置而不破坏父窗口边框的子窗口。然后它将父窗口移动到新位置,但结果却不是我期望的:
移动窗口后,窗口边框和文本的轮廓不会在旧位置自动删除。
移动后,将文本写入子窗口,然后在新旧位置输出文本。
移动后,父窗口具有新的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;
}
答案 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
的描述过于简短和含糊,无法使用。