Перевести ключи на символ - PullRequest
1 голос
/ 02 июня 2011

Я хочу перевести данный набор System.Windows.Forms.Keys и System.Windows.Forms.InputLanguage в соответствующий System.Char.

Пробовал некоторые эксперименты с MapVirtualKeyEx, но теперь есть способ рассмотреть состояние клавиатуры, и ToUnicodeEx - боль с мертвыми клавишами .

Моя цель - функция ...

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]
}

... который должен называться так:

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"))); // = '€'

(знать о Keys.Shift и Keys.ShiftKey!)

Как будет выглядеть эта функция?

Ответ, который я выберу, должен обеспечить способ перевода одного "нормального" System.Windows.Forms.Keys с необязательной комбинацией модификаторов (Keys.Shift, Keys.Alt, Keys.Control) в System.Char , Несколько последовательных вызовов должны приводить к одному и тому же символу. Нет жестко закодированных раскладок клавиатуры, InputLanguage определяет используемую раскладку.

В качестве помощи, чтобы понять, что я пытаюсь: Сгенерировать KeyPressEventArgs только с заданным KeyEventArgs (и правильным InputLangauge).

Мертвые клавиши не должны влиять FromKeys!

Ответы [ 2 ]

5 голосов
/ 06 июня 2011

Вот фрагмент кода, который, кажется, делает то, что вы ищете - если я правильно понял: -)

    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);
0 голосов
/ 02 июня 2011

Я не уверен, что это сработает, но вы можете взглянуть на ToUnicodeEx . Позволяет установить состояние клавиатуры и язык ввода.

Другая возможность, хотя и довольно сложная, состоит в том, чтобы превратить ваши события в строки, совместимые с SendKeys , а затем отправить строку в ваше приложение.

Вы должны установить культуру для основного потока и использовать отдельный поток для отправки.

Я не знаю, насколько хорошо что-то подобное будет работать, и довольно дорого (с точки зрения времени) попробовать это.

...