Application.AddMessageFilter - как прочитать, какие именно клавиши были нажаты? - PullRequest
2 голосов
/ 13 декабря 2011

Я экспериментирую с Application.AddMessageFilter, использую некоторый код, изначально написанный Somebody Else, поэтому я не обязательно понимаю все, что здесь происходит.

Вот как выглядит код.В Main():

Application.AddMessageFilter(new KeyDownMessageFilter());

В KeyDownMessageFilter:

internal class KeyDownMessageFilter : IMessageFilter {
    private const int WM_KEYDOWN = 0x0100;

    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_KEYDOWN)
        {
            var k = (Keys)m.WParam;
            var c = (char)k;
            // and some other stuff
        }
        return false;
    }
}

я могу увидеть это, приведя m.WParam к переменной типа System.Windows.Forms.Keys и затем приведя ее кchar, я могу сказать, какая клавиша на клавиатуре была нажата.Пока все хорошо.

НО - я не могу понять, как определить разницу между клавишей Shift ed и нажатием клавиши без Shift - например, нажатием% возвращает символ '5'.Еще более странно, если посмотреть на значение k, оно выглядит как «LButton | MButton | ShiftKey | Space» (независимо от того, нажимаю ли я 5 или % ).

Документация MSDN на эту тему довольно тонкая.Может кто-нибудь объяснить, как точно сказать, какой символ был выдвинут, а для бонусных отметок объяснить, для чего предназначен этот объект Message, и почему он использует такие неописуемые свойства, как LParam и WParam, чтобы нести полезныеинформация

Ответы [ 2 ]

4 голосов
/ 13 декабря 2011

Например, нажатие "%" приводит к появлению символа '5'

. В соответствии с сообщением WM_KEYDOWN передается код виртуальной клавиши в wparam.Код виртуальной клавиши для клавиши, которая выдает «%» и «5», одинаков, это та же клавиша на клавиатуре.Он не превращается в фактическую клавишу ввода, пока Windows не обработает сообщение WM_KEYDOWN и не превратит его в сообщение WM_CHAR.Который будет проверять состояние клавиш Shift, Ctrl и Alt и соответственно изменять сгенерированный символ.Фактический символ, который создается, зависит от активной раскладки клавиатуры.

, глядя на значение k, он выглядит как «LButton | MButton | ShiftKey | Пробел»

Это побочный эффект атрибута [Flags] для типа Keys.Метод Enum.ToString () по умолчанию проверяет этот атрибут и объединяет значения перечисления, если этот атрибут присутствует.Целочисленное значение Keys.D5 составляет 0x35, комбинация 0x01 + 0x04 + 0x10 + 0x20.Соответственно Keys.LButton, MButton, ShiftKey и Space.Очевидно, в вашем случае это бесполезно, приведите к (int) в выражении наблюдения.

Ну, это объясняет, что происходит.Единственное, чего вы действительно хотите избежать, - это попытаться самостоятельно перевести виртуальный ключ в набор.Взгляните на ToUnicodeEx () Windows API-функцию, которую вы должны использовать, чтобы сделать это правильно.Вы можете использовать свойство Control.ModifierKeys, чтобы обнаружить разницу между простым Keys.D5 и нажатием клавиши Shift.

Кстати: вам также следует перехватить WM_SYSKEYDOWN, сообщение, которое генерируется при нажатии клавиши AltвнизСообщение 0x104.

0 голосов
/ 13 декабря 2011

Ловушка WM_CHAR, она уже будет переведена со сменой, и вы должны получить%.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...