13

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

我有以下用于配置鼠标事件的行:

// 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

4 回答 4

19

对于其他来到这里试图弄清楚为什么他/她无法使用 Ncurses 捕获鼠标事件的人,很可能这是您需要的行:

keypad(window, TRUE);      

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

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

于 2012-12-14T22:18:34.560 回答
3

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

于 2012-07-04T10:24:48.187 回答
2

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

后一个问题记录在手册页中:

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

不是新的,在1995 年首次提到:

xterm 下的鼠标事件将无法在其键盘位关闭的窗口中正确检测到。

于 2020-01-19T12:00:38.837 回答
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; 
}
于 2012-11-09T14:33:42.180 回答