Прослушивать ключ, когда приложение не фокусируется

У меня есть приложение (С# 4.0-WPF), которое скрыто и может быть отображено нажатием значка systray или на другом созданном мной кадре (маленький кадр, который состыкован слева и сверху).

Мой клиент хочет добавить новый способ отображения приложения: При нажатии на клавишу "F" (например, F9).

Как я могу узнать в своем приложении, если пользователь нажимает эту клавишу, когда приложение не является текущим окном/или не сфокусировано?

Ответ 1

Глобальные перехватчики клавиатуры не являются правильным решением, если вы хотите только несколько глобальных горячих клавиш.

  • Глобальный крючок клавиатуры с использованием WH_KEYBOARD означает, что ваша DLL будет внедрена в каждый процесс, который получает нажатия клавиш. Он не должен использоваться вообще в управляемом коде, поскольку CLR имеет относительно большой вес и может вызвать конфликты версий.

    Эта инъекция кода также будет выглядеть подозрительной для антивирусного программного обеспечения, которое может блокировать ее.

  • Захват клавиатуры низкого уровня с использованием WH_KEYBOARD_LL - лучший выбор для управляемого кода, поскольку он обрабатывает события клавиатуры в вашем собственном приложении. Тем не менее это требует, чтобы каждое событие клавиатуры обрабатывалось вашим потоком.

    Это увеличивает время между нажатой клавишей и получающим ее целевым приложением.

    Это особенно плохо, если приложение с более высоким приоритетом ЦП, чем ваше приложение, выдает ему процессорное время. В этом случае латентность может достигать нескольких секунд, группируя множество клавиш. Некоторые (плохо написанные) игры работают так и становятся неиграбельными в такой ситуации.

  • Функция API Windows RegisterHotKey - это правильная функция для глобальных горячих клавиш.

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

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