按下 GLUT 键并按下 CTRL 键上键

发布于 2024-09-16 07:40:20 字数 1024 浏览 2 评论 0原文

我发现了很多有关使用 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”会打印到标准输出。当我按下 Ctrl 键时,没有任何反应。如果我按 Ctrl+C,“按下 keydown 控制键”。被打印。

但是,在我的主循环中我添加了:

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

并且它总是打印“Control key up”。无论我是否按下 Ctrl 键。

I've found a lot of information about using GLUT to detect whether the Ctrl key is pressed using the GLUT_ACTIVE_CTRL macro. This macro only works, apparently, within a keyboard or mouse callback function. I need to know whether or not the Ctrl key is pressed at a point in my main loop, but GLUT_ACTIVE_CTRL doesn't seem to work in this context.

So, is there a way to detect key up and key down events on the Ctrl key (without any other keys being typed) in a platform independent GLUT-ish way?

EDIT: The keyboard callback is not fired (at least for a default setup) when the Ctrl key is pressed. This is the basic problem, that I can only test whether the Ctrl key is or isn't pressed when another key is pressed and thus fires the keyboard callback.

My setup is something like:

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

When I press any normal character "keydown " is printed to stdout. When I press the Ctrl key, nothing happens. If I press Ctrl+C, "keydown control key is pressed." is printed.

However, in my main loop I added:

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

and it always prints "Control key up." regardless of whether I am pressing the Ctrl key or not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无可置疑 2024-09-23 07:40:20

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

Not using GLUT as specced. You may wish to check out GLFW.

沒落の蓅哖 2024-09-23 07:40:20

我在 GLUT 应用程序中使用了一个临时方案来解决这个问题。 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;
    }

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

现在在主代码中启动一个 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 +数字。)

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

I use a makeshift in my GLUT application that does the trick. The problem with GLUT is that it realizes only Ctrl or Shift or Alt pressed together with another key. However, the workaround simulates a continuously pressed key running in the background that GLUT can then pick up with a modifier key.

You can implement this idea by usingSendInput from the windows.h library.

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

simulates a hardware keystroke. This works together with the glutGetModifiers() callback. You can run the simulated key stroke in the background of your loop, e.g. within your idlefunc and you need to chose a key that is not in regular use in your program.

To see how it works, have first the standard callback within your GLUT code to recognize the Ctrl key through 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;
    }

Declare and define the variable bool CTRLpress globally or in your own keyboard class as an indicator for the CTRL key being pressed (1) or released (0). Then make sure that the function checkModifiers() is being called from within your glutKeyboardFunc as usual.

Now initiate an INPUT object within your main code:

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

Finally, put within your glutIdleFunc a regular call that simulates a continuous pressing of a key stroke:

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

When pressing Ctrl alone without any other pressed key, the code triggers CTRLpressed to be 1. Alternatively, when released CTRLpressed becomes (You might want to further extended your own modifier-class to overcome other GLUT shortcomings - like difficulties in detecting Ctrl +Number.)

This works with me well and I haven't come across any other drawbacks other than having to sacrifice a key.

爱给你人给你 2024-09-23 07:40:20

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

In the event handler record the setting of the key. You can then expose that storage to be read from your main loop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文