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

Posted

tags:

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

下面使用getwin和putwin完成对窗口内容的保存,而不是对整个屏幕,同时修正程序的几个小错误:

1、下面的操作提示在多次操作后会出现混乱。

2、退出后,endwin结束窗口,并且退出curses模式。

[email protected]:~/cursestest?%?cat?a.c


#include?<locale.h>

#include?<stdio.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-15,"【F9读保存内容,F10存盘,F11退出,F12删除整行】");

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

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

????????WINDOW?*win1;

????????int?width=COLS-14;

????????int?height=LINES-14;

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

????????win1=newwin(height,width,7,7);//新窗口(行,列,begin_y,begin_x)

????????keypad(win1,TRUE);

????????wattron(win1,COLOR_PAIR(1));

????????box(win1,ACS_VLINE,ACS_HLINE);

????????wrefresh(win1);

????????getyx(win1,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(win1,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(win1,y,x);

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

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

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

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

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

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

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

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

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

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

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

????????????????????????????????mvwprintw(win1,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(win1,COLOR_PAIR(1));

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

????????????????????????????????????????delwin(win1);

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

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

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

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

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

????????????????????????????????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("myet.dat","wb");

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

????????????????????????????????????????????????int?jg=?putwin(win1,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("myet.dat"))?{

????????????????????????????????????????fp2?=?fopen("myet.dat","rb");

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

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

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

????????????????????????????????????????????????????????delwin(win1);

????????????????????????????????????????????????????????win1=newwin;

????????????????????????????????????????????????????????wrefresh(win1);

????????????????????????????????????????????????????????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(win1);

????????????????????????????????winsertln(win1);

????????????????????????????????box(win1,ACS_VLINE,ACS_HLINE);

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

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

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

????????????????????????????????mvwprintw(win1,y,x,"?");

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

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

????????????????????????????????mvwprintw(win1,y,x,"%c",c);

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

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

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

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

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

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

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

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

????????????????????????????????wrefresh(win1);

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

????????}

}

执行

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

[email protected]:~/cursestest?%?./mytest
面板库(Panel?Library)能方便得管理面板:

1.?使用newwin()函数创建一个窗口,它将添加到面板里。

2.?创建面板(利用所创建的窗口)并将面板依据用户指定的可见顺序压进栈。调用

new_panel()函数即可创建该面板。

3.?调用update_panels()函数就可将面板按正确的顺序写入虚拟屏幕,调用doupdate()函

数就能让面板显示出来。

4.?show_panel(),?hide_panel(),?move_panel()等函数分别用来对面板进行显示、隐藏、移

动等操作时,可以使用panel_hidden()和panel_window()这两个辅助函数。你也可以

使用用户指针来存储面板的数据,set_panel_userptr()?和panel_userptr()函数分别用

来设置和取得一个面板的用户指针。

5.?当一个面板使用完毕后,用del_panel()函数就可删除指定的面板。

下面是一个例子

[email protected]:~/cursestest?%?cat?x.c


#include?<panel.h>

int?main()

{

WINDOW?*my_wins[3];

PANEL?*my_panels[3];

int?lines?=?10,?cols?=?40,?y?=?2,?x?=?4,?i;

initscr();

cbreak();

noecho();

/*?为每个面板创建窗口*/

my_wins[0]?=?newwin(lines,?cols,?y,?x);

my_wins[1]?=?newwin(lines,?cols,?y?+?1,?x?+?5);

my_wins[2]?=?newwin(lines,?cols,?y?+?2,?x?+?10);

/*?为窗口添加创建边框以便你能看到面板的效果*/

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

box(my_wins[i],?0,?0);

/*?按自底向上的顺序,为每一个面板关联一个窗口*/

my_panels[0]?=?new_panel(my_wins[0]);

/*?把面板0?压进栈,?叠放顺序:?stdscr0

*/

my_panels[1]?=?new_panel(my_wins[1]);

/*?把面板1?压进栈,?叠放顺序:?stdscr01

*/

my_panels[2]?=?new_panel(my_wins[2]);

/*?把面板2?压进栈,?叠放顺序:?stdscr012*/

/*?更新栈的顺序。把面板2?置于栈顶*/

update_panels();

/*?在屏幕上显示*/

doupdate();

getch();

endwin();

}

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

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

屏幕上显示了三个窗口,每个窗口都是一个面板,每个面板关联一个窗口。如下图所示:

然后看看隐藏和显示面板

[email protected]:~/cursestest?%?cat?x.c

#include?<panel.h>

int?main()

{

WINDOW?*my_wins[3];

PANEL?*my_panels[3];

int?lines?=?10,?cols?=?40,?y?=?2,?x?=?4,?i;

int?ch;

initscr();

cbreak();

noecho();

/*?为每个面板创建窗口*/

my_wins[0]?=?newwin(lines,?cols,?y,?x);

my_wins[1]?=?newwin(lines,?cols,?y?+?1,?x?+?5);

my_wins[2]?=?newwin(lines,?cols,?y?+?2,?x?+?10);

/*?为窗口添加创建边框以便你能看到面板的效果*/

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

box(my_wins[i],?0,?0);

/*?按自底向上的顺序,为每一个面板关联一个窗口*/

my_panels[0]?=?new_panel(my_wins[0]);

/*?把面板0?压进栈,?叠放顺序:?stdscr0

*/

my_panels[1]?=?new_panel(my_wins[1]);

/*?把面板1?压进栈,?叠放顺序:?stdscr01

*/

my_panels[2]?=?new_panel(my_wins[2]);

/*?把面板2?压进栈,?叠放顺序:?stdscr012*/

/*?更新栈的顺序。把面板2?置于栈顶*/

update_panels();

/*?在屏幕上显示*/

doupdate();

//q退出,按1-3键显示和隐藏对应的面板

int?isshow[3]={1,1,1};

while((ch?=?getch())?!=‘q‘)

{?switch(ch)

{

case?‘1‘:

if?((++isshow[0])%2)?show_panel(my_panels[0]);

else?hide_panel (my_panels[0]);

break;

case?‘2‘:

if?((++isshow[1])%2)?show_panel(my_panels[1]);

else?hide_panel (my_panels[1]);

break;

case?‘3‘:

if?((++isshow[2])%2)?show_panel(my_panels[2]);

else?hide_panel (my_panels[2]);

break;

}

update_panels();

doupdate();

}

getch();

endwin();

}

执行后

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

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

比如把2号面板隐藏,效果如下

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

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

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

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

Ncurses入门-安装与使用

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

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