1. 基础知识
在使用鼠标之前,首先要调用mousemask( )这个函数来激活你想要接收的鼠标事件。
mousemask( mmask_t newmask, /* 你想要监听的鼠标事件掩码*/
mmask_t *oldmask ) /* 旧版本使用的鼠标事件掩码*/
上述函数中的第一个参数,就是你所要监听的事件的位掩码,默认情况下,在使用该函数之
前,所有鼠标事件的接收状态都是未激活的。位掩码ALL_MOUSE_EVENTS 可以让鼠标
接收所有的事件。
下面是NCURSES 定义的位掩码清单:(注意:不同的鼠标按键号码设置不同,使用前需要
测试。一般情况下左键为1 号,右键为2 号)
掩码对应事件
当所有的鼠标监听事件被激活后。getch()一类的函数在每次接收到的鼠标事件时可以返回
KEY_MOUSE。然后通过getmouse()函数可以取得这些事件。
代码大概看起来是这样:
MEVENT event;
ch = getch();
if(ch == KEY_MOUSE)
if(getmouse(&event) == OK)
{
. /* 处理这个事件的代码*/
}
……
getmouse()函数将这个事件返回一个相应的指针。这个指针结构是这样的:
typedef struct
{
short id; /* ID 用来辨别不同的设备*/
int x, y, z; /* 事件发生的坐标*/
mmask_t bstate; /* 鼠标按键状态*/
}
Bstate 是我们关注的最主要变量,它返回了当前鼠标按键的状态。下面的这段代码可以让
我们看看按下鼠标左键会出现什么:
if(event.bstate & BUTTON1_PRESSED)
在使用鼠标之前,首先要调用mousemask( )这个函数来激活你想要接收的鼠标事件。
mousemask( mmask_t newmask, /* 你想要监听的鼠标事件掩码*/
mmask_t *oldmask ) /* 旧版本使用的鼠标事件掩码*/
上述函数中的第一个参数,就是你所要监听的事件的位掩码,默认情况下,在使用该函数之
前,所有鼠标事件的接收状态都是未激活的。位掩码ALL_MOUSE_EVENTS 可以让鼠标
接收所有的事件。
下面是NCURSES 定义的位掩码清单:(注意:不同的鼠标按键号码设置不同,使用前需要
测试。一般情况下左键为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 报告鼠标移动位置2. 取得鼠标事件
当所有的鼠标监听事件被激活后。getch()一类的函数在每次接收到的鼠标事件时可以返回
KEY_MOUSE。然后通过getmouse()函数可以取得这些事件。
代码大概看起来是这样:
MEVENT event;
ch = getch();
if(ch == KEY_MOUSE)
if(getmouse(&event) == OK)
{
. /* 处理这个事件的代码*/
}
……
getmouse()函数将这个事件返回一个相应的指针。这个指针结构是这样的:
typedef struct
{
short id; /* ID 用来辨别不同的设备*/
int x, y, z; /* 事件发生的坐标*/
mmask_t bstate; /* 鼠标按键状态*/
}
Bstate 是我们关注的最主要变量,它返回了当前鼠标按键的状态。下面的这段代码可以让
我们看看按下鼠标左键会出现什么:
if(event.bstate & BUTTON1_PRESSED)
printw("Left Button Pressed");
3 .把它们放在一起
能够使用鼠标操作的程序是非常棒的,让我们做用鼠标操作的菜单程序。为了让例子看起来
更有针对性,这个程序中去掉了键盘操作:
#include <ncurses.h> #include <string.h> #define WIDTH 30 #define HEIGHT 10 int startx = 0; int starty = 0; char *choices[] ={"Choice 1","Choice 2","Choice 3","Choice 4","exit"}; int n_choices = sizeof(choices)/sizeof(char *); void print_menu(WINDOW *menu_win,int highlight) { int x,y,i; x = 2;y = 2; box(menu_win,0,0); for(i = 0;i < n_choices;i++) { if(highlight == i + 1) { wattron(menu_win,A_BOLD|A_BLINK); mvwprintw(menu_win,y,x,"%s",choices[i]); wattroff(menu_win,A_BOLD|A_BLINK); } else mvwprintw(menu_win,y,x,"%s",choices[i]); ++y; } wrefresh(menu_win); } void report_choice(int mouse_x,int mouse_y,int *p_choice) { int i,j,choice; i = startx + 2; j = starty + 3; for(choice = 0;choice < n_choices;++choice) { if(mouse_y == j + choice && mouse_x >= i && mouse_x <= i + strlen(choices[choice])) { if(choice == n_choices - 1) *p_choice = -1; else *p_choice = choice + 1; break; } } } int main(int argc, char **argv) { int c,choice = 0; WINDOW *menu_win; MEVENT event; initscr(); clear(); noecho(); cbreak(); startx = (80 - WIDTH)/2; starty = (24 - HEIGHT)/2; attron(A_REVERSE); mvprintw(23,1,"Click on exit to quit(Work best in a vitual console)"); refresh(); attroff(A_REVERSE); menu_win = newwin(HEIGHT,WIDTH,starty,startx); print_menu(menu_win,1); mousemask(ALL_MOUSE_EVENTS,NULL); while(1) { c = wgetch(menu_win); switch(c) { case KEY_MOUSE: if(getmouse(&event) == OK) { if(event.bstate == BUTTON1_PRESSED) { report_choice(event.x + 1,event.y + 1, &choice); if(choice == -1) goto end; mvprintw(22,1,"Choice made is : %d string chosen is \"%10s\"",choices[choice - 1]); break; } } } } end : endwin(); return 0; }