Перехват глобальных горячих клавиш (Windows)

Сейчас я пытаюсь создать аналогичную функциональность, как в приложениях для голосового чата Push-To-Talk, но пока не смог найти для этого подходящих решений. Я не использую MFC или CLR.

Проблема довольно проста. Мое окно обычно должно быть не в фокусе (т. е. свернуто и т. д.), но мне нужно реагировать на нажатия клавиш (по сути, я даже не хочу знать, удерживается ли кнопка нажатой или нет). К сожалению, WM_KEYDOWN работает, только если окно находится в фокусе клавиатуры. Я знаю, что, например, Teamspeak использует для этого DirectInput, но я также знаю, что это определенно можно сделать и без него, что я бы очень предпочел.

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


person dialer    schedule 10.03.2011    source источник


Ответы (2)


Проблема может быть решена с помощью RegisterHotKey или с помощью глобального низкоуровневого перехвата клавиатуры< /а>.

RegisterHotKey (который Коди Грей предложил в похвалах), вероятно, здесь более подходящий выбор.

person Jon    schedule 10.03.2011
comment
Хорошо, теперь я чувствую себя немного глупо из-за того, что не угадал имя функции RegisterHotKey; API слишком интуитивно понятен для меня. Спасибо вам обоим. - person dialer; 10.03.2011
comment
@dialer: Нет причин чувствовать себя плохо. Несколько дней назад я ответил на вопрос, предлагающий глобальный хук, когда RegisterHotKey сработало бы просто отлично. К счастью, кто-то еще поправил меня (часть того, что делает этот сайт замечательным). Дело не в том, что Windows API неинтуитивен (по крайней мере, для меня), просто он настолько велик, что вы забываете о вещах, если не используете их все время! Рады, что смогли помочь. - person Cody Gray; 10.03.2011
comment
@Cody: Спасибо, что напомнили мне о RegisterHotKey. Именно это и случилось со мной здесь: забыл об этом, и случайно использовал клавиатурный хук совсем недавно ... - person Jon; 10.03.2011
comment
если другое приложение использует ту же горячую клавишу, что и я, то RegisterHotKey не удастся. не так ли? в этом случае альтернативой является использование глобальной клавиатуры. это не? - person Jayapal Chandran; 11.12.2014
comment
@JayapalChandran: Да и да - я не уверен на 100%, но вполне. - person Jon; 11.12.2014

Я согласен с Джоном. Используйте user32.dll и функцию RegisterHotKey. Очень полезный пример кода находится по адресу: https://www.codeproject.com/kb/cs/kiosk_cs.aspx?display=print

Если, как у меня изначально, код выглядит полной тарабарщиной и вы не знаете, что делать, посмотрите обучающие материалы: https://www.youtube.com/watch?v=qQWqGOaZiFI Они очень полезны!

Если вы попытаетесь зарегистрировать системную горячую клавишу: однако обратите внимание, что код из первой ссылки вернет ошибку, в зависимости от того, какую системную горячую клавишу вы пытаетесь зарегистрировать. Мой вопрос по этому поводу, который подчеркивает проблему: Как вы отключить системные горячие клавиши в user32.dll? (в настоящее время не решена). Там также есть редактирование кода, которое исправит одну из ошибок, которые вы получите, если попытаетесь переопределить горячие клавиши системы:

[DllImport("user32.dll", SetLastError = true)]

Мне удалось заблокировать горячую клавишу Windows + E, но другие, такие как Alt + F4 и Home + Right, не были отключены и возвращали ошибка.

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

Marshal.GetLastWin32Error()

^ Полный контекст этой строки кода находится в первой ссылке!

person Rehaan    schedule 10.04.2017