ncurses:非重叠窗口仍然互相破坏

时间:2013-12-02 08:21:06

标签: c ncurses curses

我正在尝试创建一个简单的应用程序,它使用一个启用了scrolllok()的文本窗口作为示例应用程序,但是我很难让我的窗口正确排列。应用程序的布局应该是这样的:

       (Not to Scale)
+------------------------+
|                        |
|        80x22           |
| scrollok() text dump   |
|                        |
|                        |
+*80x1: Status Bar ******+
= 80x1: Input Bar        +

问题:我发现我需要以正确的顺序刷新窗口。首先是wrefresh(文本),第二个是wrefresh(status),最后是wrefresh(输入)。启用了scrollok()的窗口功能,直到您向下到最后一行文本。然后它破坏了我的状态栏:它永远消失了。

如果我缩短了启用了scrollok()的窗口,它就不会正确排列到状态栏,并且终端窗口上总会有一个额外的空行文本。我正在寻找关于如何使滚动窗口与状态栏对齐的建议,而不是让它完全消失。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <curses.h>

int main(int argc, char **argv)
{
    int ch;
    char buf[256];

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

    /* Various windows we need to keep track of. */
    WINDOW *status;
    WINDOW *input;
    WINDOW *text;

    /* We need to always be aware of the zie of the terminal */
    int row;
    int col;
    getmaxyx(stdscr, row, col);

    /*
     * If we have color support, turn it on.
     */
    if (has_colors())
    {
        start_color();

        /* 
         * Standard <X> on BLACK.
         */
        init_pair(1, COLOR_RED,     COLOR_BLACK);
        init_pair(2, COLOR_GREEN,   COLOR_BLACK);
        init_pair(3, COLOR_YELLOW,  COLOR_BLACK);
        init_pair(4, COLOR_BLUE,    COLOR_BLACK);
        init_pair(5, COLOR_CYAN,    COLOR_BLACK);
        init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
        init_pair(7, COLOR_WHITE,   COLOR_BLACK);

        /* Pair 8 is the color of our status bar */
        init_pair(8, COLOR_WHITE,   COLOR_BLUE);
    }

    /* Paint the text scrollable */
    text = newwin(row - 1, col, 0, 0);
    scrollok(text, TRUE);

    /* Paint the status bar */
    status = newwin(1, col, row - 2, 0);
    wbkgd(status, COLOR_PAIR(8));       
    wprintw(status, "%ix%i", col, row);

    /* Paint the input window */
    input = newwin(1, col, row, 0);
    keypad(input, TRUE);
    wmove(input, 0, 0);

    /* Refresh all windows */
    refresh();
    wrefresh(text);
    wrefresh(status);
    wrefresh(input);

    for (;;)
    {
                ch = wgetch(input);
        switch(ch)
        {
        case KEY_UP:
        case KEY_DOWN:
            break;
        case KEY_LEFT:
            getyx(input, row, col);
            wmove(input, row, col -1); 
            wrefresh(input);
            break;
        case KEY_RIGHT:
            getyx(input, row, col);
            wmove(input, row, col +1); 
            wrefresh(input);
            break;
        case 8:     /* same as KEY_BACKSPACE */
        case 127:   /* delete */
        case KEY_BACKSPACE:
            getyx(input, row, col);
            wmove(input, row, col -1); 
            wdelch(input);
            wrefresh(input);
            break;
        case '\r':
        case '\n':
        case KEY_SEND:
        case KEY_ENTER:
            memset(buf, 0, 256);
            getyx(input, row, col);
            wmove(input, 0, 0);
            /* TODO: Plz2rethink */
            winnstr(input, buf, col);
            wclrtoeol(input);
            wprintw(text, "%s\n", buf);
            wrefresh(text);
            wrefresh(input);
            break;
        default:
            waddch(input, ch);
            wrefresh(input);
            break;
        }
    }

    endwin();
    printf("DEBUG: BUF: %s\n", buf);
    exit(0);
}

1 个答案:

答案 0 :(得分:0)

在你的图表中,你想要2行用于状态和输入以及用于文本,但代码有

text = newwin(row - 1, col, 0, 0);

使用除1行之外的所有行,因此状态行将被覆盖。它应该是

text = newwin(row - 2, col, 0, 0);