使用ncurses捕获控制台应用程序上的鼠标单击

时间:2012-07-02 22:13:23

标签: c++ unix mouseevent ncurses curses

我正在为unix平台制作一个控制台应用程序,我正在使用curses(或ncurses)库来处理键盘和鼠标输入。问题是,我发现很少有关于如何使用它的文档,来自this pagethis one的appart,它们没有非常详细的示例。 我已设法捕获左键单击,但我无法让它为右键单击工作,因为终端模拟器的选项菜单出现在光标位置,但该事件未由应用程序处理。如何避免这种情况并在应用程序中捕获事件?

我有以下行来配置鼠标事件:

// Set up mouse event throwing
mousemask(BUTTON1_PRESSED | BUTTON2_PRESSED, NULL);

在处理输入的方法中,我有以下内容:

int c = getch();
MEVENT event;
switch(c)
{
    case KEY_UP:
        ... do stuff
        break;
    case KEY_DOWN:
        ... do stuff
        break;
    case KEY_MOUSE:
        if(getmouse(&event) == OK)
        {
            if(event.bstate & BUTTON1_PRESSED) // This works for left-click
            {
                ... do stuff
            }
            else if(event.bstate & BUTTON2_PRESSED) // This doesn't capture right-click
            {
                ... do other stuff
            }
            else
                fprintf(stderr, "Event: %i", event.bstate); // Doesn't print anything on right-click
        }
        break;
    default:
        return;
}

我也尝试使用mousemask()掩码配置ALL_MOUSE_EVENTS,但它仍然不会在最后else子句上打印任何事件,所以我认为事件只是'触发。 对此有任何帮助将非常感激。

4 个答案:

答案 0 :(得分:10)

对于其他任何人来到这里试图找出为什么他/她无法完全使用Ncurses捕获鼠标事件,很可能这就是你需要的那条线:

keypad(window, TRUE);

如果没有这个,我没有得到getch()的任何鼠标事件。

我看到的所有教程/示例中都缺少这个,这就是为什么我花了很多时间来弄清楚我的代码出了什么问题 - 也许这个答案会帮助其他人找到比我更快的解决方案。 / p>

答案 1 :(得分:2)

鼠标右键是按钮3,而不是按钮2.按钮2是中间按钮。

答案 2 :(得分:1)

最初的问题是关于终端仿真器(和菜单激活会干扰将鼠标单击传递给应用程序)。某些终端特定的文档(甚至某些教程)可能已经解决了这一问题。其他答案错过了这一点,而是集中在ncurses应用程序接收(并理解)xterm协议鼠标事件的问题上。

后一个问题记录在manual page中:

xterm 下的鼠标事件将无法在窗口中正确检测到 keypad位关闭,因为它们被解释为多种 功能键。您的terminfo描述应将 kmous 设置为 "\E[M"(xterm对鼠标单击的响应的开始)。 允许使用 kmous 的其他值,但是在相同的假设下, 即是响应的开始。

不新鲜,首先在1995中提到:

在xterm下的鼠标事件将无法在带有 键盘位关闭了。

答案 3 :(得分:0)

我正在使用你的代码,但我无法得到任何反应。甚至左鼠标按钮都不起作用。

这是你的完整代码吗?

#include <ncurses.h> 

int main(int argc, char **argv){ 

while(1) 
{ 

    mousemask( ALL_MOUSE_EVENTS, NULL); 
        int c = getch(); 
        MEVENT event; 
        switch(c) 
        { 
            case KEY_UP: 
                printf("keyup"); 
                break; 
            case KEY_DOWN: 
                printf("keydown"); 
                break; 
            case KEY_MOUSE: 
                if(getmouse(&event) == OK) 
                { 
                    if(event.bstate & BUTTON1_PRESSED) // This works for left-click 
                    { 
                        printf("button1"); 
                    } 
                    else if(event.bstate & BUTTON2_PRESSED) // This doesn't capture right-click 
                    { 
                        printf("button2"); 
                    } 
                    else 
                        printf("Event: %i", event.bstate); // Doesn't print anything on right-click 
                } 
                break; 
        } 
} 
return 0; 
}