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-文本终端的图形的主要内容,如果未能解决你的问题,请参考以下文章