Подтвердить что ты не робот

Ключевые события: ProcessCmdKey

Я пытаюсь получить ответ на клавиатуру на небольшом тестовом приложении Windows Form, и у меня есть грубое решение, которое должно переопределить ProcessCmdKey. Однако есть несколько проблем, с которыми я сталкиваюсь, и несоответствия, которые я нахожу.

Различные события: Есть ли способ указать в аргументах ref Message msg, Keys keyData, является ли четный ключ KeyDown, KeyUp или KeyPress?

KeyPress: Всюду, о которой я говорил, говорит, что KeyPress, т.е. повторный ввод с клавиатуры, происходит только для клавиш символов, которых нет в клавишах со стрелками. Однако обработчик события вызывается как часто, и в том же mannor/с тем же самым поведением, для клавиш со стрелками, как клавиши символов. Это на первый взгляд событие KeyPress, или это что-то еще?

В идеале я бы хотел, чтобы на уровне формы были задействованы все события клавиатуры, не позволяя им перейти к элементам управления формы. Однако вся документация достаточно смутила меня и пропустила ключевые моменты, так что я не смог это завершить.

Помощь по любой из этих тем приветствуется. Спасибо!

4b9b3361

Ответ 1

Структура Message передана ProcessCmdKey() содержит номер сообщения WINAPI в свойстве Msg:

  • WM_KEYDOWN - 0x100 (256),
  • WM_KEYUP есть 0x101 (257),
  • WM_CHAR (примерно эквивалентно KeyPress) составляет 0x102 (258),
  • WM_SYSKEYDOWN 0x104 (260),
  • WM_SYSKEYUP - 0x105 (261).

Что касается вашего вопроса о KeyPress, это правда, что несимвольные клавиши, такие как клавиши со стрелками, не генерируют сообщения WM_CHAR внутри, но они генерируют WM_KEYDOWN, и это сообщение также отправляется несколько раз для повторный ввод.

Также обратите внимание, что я не уверен, что ProcessCmdKey() - правильный метод для достижения того, чего вы хотите. Документация описывает это как обработку main menu command keys and MDI accelerators, которая может быть только подмножеством ключей, которые вы хотите уловить. Вместо этого вы можете переопределить ProcessKeyPreview(), который обрабатывает все сообщения клавиатуры, полученные дочерними элементами управления.

Ответ 2

Переопределение ProcessCmdKey в вашей форме явно предназначено для того, чтобы вы могли реализовать пользовательскую короткую обработку нажатия клавиш вне встроенной мнемонической обработки в кнопках и пунктах меню.

Он только когда-либо вызывается в событии с ключом, прежде чем управление с фокусом получит событие KeyDown и независимо от того, какой клиентский элемент управления имеет фокус. Поэтому не связан с KeyUp, а не с KeyPress. Вы возвращаете true из вашего переопределения, когда распознаете ключ после выполнения функции быстрого доступа. Это предотвращает дальнейшую обработку ключа, не генерирует никаких событий KeyDown/Press/Up.

Очень редко используется аргумент msg метода, значение msg.Msg будет только когда-либо WM_KEYDOWN или WM_SYSKEYDOWN с последним сообщением, созданным, когда пользователь удерживает клавишу Alt. Который вас не волнует, поскольку вы всегда можете получить, если из аргумента keyData. Вот так:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == (Keys.Alt | Keys.F)) {
            // Alt+F pressed
            doSomething();
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

Другие модификаторы, которые вы можете проверить с помощью | оператор, используемый здесь, - Keys.Shift и Keys.Control. Итак (Keys.Shift | Keys.Control | Keys.F1) проверяет Ctrl + Shift + F1. Вы можете интерпретировать данные msg, если хотите сделать что-то необычное, например, проверить повторение ключей. Проверьте документы MSDN для уведомления WM_KEYDOWN. Значение msg.LParam содержит кучу информации об ключевом штрихе.

Обратите внимание, что вы получаете только виртуальные ключи в этом методе. Keys.F - это клавиша F на раскладке английской клавиатуры, но не обязательно одна и та же буква для ключа в том же месте на макете пользователя. Используйте функциональные клавиши, чтобы избежать головной боли документа.

Повторение клавиш - это функция контроллера клавиатуры и не ограничивается набором клавиш. Стрелка и функциональные клавиши, безусловно, будут повторяться при удержании. Вы хотите игнорировать KeyPress в этом сценарии. Но если вы назначаете клавишу быстрого доступа для клавиши, которая также вводит ключ (например, Keys.F), то вы всегда должны также проверять ключ модификатора, чтобы не нарушать элементы управления, такие как TextBox.

И последнее, но не менее важное: не забывайте о встроенной поддержке мнемоники в кнопках и элементах меню. Написание своего свойства Text, например &OK, создает ярлык самодокументирования без необходимости использования какого-либо кода. Управляемый пользователем, в этом примере, набрав Alt + O.