3

私が意味することをよりよく説明しようとします。また、質問を言語から解放しようとしますが、何かを参照することなく C# でやりたいことを行う方法があれば、それは素晴らしいことです. ともかく。

キーボード入力を処理し、文字列に変換しています。大丈夫だ。Shift キーと CapsLock キーのステータスを取得し、それを EXOR して、結果の文字列の大文字と小文字を区別します。

bool shift = KeyDown(SHIFT_KEY)
bool capslock = KeyToggled(CAPSLOCK)
bool stringCasing = shift ^ capslock //if both are true/false, the string will be lowercase. Otherwise uppercase.

foreach Key k in [list of keys passed as parameter]
     char c = (char)k
     if stringCasing
          c = Char.ToUpper(c)
     else
          c = Char.ToLower(c)
end foreach

そして、今のところ問題はありません。Shift キーを押しながら、または capslock を切り替えた状態でユーザーが「a」を入力すると、「A」になります。

ただし、ユーザーが「!」(「1」にシフトを加えたもの) を入力すると、大文字の「1」は「1」のままであるため、1 しか取得できません。

この質問をする前にウェブを少し調べましたが、「キーを自分でマップする」というものしか得られませんでした。それが本当に唯一の答えですか?また、キーをマッピングした後で、別のキーボード レイアウトを持つユーザーがアプリケーションを使用しようとするとどうなるでしょうか。前もって感謝します。

4

1 に答える 1

8

ToAsciiこれは、Win32関数 ( MSDN リファレンス)を使用して実行できます。これらの関数をラップする .NET フレームワーク メソッドを知らないので、P/Invoke を使用する必要があるかもしれません。

とともに、キーを仮想キー コードに変換するためToAsciiの参照が必要になる場合があります。このキー コードは、 へのパラメータとして使用されます。これらのメソッドの単純な P/Invoke 宣言は次のとおりです。VkKeyScanToAscii

    [DllImport("user32.dll")]
    static extern short VkKeyScan(char c);

    [DllImport("user32.dll", SetLastError=true)]
    static extern int ToAscii(
        uint uVirtKey,
        uint uScanCode,
        byte[] lpKeyState,
        out uint lpChar,
        uint flags
        );

の 3 番目のパラメータToAsciiは、各キーの状態を参照する 256 要素の配列であることに注意してください。値 0x80 (上位ビット セット) は、キーが設定されていることを示します。設定要素 0x10 (Shift の仮想キー コード) はShift、押されていることをエミュレートします。

次に、キーを表す文字をパラメーターとして取り、そのキーをShift押した状態で出力するヘルパー メソッドを定義できます。

public static char GetModifiedKey(char c)
{
    short vkKeyScanResult = VkKeyScan(c);

    // a result of -1 indicates no key translates to input character
    if (vkKeyScanResult == -1)
        throw new ArgumentException("No key mapping for " + c);

    // vkKeyScanResult & 0xff is the base key, without any modifiers
    uint code = (uint)vkKeyScanResult & 0xff;

    // set shift key pressed
    byte[] b = new byte[256];
    b[0x10] = 0x80;

    uint r;
    // return value of 1 expected (1 character copied to r)
    if (1 != ToAscii(code, code, b, out r, 0))
        throw new ApplicationException("Could not translate modified state");

    return (char)r;
}

Shiftこのメソッドを呼び出すと、入力文字の +base キーに関連付けられた文字が返されます (ここで、base キーは、文字を入力するために押された物理的なキーです。たとえば、1のベース キーです!)。たとえば、US キーボードの場合、GetModifiedKey('7')両方GetModifiedKey('&')とも「&」を返します。戻り値は、読み込まれたキーボード レイアウトを使用します。たとえば、ドイツ語のキーボード ( Shift+7/) では、代わりにメソッドが返さ/れます。

于 2013-06-30T05:57:42.180 に答える