阻止Win 8中的键盘播放/暂停按钮

时间:2014-03-27 18:04:57

标签: c++ hook keyboard-hook setwindowshookex

我正在编写一个需要暂时禁用多媒体键盘上显示的播放/暂停按钮的应用程序。

通常情况下,通过安装低级键盘挂钩(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中一切正常。

或者,有人可以建议另一种方法来阻止多媒体键盘播放/暂停按钮吗?

1 个答案:

答案 0 :(得分:0)

来自ShellProc的MSDN文档:

  

HSHELL_APPCOMMAND:用户完成输入事件(例如,按下鼠标上的应用程序命令按钮或键盘上的应用程序命令键),应用程序未处理生成的WM_APPCOMMAND消息通过那个输入。 [重点补充。]

强调部分表明只有在应用程序忽略WM_APPCOMMAND后才会调用钩子回调。换句话说,你来不及。

为了捕捉飞行中的消息,我认为你需要一种不同类型的钩子。也许WH_GETMESSAGE或WH_CALLWNDPROC。

但是你为什么要阻止用户选择与他们的应用程序交互?