开发者

How to write an localized on-screen-keyboard

开发者 https://www.devze.com 2023-02-06 15:23 出处:网络
I have to write an on screen keyboard for our company\'s program, which is mostly used on industry\'s PCs with touch capability.

I have to write an on screen keyboard for our company's program, which is mostly used on industry's PCs with touch capability.

We can't use the windows default keyboard because we don't need all keys on the keyboard. So I was asked开发者_高级运维 to write a custom one in C#.

I already found this blog as reference, but I'm not sure how to start.

I created a small prototype GUI and assign for each key a scancode, and translate these scancodes to the related character. And send them to the active control. But I'm not sure what scancodes I should use.

So my question is, is that the correct way to write a OSK like this and if yes which scancodes should I use? Any links?

I'm also not sure how to handle the shift states...

Edit:

Okay I did a bit more research and came up with a osk which reads the current keyboard layout and even handles the easy shift states (Shift and Alt Gr). I wrote a KeyButton class which inherits from Button, this KeyButton has a ScanCode property of type byte and if you assign a valid scancode to it, the KeyButton will call the related functions to get the correct text. I used the functions from Michael Kaplan blogs with some small changes. In the end it turned out that I just had to do the same as he did.

So the answer to my question is: Yes, you have to use scancodes on your buttons and then get the virtualkey and the unicode from the keyboard layout. Use these scancodes.

Now I get the characters the only thing left is to send these around.


I think this is fairly simple, just make a series of buttons and assign each button a letter, and inside the buttons Click method you can do a simple.

SendKeys.Send("A"); 

Changing key based on button etc


I wrote mapping classes that map key code to character for WPF application. May be this can help.

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);
}


You might want to check out these guys:

http://cnt.lakefolks.com/

Might be cheaper just to buy it rather than develop it, ya never know ;-)

0

精彩评论

暂无评论...
验证码 换一张
取 消