Я пишу приложение, которое должно временно отключить кнопку Play / Pause, которая появляется на мультимедийных клавиатурах.
Как правило, клавиша может быть довольно легко заблокирована установкой низкоуровневой клавиатуры (WH_KEYBOARD_LL
) где KeyboardProc
перехватывает ключ (в этом случае VK_MEDIA_PLAY_PAUSE
) и возвращает 1 вместо вызова CallNextHookEx
, Я пробовал это с другими ключами (включая ключ Windows VK_LWIN
) и это работает отлично. У меня также нет проблем с этим методом под Windows 7, где все ключи, в том числе VK_MEDIA_PLAY_PAUSE
получить заблокирован.
Windows 8 — это другая история. Когда мое приложение имеет фокус ввода, все работает как положено, то есть VK_MEDIA_PLAY_PAUSE
ключ блокируется, и никакое другое приложение не отвечает на него. Однако, когда мое приложение теряет фокус, вызывается моя подключаемая процедура (это было проверено путем отправки OutputDebugString
) но другие приложения реагируют на ключ, даже если я возвращаю 1. Как только мое приложение снова сфокусируется, все блокируется, как и должно быть.
После некоторого исследования я обнаружил, что мультимедийные клавиши не только генерируют нажатия клавиш, но и генерируют WM_APPCOMMAND
сообщения, чтобы я добавил ShellProc (WH_SHELL)
подключить с помощью следующей процедуры подключения:
LRESULT __declspec(dllexport)__stdcall CALLBACK ShellProc(int nCode,WPARAM wParam,LPARAM lParam)
{
// Do we have to handle this message?
if (nCode == HSHELL_APPCOMMAND)
{
OutputDebugStringX(">>>>> HSHELL_APPCOMMAND");
// Process the hook if the hNotifyWnd window handle is valid
short AppCommand = GET_APPCOMMAND_LPARAM(lParam);
switch (AppCommand)
{
case APPCOMMAND_MEDIA_NEXTTRACK:
case APPCOMMAND_MEDIA_PLAY_PAUSE:
case APPCOMMAND_MEDIA_PREVIOUSTRACK:
case APPCOMMAND_MEDIA_STOP:
OutputDebugString(">>>>>ShellProc got a media command");
return 1;
}
}
// Call the next handler in the chain
return CallNextHookEx (hsh, nCode, wParam, lParam);
}
Эта процедура вызывается только тогда, когда мое приложение имеет фокус ввода. Всякий раз, когда у меня есть фокус ввода и возвращаю 1, команда Play / Pause блокируется. Как только я теряю фокус, процедура не вызывается / подключается.
Кто-нибудь имеет представление о том, что происходит? Как я уже упоминал, код работает для других клавиш, но не для мультимедийных клавиш. Все отлично работает в Windows 7.
В качестве альтернативы, может кто-нибудь предложить другой способ блокировки мультимедийных клавиатур кнопкой Play / Pause?
Из документации MSDN для ShellProc:
HSHELL_APPCOMMAND: пользователь завершил событие ввода (например, нажал кнопку приложения на клавиатуре мыши или клавишу на клавиатуре приложения) и приложение не обработало сообщение WM_APPCOMMAND генерируется этим входом. [Акцент добавлен.]
Подчеркнутая часть предполагает, что ваш обратный вызов перехватывается только после того, как приложение игнорирует WM_APPCOMMAND. Другими словами, вы опоздали.
Чтобы поймать сообщение в полете, я думаю, вам нужен другой тип крючка. Возможно WH_GETMESSAGE или WH_CALLWNDPROC.
Но почему вы пытаетесь запретить пользователям взаимодействовать со своими приложениями по своему усмотрению?
Других решений пока нет …