2010-08-26 127 views
4

我发现了很多关于使用GLUT来检测是否使用GLUT_ACTIVE_CTRL宏按下Ctrl键的信息。显然,这个宏只适用于键盘或鼠标回调函数。我需要知道Ctrl键是否在我的主循环中的某个点被按下,但GLUT_ACTIVE_CTRL在此上下文中似乎不起作用。GLUT键和CTRL键上的按键

那么,有没有一种方法可以检测到键盘上的按键事件和键盘按键事件?在不依赖于平台的GLUT-ish方式下,按键(没有键入任何其他键)?

编辑:当Ctrl键被按下时,键盘回调未被触发(至少默认设置)。这是基本问题,我只能测试当按下另一个键时是否按下了键Ctrl,从而触发键盘回调。

我的设置是这样的:

// ... in main function: 
glutKeyboardFunc(keyboard); 

//later in the code: 

void keyboard(unsigned char key, int _x, int _y) 
{ 
    printf("keydown \n"); 

    if (glutGetModifiers() == GLUT_ACTIVE_CTRL) { 
      printf("control key is pressed.\n"); 
    } 
    //etc. 

当我按下任何正常的字符“的keydown”被打印到标准输出。当我按Ctrl键时,没有任何反应。如果我按Ctrl + C,“keydown控制键被按下。”被打印。

然而,在我主回路我说:

if (glutGetModifiers() == GLUT_ACTIVE_CTRL) { 
    printf("Control key down.\n"); 
} else { 
    printf("Control key up.\n"); 
} 

,它总是打印 “Control键了。”不管我是否按下Ctrl键。

回答

0

在事件处理程序中记录密钥的设置。然后,您可以将该存储展示给您的主循环中。

+1

对于使用典型方法(glutKeyboardFunc(callback))的GLUT,这将不起作用,因为键盘回调未针对修饰键启动。 – jcb 2010-08-26 19:37:07

+0

至少,它们不会在默认设置下被解雇。 – jcb 2010-08-26 19:37:48

1

我在我的GLUT应用程序中使用makehift来完成这个技巧。 GLUT的问题在于它只实现了CtrlShiftAlt按在一起与另一个键。但是,该解决方法模拟了在后台运行的连续按下的键,然后GLUT可以使用修饰键进行拾取。

您可以使用windows.h库中的SendInput来实现此想法。

UINT WINAPI SendInput(_In_ UINT nInputs, _In_ LPINPUT pInputs, _In_ int cbSize); 

模拟硬件击键。这与glutGetModifiers()回调一起工作。您可以在循环的背景中运行模拟的击键,例如在您的idlefunc中,您需要选择一个在您的程序中不常用的密钥。

要看看它是如何工作的,必须先把你GLUT代码中的标准回调至glutGetModifiers()承认按Ctrl键

bool CTRLpress=0; 

int checkModifiers(void) 
    { 
    int mod_key = glutGetModifiers(); 
    if (mod_key!= 0) 
     { 
     if (mod_key == GLUT_ACTIVE_CTRL) 
      { 
      CTRLpress=1; 
      } 
     return 1; 
     } 
    else if (CTRLpress) 
     { 
     CTRLpress=0; 
     return 1; 
     } 
    return 0; 
    } 

声明和定义全局或在自己的键盘类作为CTRL键的指示器变量布尔CTRLpress被按下(1)或释放(0)。然后确保像往常一样从您的glutKeyboardFunc内调用checkModifiers()函数。

现在开始你的主代码中输入对象:

#define WINVER 0x0500 // Note: This needs to be put in here as SendInput is compatible from Windows 2000 onwards 
#include <windows.h> 

INPUT permkey; //optionally you could also use a pointer to INPUT with *premkey here 

int main (int argc, char **argv) 
     { 
     permkey.type = INPUT_KEYBOARD; 
     permkey.ki.wVk = 0x42; // keystroke 'b' but check out all ASCII codes 
     permkey.ki.time = 0; 
     permkey.ki.dwFlags = 0; 

     //your code here 
     } 

最后,把你的glutIdleFunc模拟连续按下按键敲击的正常通话中:

void idle() 
    { 
    SendInput(1, &permkey, sizeof(INPUT)); 
    // your other code here 
    } 

当按下单独使用Ctrl而没有任何其他按键,代码触发CTRL按下为1.或者,当释放CTRL按下时(您可能想要进一步扩展自己的修饰符类克服其他GLUT缺点 - 样的困难检测按Ctrl +

这工作我很好,我还没有碰到过不必牺牲关键以外的任何其他缺点来。