5

CtrlGLUT_ACTIVE_CTRL マクロを使用してキーが押されたかどうかを検出するために GLUT を使用する方法に関する多くの情報を見つけました。このマクロは、明らかに、キーボードまたはマウスのコールバック関数内でのみ機能します。メインループのある時点でキーが押されたかどうかを知る必要がありCtrlますが、GLUT_ACTIVE_CTRL はこのコンテキストでは機能しないようです。

それで、プラットフォームに依存しないGLUTっぽい方法で、キーのキーアップとキーダウンイベントを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、「キーダウンコントロールキーが押されました。」印刷されます。

ただし、メインループに次を追加しました。

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

常に「Control key up」と表示されます。Ctrlキーを押しているかどうかに関係なく。

4

3 に答える 3

1

スペックとしてGLUTを使用していません。GLFWをチェックすることをお勧めします。

于 2010-08-26T20:59:15.153 に答える
1

トリックを行う GLUT アプリケーションでその場しのぎを使用します。GLUT の問題は、別のキーと一緒に押されたCtrlorのみを実現することです。ただし、回避策は、GLUT が修飾キーで取得できるバックグラウンドで実行されている連続して押されたキーをシミュレートします。ShiftAlt

ライブラリ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) ことを示すインジケーターとして定義します。次に、関数 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+の検出の難しさなどNumber)。

これは私にとってはうまく機能し、キーを犠牲にしなければならないこと以外に他の欠点に出くわしたことはありません。

于 2013-11-05T02:49:15.643 に答える
0

イベント ハンドラで、キーの設定を記録します。次に、そのストレージを公開して、メイン ループから読み取ることができます。

于 2010-08-26T19:20:20.577 に答える