我正在为unix平台制作一个控制台应用程序,我正在使用curses(或ncurses)库来处理键盘和鼠标输入。问题是,我发现很少有关于如何使用它的文档,来自this page和this 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
子句上打印任何事件,所以我认为事件只是'触发。
对此有任何帮助将非常感激。
答案 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;
}