Ncurses学习经历(八) 使用鼠标操作

1. 基础知识
   在使用鼠标之前,首先要调用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;
}

猜你喜欢

转载自blog.csdn.net/zhanganliu/article/details/80176725