2012-07-13 285 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字符串。