C 教室:不重叠的窗户仍然互相碰撞

C 教室:不重叠的窗户仍然互相碰撞,c,ncurses,curses,C,Ncurses,Curses,我正在尝试创建一个简单的应用程序,它使用一个支持scrollok()的文本窗口作为示例应用程序,但是我很难让我的窗口正确对齐。应用程序的布局应该是这样的: (Not to Scale) +------------------------+ | | | 80x22 | | scrollok() text dump | | | |

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

       (Not to Scale)
+------------------------+
|                        |
|        80x22           |
| scrollok() text dump   |
|                        |
|                        |
+*80x1: Status Bar ******+
= 80x1: Input Bar        +
问题:我发现我需要按正确的顺序刷新窗口。首先是wrefresh(文本),其次是wrefresh(状态),最后是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);
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
int-ch;
char-buf[256];
initscr();
键盘(stdscr,真);
诺尔();
cbreak();
noecho();
/*我们需要跟踪的各种窗口*/
窗口*状态;
窗口*输入;
窗口*文本;
/*我们需要时刻注意航站楼的安全*/
int行;
int col;
getmaxyx(stdscr、row、col);
/*
*如果我们有颜色支持,打开它。
*/
如果(有颜色()
{
启动颜色();
/* 
*标准的黑色。
*/
初始对(1,红色,黑色);
初始对(2,颜色为绿色,颜色为黑色);
初始对(3,颜色为黄色,颜色为黑色);
初始对(4,颜色为蓝色,颜色为黑色);
初始对(5,青色,黑色);
初始对(6,颜色为洋红色,颜色为黑色);
初始对(7,白色,黑色);
/*第8对是状态栏的颜色*/
初始对(8,白色,蓝色);
}
/*将文本绘制为可滚动的*/
text=newwin(第1行,第0列,第0列);
scrollok(文本,TRUE);
/*绘制状态栏*/
状态=newwin(1,列,第2行,0);
wbkgd(状态,颜色对(8));
wprintw(状态,“%ix%i”,列,行);
/*绘制输入窗口*/
输入=newwin(1,列,行,0);
键盘(输入,真);
wmove(输入,0,0);
/*刷新所有窗口*/
刷新();
(文本);
(身份);;
输入;
对于(;;)
{
ch=wgetch(输入);
开关(ch)
{
案例编号:
案例键向下:
打破
案例键左:
getyx(输入、行、列);
wmove(输入,行,列-1);
输入;
打破
案例编号:右:
getyx(输入、行、列);
wmove(输入、行、列+1);
输入;
打破
案例8:/*与键_退格相同*/
案例127:/*删除*/
大小写键\u退格:
getyx(输入、行、列);
wmove(输入,行,列-1);
wdelch(输入);
输入;
打破
案例'\r':
案例“\n”:
案例密钥发送:
大小写键输入:
memset(buf,0256);
getyx(输入、行、列);
wmove(输入,0,0);
/*TODO:Plz2rethink*/
winnstr(输入、buf、col);
wclrtoeol(输入);
wprintw(文本,“%s\n”,buf);
(文本);
输入;
打破
违约:
waddch(输入,ch);
输入;
打破
}
}
endwin();
printf(“调试:BUF:%s\n”,BUF);
出口(0);
}

在图表中,状态和输入需要两行,文本需要两行,但代码没有

text = newwin(row - 1, col, 0, 0);
使用除1行以外的所有行,因此状态行被覆盖。应该是

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

这是正确的一半。我还发现换行符是在窗口底部创建额外空行的原因。我根本没有想到这一点。