1

C++ で独自のテキスト エディターを実装しています。進んでいます...わかりました。;P

キーコード (具体的には Allegro、彼らはそれをスキャンコードと呼んでいます) を ASCII 文字に変換する方法が必要です。AZ を簡単に実行でき、それらを az に変換するのも簡単です。私が現在行っていることは、スキャンコード (al_keycode_to_name) から名前を返す Allegro の関数を使用することです。つまり、押されたキーが AZ の場合、「A」から「Z」を返します。それは簡単ですが、「、」、「;」などの特殊文字を単純に読み取ることはできません。など、そこが苦労しています。

これを自動的に行う方法はありますか?多分これを行うライブラリ?本当の秘訣は、さまざまなレイアウトを考慮することです。

誰かが興味を持っている場合に備えて、これまでのところ私が持っているものがあります。クラス InputState は、基本的に Allegro の inputstate のコピーで、機能が追加されています (keyDown、keyUp、keyPress など)。

    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;


                    }
                }
            }
        }
    }
4

1 に答える 1

1

テキスト入力を読み取るALLEGRO_EVENT_KEY_CHARには、値を指定してイベントを使用する必要があります。押された物理キーに対応します。それらと印刷可能な文字の間には 1 対 1 の対応はありません。event.keyboard.unicharALLEGRO_EVENT_KEY_DOWNALLEGRO_EVENT_KEY_UP

デッドキーが 2 つのキーe'をに変換するために使用されているとしますéeとの 2 つのキー ダウン イベント'(どちらも適切な入力をキャプチャするのには役立ちません) を取得しますが、. の 1 つのキー char イベントを取得しますé。または逆に、誰かF4がテキストの段落全体を解き放つマクロにマップした可能性があります。その場合、1 つのキーを押すと複数の文字が表示されます。

または、簡単なテスト: キーを 5 秒間押し続けると、OS のキーボード ドライバーが繰り返しイベントを送信するため、キーは 1 つです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 データ型を直接使用するか、 UTF-8 文字列への読み取り専用ポインターを取得するためにal_draw_ustr(font, color, x, y, flags, input)使用できます。al_cstr(input)

于 2012-07-14T17:32:00.360 に答える