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