覆盖一个窗口

时间:2017-02-13 00:44:57

标签: c ncurses curses

我正在制作一个带有ncurses的程序,它将屏幕分成两个窗口。顶部屏幕可以接受输入,按“#”可以将所有文本向下移动到底部窗口并擦除顶部窗口。在我的代码中,我试图使用copywin()来替换底部窗口,但它不会在第二个窗口中粘贴措辞。这就是我的......

#include <ncurses.h>

int main(int argc, char *argv[])
{
// Declare variables for windows and sizes
WINDOW *top_win, *bottom_win;
int maxx, maxy, halfy, flag = 0, ch;

// Start curses
initscr();
noecho();
refresh();

// get the max x's and y's
getmaxyx(stdscr, maxy, maxx);
halfy = maxy >> 1;

// Start color
start_color();
init_pair(1, COLOR_BLACK, COLOR_WHITE);
init_pair(2, COLOR_WHITE, COLOR_CYAN);
init_pair(3, COLOR_RED, COLOR_WHITE);

// Make windows
top_win = newwin(halfy, maxx, 0, 0);
wbkgd(top_win, COLOR_PAIR(1));
wrefresh(top_win);

bottom_win = newwin(halfy, maxx, halfy, 0);
wbkgd(bottom_win, COLOR_PAIR(2));
wrefresh(bottom_win);

// Allow functions keys
keypad(top_win, TRUE);
keypad(bottom_win, TRUE);

// while loop to get input
while((ch = getch()) != '`')
    {
        if(ch == '@')
            {
                if(flag == 1)
                    {
                        flag = 0;
                    }
                else
                    {
                        flag = 1;
                    }
            }
        else if(ch == '#')
            {
                //waddstr(bottom_win, "testing");
                copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE);
                //overwrite(top_win, bottom_win);
                //werase(top_win);
            }
        else if(flag != 1)
            {
                waddch(top_win, ch | COLOR_PAIR(1));
            }
        else if(flag == 1)
            {
                waddch(top_win, ch | COLOR_PAIR(3));
            }
        wrefresh(top_win);
        wrefresh(bottom_win);
    }

// end curses
delwin(top_win);
delwin(bottom_win);
endwin();
return 0;
}

我知道我可以使用'#'字符打印到窗口,因为我已经注释掉了测试声明。我也尝试过使用overwrite(),但这也没用。我只是把论点搞砸了,还是别的什么?有任何想法吗?提前谢谢!

2 个答案:

答案 0 :(得分:3)

copywin检查给定的行/列和decides that your destination rectangle doesn't lie completely within the destination window。这是您的计划的快速解决方案:

--- foo.c.orig  2017-02-13 16:13:12.000000000 -0500
+++ foo.c       2017-02-13 16:30:18.037987489 -0500
@@ -51,7 +51,7 @@
         else if(ch == '#')
             {
                 //waddstr(bottom_win, "testing");
-                copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE);
+                copywin(top_win, bottom_win, 0, 0, 0, 0, halfy - 1, maxx - 1, TRUE);
                 //overwrite(top_win, bottom_win);
                 //werase(top_win);
             }
@@ -73,4 +73,3 @@
 endwin();
 return 0;
 }

行和列的编号从零到最后一行/列(比窗口大小少一个),所以我从 dmaxrow dmaxcol 中减去一行参数。第五个参数 dminrow 超出了窗口的底部。

ncurses检查参数。关于兼容性和可移植性,使用Solaris curses运行相同的程序(将“ncurses.h”更改为“curses.h”)会转储核心。

手册页可以改进,但关于colors

已经足够清楚了
  仅复制两个窗口重叠的文本

答案 1 :(得分:1)

我对其工作原理没有一个很好的解释,但只要xoffyoff在下面的代码中至少为1,上部窗口中的数据复制到下部窗口确定(并从上部窗口清除)。颜色不会被复制。如果任一偏移量为0,则不复制数据。字符串testing添加在下部窗口的左上角 - 可以省略,复制的材料仍然正常。

#include <ncurses.h>

int main(void)
{
    // Declare variables for windows and sizes
    WINDOW *top_win, *bottom_win;
    int maxx, maxy, halfy, flag = 0, ch;

    // Start curses
    initscr();
    noecho();
    refresh();

    // get the max x's and y's
    getmaxyx(stdscr, maxy, maxx);
    halfy = maxy >> 1;

    // Start color
    start_color();
    init_pair(1, COLOR_BLACK, COLOR_WHITE);
    init_pair(2, COLOR_WHITE, COLOR_CYAN);
    init_pair(3, COLOR_RED, COLOR_WHITE);

    // Make windows
    top_win = newwin(halfy, maxx, 0, 0);
    wbkgd(top_win, COLOR_PAIR(1));
    wrefresh(top_win);

    bottom_win = newwin(halfy, maxx, halfy, 0);
    wbkgd(bottom_win, COLOR_PAIR(2));
    wrefresh(bottom_win);

    // Allow functions keys
    // keypad(top_win, TRUE);
    // keypad(bottom_win, TRUE);

    // while loop to get input
    int xoff = 1;
    int yoff = 1;
    while ((ch = getch()) != '`')
    {
        if (ch == '@')
        {
            if (flag == 1)
            {
                flag = 0;
            }
            else
            {
                flag = 1;
            }
        }
        else if (ch == '#')
        {
            waddstr(bottom_win, "testing");
            // copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE);
            copywin(top_win, bottom_win, 0, 0, yoff, xoff, halfy-yoff, maxx-xoff, TRUE);
            // overwrite(top_win, bottom_win);
            werase(top_win);
        }
        else if (flag != 1)
        {
            waddch(top_win, ch | COLOR_PAIR(1));
        }
        else if (flag == 1)
        {
            waddch(top_win, ch | COLOR_PAIR(3));
        }
        wrefresh(top_win);
        wrefresh(bottom_win);
    }

    // end curses
    delwin(top_win);
    delwin(bottom_win);
    endwin();
    return 0;
}

使用本地-lncurses库在Mac上运行带有GCC 6.3.0的macOS Sierra 10.12.3进行测试。