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

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

文件中 wid printf 存儲 click default attr 接收 版本

調用mousemask(?)這個函數來激活你想要接收的鼠標事件。

mousemask(?mmask_t?newmask,?/?你想要監聽的鼠標事件掩碼/

mmask_t?oldmask?)?/?舊版本使用的鼠標事件掩碼*/

主要事件如下:(一般來說,左鍵為1?號,右鍵為2?號)

BUTTON1_PRESSED?鼠標1?號鍵按下

BUTTON1_RELEASED?鼠標1?號鍵釋放

BUTTON1_CLICKED?鼠標1?號鍵單擊

BUTTON1_DOUBLE_CLICKED?鼠標1?號鍵雙擊

BUTTON1_TRIPLE_CLICKED?鼠標1?號鍵三擊

BUTTON2_PRESSED?鼠標2?號鍵按下

BUTTON2_RELEASED?鼠標2?號鍵釋放

BUTTON2_CLICKED?鼠標2?號鍵單擊

BUTTON2_DOUBLE_CLICKED?鼠標2?號鍵雙擊

BUTTON2_TRIPLE_CLICKED?鼠標2?號鍵三擊

BUTTON3_PRESSED?鼠標3?號鍵按下

BUTTON3_RELEASED?鼠標3?號鍵釋放

BUTTON3_CLICKED?鼠標3?號鍵單擊

BUTTON3_DOUBLE_CLICKED?鼠標3?號鍵雙擊

BUTTON3_TRIPLE_CLICKED?鼠標3?號鍵三擊

BUTTON4_PRESSED?鼠標4?號鍵按下

BUTTON4_RELEASED?鼠標4?號鍵釋放

BUTTON4_CLICKED?鼠標4?號鍵單擊

BUTTON4_DOUBLE_CLICKED?鼠標4?號鍵雙擊

BUTTON4_TRIPLE_CLICKED?鼠標4?號鍵三擊

BUTTON_SHIFT?在鼠標事件發生時,伴隨Shift?鍵按下

BUTTON_CTRL?在鼠標事件發生時,伴隨Ctrl?鍵按下

BUTTON_ALT?在鼠標事件發生時,伴隨Alt?鍵按下

ALL_MOUSE_EVENTS?報告所有的鼠標事件

REPORT_MOUSE_POSITION?報告鼠標移動位置

getmouse()函數將這個事件返回一個相應的指針。這個指針結構是這樣的:

typedef?struct

{

short?id??/?ID?用來辨別不同的設備

/

int?x,?y,?z??/?事件發生的坐標/

mmask_t?bstate??/?鼠標按鍵狀態/

}

Bstate?是我們關註的最主要變量,它返回了當前鼠標按鍵的狀態。下面的這段代碼可以捕捉鼠標左鍵按下:

if(event.bstate?&?BUTTON1_PRESSED)

我們在上面的編輯器中加上鼠標左鍵定位。

dp@dp:~/cursestest?%?cat?a.c

#include?<locale.h>

#include?<stdio.h>

#include?<ncurses.h>

//[email protected]

//date:2014/1/17

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(5,COLS/2-10,"簡單編輯器-僅限於單個屏幕的編輯");

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;

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_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(1):

??????? //退出

mvprintw(LINES-3,2,"退出編輯器嗎?");

mvprintw(LINES-2,2,"????");

refresh();

int?ans=getch();

if?(ans==‘Y‘?||ans==‘y‘)

{

mvprintw(LINES-2,2,"是\n");

refresh();

return?0;

}else

mvprintw(LINES-2,2,"否\n");

refresh();

break;

case?KEY_F(12):

??????? //刪除某行

wdeleteln(win1);

winsertln(win1);

???????? box(win1,ACS_VLINE,ACS_HLINE);

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);

}

}

????????wattroff(win1,COLOR_PAIR(1));

endwin();

mousemask(oldmousemask,NULL);

return?0;

}

執行

dp@dp:~/cursestest?%?gcc?-lncursesw?a.c?-o?mytest

dp@dp:~/cursestest?%?./mytest

scr_dump()?函數可以把當前屏幕的內容存入指定文件,即以文件名作為函數的參數,而通過?scr_restore()函數調用屏幕數據文件來恢復屏幕。它們的函數調用方式為:

scr_dump(const?char?*file)?

scr_restore(const?char?*file)?

getwin()函數用來將窗口內容存儲到一個指定的文件中。?putwin()?函數則調用相應的文件來恢復窗口。

它們的函數調用方式為:

getwin(FILE?*?filep)?

putwin(WINDOW?win,?FILE??filep)

我們先利用scr_dump()與scr_restore()函數,實現將編輯器的內容存盤與讀取,但是它會把整個屏幕保存下來。

設定F9讀取,F10存盤,同時修改退出為F11,並加入對退格鍵的支持。

dp@dp:~/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("你的終端不支持色彩!\n");

????????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;

????????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,"????");

????????????????????????????????refresh();

????????????????????????????????ans=getch();

????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)

????????????????????????????????{

????????????????????????????????????????mvprintw(LINES-2,2,"是\n");

????????????????????????????????????????refresh();

????????????????????????????????????????return?0;

????????????????????????????????}else

????????????????????????????????????????mvprintw(LINES-2,2,"否\n");

????????????????????????????????????????refresh();

????????????????????????????????break;

????????????????????????case?KEY_F(10):

????????????????????????????????//存盤

????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");

????????????????????????????????mvprintw(LINES-3,2,"保存當前內容嗎??????");

????????????????????????????????mvprintw(LINES-2,2,"????");

????????????????????????????????refresh();

????????????????????????????????ans=getch();

????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)

????????????????????????????????{

????????????????????????????????????????mvprintw(LINES-3,2,"?????????????????????");

????????????????????????????????????????scr_dump("myedit.dat");

????????????????????????????????????????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,"????");

????????????????????????????????refresh();

????????????????????????????????ans=getch();

????????????????????????????????if?(ans==‘Y‘?||ans==‘y‘)

????????????????????????????????{

????????????????????????????????????????if?(isExist("myedit.dat"))?scr_restore("myedit.dat");

????????????????????????????????????????mvprintw(LINES-3,2,"讀取保存內容嗎?????");

????????????????????????????????????????mvprintw(LINES-2,2,"是\n");

????????????????????????????????????????refresh();

????????????????????????????????}else

????????????????????????????????????????mvprintw(LINES-2,2,"否\n");

????????????????????????????????????????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);

????????????????}

????????}

????????wattroff(win1,COLOR_PAIR(1));

????????endwin();

????????mousemask(oldmousemask,NULL);

????????return?0;

}

執行

dp@dp:~/cursestest?%?gcc?-lncursesw?a.c?-o?mytest

dp@dp:~/cursestest?%?./mytest

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