C指针原理(35)-Ncurses-文本终端的图形

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C指针原理(35)-Ncurses-文本终端的图形相关的知识,希望对你有一定的参考价值。

下面将全屏编辑器修改一下,通过panel的支持,让它能同时打开3个窗口编辑不同的内容,同时对3个窗口的内容进行保存。

效果如下:

#include?<locale.h>

#include?<stdio.h>

#include?<panel.h>

#include?<ncurses.h>

//[email protected]

//date:2014/1/17

int?isExist(char?*filename)

{

?????????return?(access(filename,?0)?==?0);

}

int?main(int?argc,?char?*argv[])

{

????????MEVENT?event;

????????setlocale(LC_ALL,"");

????????initscr();

????????clear();

????????noecho();

????????cbreak();

????????if(has_colors()?==?FALSE)

????????{

????????endwin();

????????printf("你的终端不支持色彩! ");

????????return?(1);

????????}

????????start_color();?/启动color?机制/

????????mvprintw(3,COLS/2-10,"简单编辑器-仅限于单个屏幕的编辑");

????????mvprintw(4,COLS/2-20,"【F9读保存内容,F10存盘,F11退出,F12删除整行,TAB换窗口】");

????????refresh();

????????init_pair(1,?COLOR_GREEN,?COLOR_BLACK);

????????init_pair(2,?COLOR_BLUE,?COLOR_BLACK);

??????? init_pair(3,?COLOR_RED,COLOR_BLACK);?

WINDOW?*mywins[3];

PANEL?*top;

??????? PANEL?*mypanels[3];

char?filename[10];

????????int?width=COLS-18;

????????int?height=LINES-18;

????????int?x,y;

int?begin_y=5;int?begin_x=5;

int?i;

for(i?=?0;?i?<?3;?+++i)

{

????????mywins[i]=newwin(height,width,begin_y,begin_x);//新窗口(行,列,begin_y,begin_x)

??????? ????????keypad(mywins[i],TRUE);

????????wattron(mywins[i],COLOR_PAIR(i+1));

mypanels[i]?=?new_panel(mywins[i]);

box(mywins[i],ACS_VLINE,ACS_HLINE);

????????wattroff(mywins[i],COLOR_PAIR(i+1));

begin_y+=4;begin_x+=4;

}

set_panel_userptr(mypanels[0],mypanels[1]);

set_panel_userptr(mypanels[1],mypanels[2]);

set_panel_userptr(mypanels[2],mypanels[0]);

top?=?mypanels[2];

update_panels();

doupdate();

int?nowwinid=2;

sprintf(filename,"myed%d.dat",nowwinid);

getyx(mywins[nowwinid],y,x);

??????? ++y;++x;

????????mmask_t?oldmousemask;

????????int?ans=0;

????????FILE?*fp2=NULL;

????????FILE?*fp1=NULL;

????????mousemask(ALL_MOUSE_EVENTS,?&oldmousemask);

????????while(1){

????????????????int?c=mvwgetch(mywins[nowwinid],y,x);

????????????????switch(c)

????????????????{???????case?KEY_MOUSE:

????????????????????????if(getmouse(&event)?==?OK)

????????????????????????{???????/?When?the?user?clicks?left?mouse?button?/

????????????????????????????????if(event.bstate?&?BUTTON1_PRESSED)

????????????????????????????????{

????????????????????????????????????????????????y=event.y-7;x=event.x-7;

????????????????????????????????????????????????wmove(mywins[nowwinid],y,x);

????????????????????????????????}

????????????????????????}

????????????????????????break;

????????????????????????case?KEY_BACKSPACE:

????????????????????????????????--x;

????????????????????????????????if?(x<1){

????????????????????????????????????????--y;x=width-2;

????????????????????????????????}

????????????????????????????????if?(y<1){

????????????????????????????????????????y=height-2;

????????????????????????????????}

????????????????????????????????mvwprintw(mywins[nowwinid],y,x,"?");

????????????????????????????????break;

????????????????????????case?KEY_RIGHT:

????????????????????????????????++x;

????????????????????????????????if?(x>=width-1)?{

????????????????????????????????????????++y;

????????????????????????????????????????x=1;

????????????????????????????????}

????????????????????????????????break;

????????????????????????case?KEY_LEFT:?--x;

????????????????????????????????if?(x<1){

????????????????????????????????????????--y;

????????????????????????????????????????x=width-2;

????????????????????????????????}

????????????????????????????????break;

????????????????????????case?KEY_UP:

????????????????????????????????--y;

????????????????????????????????if?(y<1){

????????????????????????????????????????y=height-2;

????????????????????????????????}

????????????????????????????????break;

????????????????????????case?KEY_DOWN:

????????????????????????????????++y;

????????????????????????????????if?(y>=height-1){

????????????????????????????????????????y=1;

????????????????????????????????}

????????????????????????????????break;

????????????????????????case?10:

????????????????????????????????++y;

????????????????????????????????if?(y>=height-1){

????????????????????????????????????????y=1;

????????????????????????????????}

????????????????????????????????break;

????????????????????????case?KEY_F(11):

????????????????????????????????//退出

????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");

????????????????????????????????mvprintw(LINES-3,2,"退出编辑器吗??????");

????????????????????????????????mvprintw(LINES-2,2,"????");

????????????????????????????????mvprintw(LINES-1,2,"????? ");

????????????????????????????????refresh();

????????????????????????????????ans=getch();

????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)

????????????????????????????????{

????????????????????????????????????????mvprintw(LINES-2,2,"是 ");

????????????????????????????????????????refresh();

????????????????????????????????????????wattroff(mywins[nowwinid],COLOR_PAIR(1));

????????????????????????????????????????mousemask(oldmousemask,NULL);

????????????????????????????????????????endwin();

????????????????????????????????????????return?0;

????????????????????????????????}else

????????????????????????????????????????mvprintw(LINES-2,2,"否 ");

????????????????????????????????????????refresh();

????????????????????????????????break;


case?9:

top?=?(PANEL?*)panel_userptr(top);

top_panel(top);

update_panels();

doupdate();

nowwinid=(++nowwinid)%3;

sprintf(filename,"myed%d.dat",nowwinid);

break;

????????????????????????case?KEY_F(10):

????????????????????????????????//存盘

????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");

????????????????????????????????mvprintw(LINES-3,2,"保存当前内容吗??????");

????????????????????????????????mvprintw(LINES-2,2,"????");

????????????????????????????????mvprintw(LINES-1,2,"?????
");

????????????????????????????????refresh();

????????????????????????????????ans=getch();

????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)

????????????????????????????????{

????????????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");

????????????????????????????????????????fp1?=?fopen(filename,"wb");

????????????????????????????????????????if?(fp1!=NULL){

????????????????????????????????????????????????int?jg=?putwin(mywins[nowwinid],fp1);

????????????????????????????????????????????????fclose(fp1);

????????????????????????????????????????????????if?(jg==OK)??mvprintw(LINES-1,2,"保存成功!
");

????????????????????????????????????????}

????????????????????????????????????????mvprintw(LINES-3,2,"保存当前内容吗??????");

????????????????????????????????????????mvprintw(LINES-2,2,"是
");

????????????????????????????????????????refresh();

????????????????????????????????}else

????????????????????????????????????????mvprintw(LINES-2,2,"否
");

????????????????????????????????????????refresh();

????????????????????????????????break;

????????????????????????case?KEY_F(9):

????????????????????????????????//读取存盘

????????????????????????????????mvprintw(LINES-3,2,"????????????????????");

????????????????????????????????mvprintw(LINES-3,2,"读取保存内容吗?????");

????????????????????????????????mvprintw(LINES-2,2,"????");

????????????????????????????????mvprintw(LINES-1,2,"?????
");

????????????????????????????????refresh();

????????????????????????????????ans=getch();

????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)

????????????????????????????????{

????????????????????????????????????????if?(isExist(filename))?{

????????????????????????????????????????fp2?=?fopen(filename,"rb");

????????????????????????????????????????if?(fp2!=NULL){

????????????????????????????????????????????????WINDOW?*newwin=getwin(fp2);

????????????????????????????????????????????????if?(newwin!=NULL)?{

????????????????????????????????????????????????????????WINDOW?*temp=mywins[nowwinid];

????????????????????????????????????????????????????????mywins[nowwinid]=newwin;

delwin(temp);

PANEL?*temppan=mypanels[nowwinid];

mypanels[nowwinid]?=?new_panel(mywins[nowwinid]);

del_panel(temppan);

set_panel_userptr(mypanels[0],mypanels[1]);

set_panel_userptr(mypanels[1],mypanels[2]);

set_panel_userptr(mypanels[2],mypanels[0]);

top?=?mypanels[nowwinid];

top_panel(top);

update_panels();

doupdate();

????????????????????????????????????????????????????????mvprintw(LINES-1,2,"读取成功!
");

????????????????????????????????????????????????}

????????????????????????????????????????????????fclose(fp2);

????????????????????????????????????????}

????????????????????????????????????????}

????????????????????????????????????????mvprintw(LINES-3,2,"读取保存内容吗?????");

????????????????????????????????????????mvprintw(LINES-2,2,"是
");

????????????????????????????????????????refresh();

????????????????????????????????}else

????????????????????????????????????????mvprintw(LINES-2,2,"否
");

????????????????????????????????????????refresh();

????????????????????????????????break;

????????????????????????case?KEY_F(12):

????????????????????????????????//删除某行

????????????????????????????????wdeleteln(mywins[nowwinid]);

????????????????????????????????winsertln(mywins[nowwinid]);

????????????????????????????????box(mywins[nowwinid],ACS_VLINE,ACS_HLINE);

????????????????????????????????break;

????????????????????????case?KEY_DC:

????????????????????????????????//删除某字符

????????????????????????????????mvwprintw(mywins[nowwinid],y,x,"?");

????????????????????????????????break;

????????????????????????default:

????????????????????????????????mvwprintw(mywins[nowwinid],y,x,"%c",c);

????????????????????????????????++x;

????????????????????????????????if?(x>=width-1){

????????????????????????????????????????++y;

????????????????????????????????????????x=1;

????????????????????????????????}

????????????????????????????????if?(y>=height-1){

????????????????????????????????????????y=1;

????????????????????????????????}

doupdate();

????????????????}

????????}

return?0;

}

[email protected]:~/cursestest?%?gcc?-lncursesw?-lpanel?a.c?-o?mytest

[email protected]:~/cursestest?%?./mytest

编写含有表单的程序,一般步骤如下:

1.?初始化并进入curses

2.?用new_field()函数创建表单域。你可以指定域的高度,宽度以及它在表单中的位

置。

3.?指定已创建的表单域所作用的表单,并用new_form()函数创建表单。

4.?用post_form()函数来递送表单,并刷新屏幕。

5.?用一个循环来处理用户请求,通过form_driver()函数对表单做相应的更新。

6.?用unpost_form()函数取消表单的递送。

7.?用free_form()函数释放已分配给表单的内存。

8.?用free_field()函数释放已分配给菜单项的内存。

9.?退出curses?模式

下面演示了表单的操作基础

#include?<form.h>

int?main()

{?

FIELD?*field[3];

FORM?*my_form;

int?ch;

/*?初始化curses?*/

initscr();

cbreak();

noecho();

keypad(stdscr,?TRUE);

/*?初始化表单域*/

field[0]?=?new_field(1,?10,?4,?18,?0,?0);

field[1]?=?new_field(1,?10,?6,?18,?0,?0);

field[2]?=?NULL;

/*?设置表单域*/

set_field_back(field[0],A_UNDERLINE);?/*?为选项打印一条下滑线*/

field_opts_off(field[0],O_AUTOSKIP);

/*?在域(输入框)填满后光标不会自动跳到下一个表单域*/

set_field_back(field[1],A_UNDERLINE);

field_opts_off(field[1],O_AUTOSKIP);

/*?创建并递送表单*/

my_form?=?new_form(field);

post_form(my_form);

refresh();

mvprintw(4,?10,?"name:");

mvprintw(6,?10,?"age:");

refresh();

move(4,15);

/*?用循环获取用户请求,F12退出*/

while((ch?=?getch())?!=?KEY_F(12))

{?

switch(ch)

{?

case?KEY_DOWN:

/*?跳至下一个表单域*/

form_driver(my_form,REQ_NEXT_FIELD);

/*?跳到当前缓冲的末尾*/

/*?精确地在输入最后一个后字符跳出这个表单域*/

form_driver(my_form,REQ_END_LINE);

break;

case?KEY_UP:

/*?移动到前一个表单域*/

form_driver(my_form,REQ_PREV_FIELD);

form_driver(my_form,REQ_END_LINE);

break;

default:

/*?如果输入的是普通字符,?就把它打印出来*/

form_driver(my_form,ch);

break;

}

}

/*?取消表单并释放内存*/

unpost_form(my_form);

free_form(my_form);

free_field(field[0]);

free_field(field[1]);

endwin();

return?0;

}

[email protected]:~/cursestest?%?gcc?-lncursesw?-lform?b.c?-o?mytest

[email protected]:~/cursestest?%?./mytest

以上是关于C指针原理(35)-Ncurses-文本终端的图形的主要内容,如果未能解决你的问题,请参考以下文章

C指针原理(33)-Ncurses-文本终端的图形

C指针原理(34)-Ncurses-文本终端的图形

C指针原理(34)-Ncurses-文本终端的图形

在没有 ncurses 的 C/C++ 中编写“真正的”交互式终端程序,如 vim、htop、...

Ncurses入门-安装与使用

基于文本图形(ncurses)的文本搜索工具 ncgrep