1. 程式人生 > >C指針原理(35)-Ncurses-文本終端的圖形

C指針原理(35)-Ncurses-文本終端的圖形

drive 普通 編寫 當前 post F12 meven 指針 click

下面將全屏編輯器修改一下,通過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("你的終端不支持色彩!\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-文本終端的圖形