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

PreviewKeyDown не видит Alt-модификаторы

У меня есть код, который (предположительно) будет захватывать нажатия клавиш. Окно верхнего уровня имеет

Keyboard.PreviewKeyDown="Window_PreviewKeyDown"

и файл CS поддержки:

private void Window_PreviewKeyDown(object sender, KeyEventArgs e) {
    if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) {
        switch (e.Key) {
            case Key.L:
                btnPrev_Click(sender, new RoutedEventArgs());
                e.Handled = true;
                break;
            case Key.R:
                btnNext_Click(sender, new RoutedEventArgs());
                e.Handled = true;
                break;
        }
    }
}

Теперь, когда все работает нормально, оба CTRL L и CTRL R вызывают соответствующие функции.

Как только я изменю проверку модема на использование ModifierKeys.Alt, он перестает работать. Другими словами, ни ALT L, и ALT R не вызывают функции.

Что мне здесь не хватает?

4b9b3361

Ответ 1

В случае модификатора Alt e.Key возвращает Key.System, а реальный ключ находится в e.SystemKey. Вы можете использовать следующий фрагмент кода, чтобы всегда получать правильную нажатую клавишу:

Key key = (e.Key == Key.System ? e.SystemKey : e.Key);

Ответ 2

Проблема заключается в том, что, когда Alt удерживается, KeyEventArgs имеет:

Key = Key.System
SystemKey = the real key

поэтому при проверке Alt вам нужно использовать e.SystemKey вместо e.Key, например:

if (e.KeyboardDevice.Modifiers == ModifierKeys.Alt) {   
    switch (e.SystemKey) { 
      ...

Объяснение

В Windows, клавиша "Alt" обрабатывается специально. Когда нажата клавиша Alt или нажата другая клавиша, когда клавиша Alt удерживается нажатой, это считается нажатием клавиши "Система". "Системные" нажатия клавиш обрабатываются по-разному, чем обычные нажатия клавиш разными способами.

Все начинается, когда Windows передает нажатие на ваше приложение. События с нормальным нажатием клавиши генерируют WM_KEYDOWN, но если нажата клавиша Alt, генерируется WM_SYSKEYDOWN. Точно так же WM_KEYUP переводится в WM_SYSKEYUP.

В Windows, в том числе в WPF, специальная обработка клавиши Alt используется с MenuItems, кнопками и ярлыками, которые включают "текст доступа". Например, если кнопка имеет содержимое "Say _Hi", то нажатие Alt-H будет считаться нажатием кнопки.

Когда клавиша Alt нажата, буквы входят в три пары событий: KeyDown, KeyUp и TextInput, каждая из которых имеет связанные версии предварительного просмотра. Основные отличия здесь:

  • События KeyDown и KeyUp имеют свойство Key для "Key.System", а не фактический нажатый ключ, а SystemKey установлен на фактическую нажатую клавишу.
  • Событие TextInput передается нормально, но затем обрабатывается как AccessKey, если оно не используется