5

我找到了很多关于使用 GLUT 来检测是否Ctrl使用 GLUT_ACTIVE_CTRL 宏按下键的信息。显然,这个宏只在键盘或鼠标回调函数中有效。我需要知道Ctrl在我的主循环中的某个点是否按下了键,但是 GLUT_ACTIVE_CTRL 在这种情况下似乎不起作用。

Ctrl那么,有没有办法以独立于平台的 GLUT方式检测按键上的按键向上和按键向下事件(无需键入任何其他键)?

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

它总是打印“控制键向上”。不管我是否Ctrl按键。

4

3 回答 3

1

不按规定使用 GLUT 。您可能希望查看GLFW

于 2010-08-26T20:59:15.153 回答
1

我在我的 GLUT 应用程序中使用了一个临时工具来解决问题。GLUT 的问题在于它只实现Ctrlor Shiftor or与另一个键Alt一起按下但是,该解决方法模拟了在后台运行的连续按下的键,GLUT 可以使用修改键拾取该键。

您可以通过使用库中SendInput的来实现这个想法。windows.h

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

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

要查看它是如何工作的,首先在您的GLUT代码中使用标准回调来Ctrl通过glutGetModifiers().

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 作为 CTRL 键被按下 (1) 或释放 (0) 的指示器。然后确保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。)

这对我很有效,除了必须牺牲一把钥匙之外,我没有遇到任何其他缺点。

于 2013-11-05T02:49:15.643 回答
0

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

于 2010-08-26T19:20:20.577 回答