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

下面將全屏編輯器修改一下,通過panel的支持,讓它能同時打開3個窗口編輯不同的內容,同時對3個窗口的內容進行保存。

效果如下:

#include <locale.h>

#include <stdio.h>

#include <panel.h>

#include <ncurses.h>

//code by [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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章