C指针原理(34)-Ncurses-文本终端的图形

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C指针原理(34)-Ncurses-文本终端的图形相关的知识,希望对你有一定的参考价值。

调用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)

我们在上面的编辑器中加上鼠标左键定位。

[email protected]:~/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("你的终端不支持色彩! ");

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

refresh();

return?0;

}else

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

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;

}

执行

[email protected]:~/cursestest?%?gcc?-lncursesw?a.c?-o?mytest

[email protected]:~/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,并加入对退格键的支持。

[email protected]:~/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("你的终端不支持色彩! ");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}

执行

[email protected]:~/cursestest?%?gcc?-lncursesw?a.c?-o?mytest

[email protected]:~/cursestest?%?./mytest

以上是关于C指针原理(34)-Ncurses-文本终端的图形的主要内容,如果未能解决你的问题,请参考以下文章

C指针原理(29)-Ncurses-文本终端的图形

C指针原理(35)-Ncurses-文本终端的图形

C指针原理(33)-Ncurses-文本终端的图形

Ncurses入门-安装与使用

基于文本图形(ncurses)的文本搜索工具 ncgrep

在没有 ncurses 的 C/C++ 中编写“真正的”交互式终端程序,如 vim、htop、...