Translate Keys to char

北城余情 提交于 2019-12-30 12:14:20

问题


I want to translate a given set of System.Windows.Forms.Keys and a System.Windows.Forms.InputLanguage to the corresponding System.Char.

Tried some experiments with MapVirtualKeyEx, but there is now way to consider keyboard state, and ToUnicodeEx is a pain with dead keys.

My goal is a function ...

static char? FromKeys(Keys keys, InputLanguage inputLanguage)
{
    // As I think what can be helpful and I got trying to find a solution for this problem:
    Keys vkCode = keys & Keys.KeyCode;
    Keys modifiers = keys & Keys.Modifiers;

    byte[] keyboardState = new byte[256];

    keyboardState[vkCode] = 1 << 7;

    if (modifiers.HasFlag(Keys.Shift))
    {
        keyboardState[(int)Keys.ShiftKey] = 1 << 7;
    }

    if (modifiers.HasFlag(Keys.Control))
    {
        keyboardState[(int)Keys.ControlKey] = 1 << 7;
    }

    if (modifiers.HasFlag(Keys.Alt))
    {
        keyboardState[(int)Keys.Menu] = 1 << 7;
    }

    // [Put your code here]
}

... which should be called like this:

FromKeys(Keys.A | Keys.Shift, InputLanguage.CurrentInputLanguage); // = 'A'
FromKeys(Keys.Escape, InputLanguage.DefaultInputLanguage); // = null
FromKeys(Keys.Oemtilde, InputLanguage.FromCulture(new CultureInfo("de-DE"))); // = 'ö'
FromKeys(Keys.E | Keys.Control | Keys.Alt, InputLanguage.FromCulture(new CultureInfo("de-DE"))); // = '€'

(Be aware of Keys.Shift and Keys.ShiftKey!)

How would this function look like?

The answer I'll choose should provide a way to translate one "normal" System.Windows.Forms.Keys with an optional combination of the modifiers (Keys.Shift, Keys.Alt, Keys.Control) to a System.Char. Multiple successively calls have to result in the same character. No hardcoded keyboard layouts, the InputLanguage defines the layout to use.

As a help to understand what I'm trying to to: Generate a KeyPressEventArgs with just the KeyEventArgs (and the correct InputLangauge) given.

Dead keys should not affect FromKeys!


回答1:


Here is a piece of code that seems to do what you're looking for - if I understood it correctly :-)

    public static char? FromKeys(Keys keys, InputLanguage inputLanguage)
    {
        return FromKeys(keys, inputLanguage, true);
    }

    private static char? FromKeys(Keys keys, InputLanguage inputLanguage, bool firstChance)
    {
        if (inputLanguage == null)
        {
            inputLanguage = InputLanguage.CurrentInputLanguage;
        }

        byte[] keyStates = new byte[256];

        const byte keyPressed = 0x80;
        keyStates[(int)(keys & Keys.KeyCode)] = keyPressed;
        keyStates[(int)Keys.ShiftKey] = ((keys & Keys.Shift) == Keys.Shift) ? keyPressed : (byte)0;
        keyStates[(int)Keys.ControlKey] = ((keys & Keys.Control) == Keys.Control) ? keyPressed : (byte)0;
        keyStates[(int)Keys.Menu] = ((keys & Keys.Alt) == Keys.Alt) ? keyPressed : (byte)0;

        StringBuilder sb = new StringBuilder(10);
        int ret = ToUnicodeEx(keys, 0, keyStates, sb, sb.Capacity, 0, inputLanguage.Handle);
        if (ret == 1)
            return sb[0];

        if (ret == -1)
        {
            // dead letter
            if (firstChance)
            {
                FromKeys(keys, inputLanguage, false);
            }
            return null;
        }
        return null;
    }

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern int ToUnicodeEx(Keys wVirtKey, uint wScanCode, byte[] lpKeyState, StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);



回答2:


I'm not certain this will work, but you might take a look at ToUnicodeEx. It lets you set the keyboard state as well as the input locale.

Another possibility, although pretty involved, would be to turn your events into strings that are compatible with SendKeys, and then send the string to your application.

You'd have to set the culture for the main thread and use a separate thread to do the sending.

I don't know how well something like that would work, and it's kind of expensive (in terms of time) to try it.



来源:https://stackoverflow.com/questions/6214326/translate-keys-to-char

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!