C指針原理(35)-Ncurses-文本終端的圖形
效果如下:
#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("你的終端不支持色彩!\n");
????????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,"?????\n");
????????????????????????????????refresh();
????????????????????????????????ans=getch();
????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)
????????????????????????????????{
????????????????????????????????????????mvprintw(LINES-2,2,"是\n");
????????????????????????????????????????refresh();
????????????????????????????????????????wattroff(mywins[nowwinid],COLOR_PAIR(1));
????????????????????????????????????????mousemask(oldmousemask,NULL);
????????????????????????????????????????endwin();
????????????????????????????????????????return?0;
????????????????????????????????}else
????????????????????????????????????????mvprintw(LINES-2,2,"否\n");
????????????????????????????????????????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,"?????\n");
????????????????????????????????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,"保存成功!\n");
????????????????????????????????????????}
????????????????????????????????????????mvprintw(LINES-3,2,"保存當前內容嗎??????");
????????????????????????????????????????mvprintw(LINES-2,2,"是\n");
????????????????????????????????????????refresh();
????????????????????????????????}else
????????????????????????????????????????mvprintw(LINES-2,2,"否\n");
????????????????????????????????????????refresh();
????????????????????????????????break;
????????????????????????case?KEY_F(9):
????????????????????????????????//讀取存盤
????????????????????????????????mvprintw(LINES-3,2,"????????????????????");
????????????????????????????????mvprintw(LINES-3,2,"讀取保存內容嗎?????");
????????????????????????????????mvprintw(LINES-2,2,"????");
????????????????????????????????mvprintw(LINES-1,2,"?????\n");
????????????????????????????????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,"讀取成功!\n");
????????????????????????????????????????????????}
????????????????????????????????????????????????fclose(fp2);
????????????????????????????????????????}
????????????????????????????????????????}
????????????????????????????????????????mvprintw(LINES-3,2,"讀取保存內容嗎?????");
????????????????????????????????????????mvprintw(LINES-2,2,"是\n");
????????????????????????????????????????refresh();
????????????????????????????????}else
????????????????????????????????????????mvprintw(LINES-2,2,"否\n");
????????????????????????????????????????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;
}
dp@dp:~/cursestest?%?gcc?-lncursesw?-lpanel?a.c?-o?mytest
dp@dp:~/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;
}
dp@dp:~/cursestest?%?gcc?-lncursesw?-lform?b.c?-o?mytest
dp@dp:~/cursestest?%?./mytest
C指針原理(35)-Ncurses-文本終端的圖形