C 教室:不重叠的窗户仍然互相碰撞
我正在尝试创建一个简单的应用程序,它使用一个支持scrollok()的文本窗口作为示例应用程序,但是我很难让我的窗口正确对齐。应用程序的布局应该是这样的:C 教室:不重叠的窗户仍然互相碰撞,c,ncurses,curses,C,Ncurses,Curses,我正在尝试创建一个简单的应用程序,它使用一个支持scrollok()的文本窗口作为示例应用程序,但是我很难让我的窗口正确对齐。应用程序的布局应该是这样的: (Not to Scale) +------------------------+ | | | 80x22 | | scrollok() text dump | | | |
(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);
这是正确的一半。我还发现换行符是在窗口底部创建额外空行的原因。我根本没有想到这一点。