GLUT键按下并按下CTRL键

时间:2010-08-26 19:16:39

标签: opengl glut keyboard-events

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

那么,有没有办法在平台独立的GLUT-ish方式中检测 Ctrl 键上的键向上和按键事件(没有键入任何其他键)?

编辑:当按下 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”会打印到stdout。当我按 Ctrl 键时,没有任何反应。如果我按 Ctrl + C ,则按下“keydown控制键”。打印出来。

然而,在我的主循环中,我添加了:

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

并始终打印“控制键”。无论我是否按 Ctrl 键。

3 个答案:

答案 0 :(得分:1)

我在我的GLUT应用程序中使用临时替换功能。 GLUT的问题在于它只用另一个键实现 Ctrl Shift Alt 一起按 。但是,变通方法模拟了在后台运行的连续按下的键,然后GLUT可以使用修改键进行拾取。

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

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;
    }

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

现在在主代码中启动一个INPUT对象:

#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 而没有任何其他按键时,代码触发CTRLpressed为1.或者,当释放时CTRLpressed变为(您可能希望进一步扩展自己的修饰符类以克服其他GLUT缺点 - 比如检测 Ctrl + Number 时的困难。)

这很适合我,除了不得不牺牲一把钥匙外,我没有遇到任何其他缺点。

答案 1 :(得分:0)

在事件处理程序中记录密钥的设置。然后,您可以公开要从主循环中读取的存储空间。

答案 2 :(得分:0)

不使用GLUT as specced。您可以查看GLFW