我正在编写一个需要暂时禁用多媒体键盘上显示的播放/暂停按钮的应用程序。
通常情况下,通过安装低级键盘挂钩(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时,播放/暂停命令就会被阻止。一旦我失去焦点,程序就不会被调用/挂钩。
任何人都知道发生了什么事吗?正如我所提到的,代码适用于其他键,而不是多媒体键。在Windows 7中一切正常。
或者,有人可以建议另一种方法来阻止多媒体键盘播放/暂停按钮吗?
答案 0 :(得分:0)
来自ShellProc的MSDN文档:
HSHELL_APPCOMMAND:用户完成输入事件(例如,按下鼠标上的应用程序命令按钮或键盘上的应用程序命令键),应用程序未处理生成的WM_APPCOMMAND消息通过那个输入。 [重点补充。]
强调部分表明只有在应用程序忽略WM_APPCOMMAND后才会调用钩子回调。换句话说,你来不及。
为了捕捉飞行中的消息,我认为你需要一种不同类型的钩子。也许WH_GETMESSAGE或WH_CALLWNDPROC。
但是你为什么要阻止用户选择与他们的应用程序交互?