2010-08-26 81 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 +

這工作我很好,我還沒有碰到過不必犧牲關鍵以外的任何其他缺點來。