2012-07-13 284 views
1

我正在C++中實現我自己的文本編輯器。它會......好的。 ; P將掃描碼轉換爲ASCII

我需要一種方法來將一個鍵碼(特別是Allegro,他們稱之爲掃描碼)轉換成一個ASCII字符。我可以輕鬆完成A-Z,並且將它們轉換爲a-z也很容易。我目前所做的是在Allegro中使用一個函數,它從掃描碼(al_keycode_to_name)返回一個名稱,這意味着如果按下的鍵是A-Z,它將「A」返回到「Z」。這很容易,但我不能簡單地閱讀特殊字符,如「,」,「;」等等,那是我很難過的地方。

有沒有辦法自動做到這一點?也許一個這樣做的圖書館?真正的技巧是考慮到不同的佈局。

這是我到目前爲止,以防萬一誰感興趣。類InputState基本上是快板inputstate的副本,添加了功能(的keyDown,使用keyUp,按鍵爲例):

void AllegroInput::TextInput(const InputState &inputState, int &currentCharacter, int &currentRow, std::string &textString) 
    { 
     static int keyTimer = 0; 
     static const int KEY_TIMER_LIMIT = 15; 
     for (int i = 0; i < 255; i++) 
     { 
      if (inputState.key[i].keyDown) 
      { 
       keyTimer++; 
      } 
      if (inputState.key[i].keyPress) 
      { 
       keyTimer = 0; 
      } 

      if ((inputState.key[i].keyPress) || ((inputState.key[i].keyDown) && (keyTimer >= KEY_TIMER_LIMIT))) 
      { 
       std::string ASCII = al_keycode_to_name(i); 

       if ((ASCII.c_str()[0] >= 32) && (ASCII.c_str()[0] <= 126) && (ASCII.length() == 1)) 
       { 
        textString = textString.substr(0, currentCharacter) + ASCII + textString.substr(currentCharacter, textString.length()); 
        currentCharacter++; 
       } 
       else 
       { 
        switch(i) 
        { 
         case ALLEGRO_KEY_DELETE: 
          if (currentCharacter >= 0) 
          { 
           textString.erase(currentCharacter, 1); 
          } 
          break; 

         case ALLEGRO_KEY_BACKSPACE: 
          if (currentCharacter > 0) 
          { 
           currentCharacter--; 
           textString.erase(currentCharacter, 1); 
          } 
          break; 

         case ALLEGRO_KEY_RIGHT: 
          if (currentCharacter < textString.length()) 
          { 
           currentCharacter++; 
          } 
          break; 

         case ALLEGRO_KEY_LEFT: 
          if (currentCharacter > 0) 
          { 
           currentCharacter--; 
          } 
          break; 
         case ALLEGRO_KEY_SPACE: 
          if (currentCharacter > 0) 
          { 

           textString = textString.substr(0, currentCharacter) + " " + textString.substr(currentCharacter, textString.length()); 
           currentCharacter++; 
          } 
          break; 


        } 
       } 
      } 
     } 
    } 
+0

沒有意識到我可以,謝謝! – 2012-07-14 14:42:54

回答

1

你應該使用ALLEGRO_EVENT_KEY_CHAR事件與event.keyboard.unichar值讀取文本輸入。 ALLEGRO_EVENT_KEY_DOWNALLEGRO_EVENT_KEY_UP對應於被按下的物理鍵。它們和可打印字符之間沒有1:1的對應關係。

假設一個死鎖正用於將兩個鍵e'轉換爲é。你會得到e'兩個關鍵事件(這兩個關鍵事件都不適用於捕獲正確的輸入),但是有一個關鍵的事件é。或者相反,也許有人將F4映射到一個釋放整段文本的宏。在這種情況下,您可以使用多個字符來輸入單個關鍵字。或者一個簡單的測試:如果你按住一個鍵五秒鐘,你會得到一個ALLEGRO_EVENT_KEY_DOWN,但是多個ALLEGRO_EVENT_KEY_CHAR作爲操作系統的鍵盤驅動程序發送重複事件。

您可以使用ALLEGRO_USTR輕鬆存儲這些unicode字符串。

ALLEGRO_USTR *input = al_ustr_new(""); 

// in the event loop 
al_ustr_append_chr(input, event.keyboard.unichar); 

還有辦法刪除字符如果按退格等,您可以使用USTR數據類型的字體插件直接通過al_draw_ustr(font, color, x, y, flags, input),或者您可以使用al_cstr(input)得到一個只讀指針一個UTF-8字符串。