5

タッチ機能を備えた業界のPCで主に使用されている、当社のプログラム用のオンスクリーンキーボードを作成する必要があります。

キーボードのすべてのキーが必要なわけではないため、Windowsのデフォルトのキーボードを使用することはできません。そこで、C#でカスタムを作成するように依頼されました。

すでにこのブログを参考にしていますが、どうやって始めたらいいのかわかりません。

小さなプロトタイプGUIを作成し、各キーにスキャンコードを割り当て、これらのスキャンコードを関連する文字に変換しました。そして、それらをアクティブコントロールに送信します。しかし、どのスキャンコードを使用すべきかわかりません。

だから私の質問は、このようなOSKを書く正しい方法であり、もしそうなら、どのスキャンコードを使うべきかということです。リンクはありますか?

状態の処理方法もわかりませんshift...

編集:

shiftさて、私はもう少し調査を行い、現在のキーボードレイアウトを読み取り、簡単な状態(Shiftおよび)を処理するoskを思いつきましたAlt GrKeyButtonから継承するクラスを作成しましたButton。これKeyButtonにはScanCodebyte型のプロパティがあり、有効なスキャンコードを割り当てるKeyButtonと、関連する関数を呼び出して正しいテキストを取得します。Michael Kaplanブログの関数を使用しましたが、いくつかの小さな変更がありました。結局、私は彼と同じことをしなければならなかったことがわかりました。

したがって、私の質問に対する答えは次のとおりです。はい、ボタンでスキャンコードを使用してから、キーボードレイアウトから仮想キーとUnicodeを取得する必要があります。これらのスキャンコードを使用してください。

今、私はキャラクターを手に入れました。残っているのは、これらを送ることだけです。

4

3 に答える 3

1

キー コードを WPF アプリケーションの文字にマップするマッピング クラスを作成しました。これが役立つかもしれません。

public class KeyMapper
{
    /// <summary>
    /// Map key code to character.
    /// If key code cannot be mapped returns empty char.
    /// </summary>
    public static char MapKey(Key key, bool shiftPressed, string culture)
    {
        CheckCulture(culture);
        int englishVirtuaCode = KeyInterop.VirtualKeyFromKey(key);
        return EnglishVirtualCodeToChar(englishVirtuaCode, shiftPressed, culture);
    }

    private static void CheckCulture(string culture)
    {
        InputLanguage language = InputLanguage.FromCulture(new CultureInfo(culture));
        if (language == null)
            throw new ArgumentException(string.Format("culture {0} does not exist.", culture));
    }

    private static char EnglishVirtualCodeToChar(int enlishVirtualCode, bool shiftPressed, string culture)
    {
        var scanCode = KeyMappingWinApi.MapVirtualKeyEx((uint)enlishVirtualCode, 0, EnglishCultureHandle);
        var vitualKeyCode = KeyMappingWinApi.MapVirtualKeyEx(scanCode, 1, GetCultureHandle(culture));
        byte[] keyStates = GetKeyStates(vitualKeyCode, shiftPressed);
        const int keyInformationSize = 5;
        var stringBuilder = new StringBuilder(keyInformationSize);
        KeyMappingWinApi.ToUnicodeEx(vitualKeyCode, scanCode, keyStates, stringBuilder, stringBuilder.Capacity, 0, GetCultureHandle(culture));
        if (stringBuilder.Length == 0)
            return ' ';
        return stringBuilder[0];
    }

    private static IntPtr EnglishCultureHandle
    {
        get { return GetCultureHandle("en-US"); }
    }

    private static IntPtr GetCultureHandle(string culture)
    {
        return InputLanguage.FromCulture(new CultureInfo(culture)).Handle;
    }

    /// <summary>
    /// Gets key states for ToUnicodeEx function
    /// </summary>
    private static byte[] GetKeyStates(uint keyCode, bool shiftPressed)
    {
        const byte keyPressFlag = 0x80;
        const byte shifPosition = 16; // position of Shift key in keys array
        var keyStatses = new byte[256];
        keyStatses[keyCode] = keyPressFlag;
        keyStatses[shifPosition] = shiftPressed ? keyPressFlag : (byte)0;
        return keyStatses;
    }
}

public class KeyMappingWinApi
{
    [DllImport("user32.dll")]
    public static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl);

    [DllImport("user32.dll")]
    public static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState,
        [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);

    [DllImport("user32.dll")]
    public static extern short VkKeyScanEx(char ch, IntPtr dwhkl);
}
于 2011-01-26T17:47:28.787 に答える
1

これはかなり単純だと思います。一連のボタンを作成し、各ボタンに文字を割り当てるだけで、ボタンの Click メソッド内で簡単に実行できます。

SendKeys.Send("A"); 

ボタンなどに基づいてキーを変更する

于 2011-01-24T11:34:01.643 に答える
0

あなたはこれらの人をチェックしたいかもしれません:

http://cnt.lakefolks.com/

開発するよりも買うだけの方が安いかもしれません、あなたは決して知りません;-)

于 2011-04-08T21:28:28.137 に答える