C++ 在Win 8中阻止键盘播放/暂停按钮

C++ 在Win 8中阻止键盘播放/暂停按钮,c++,hook,keyboard-hook,setwindowshookex,C++,Hook,Keyboard Hook,Setwindowshookex,我正在编写一个需要暂时禁用多媒体键盘上显示的播放/暂停按钮的应用程序 通常,通过安装一个低级键盘挂钩(WH\u keyboard\u LL)可以很容易地锁定一个键,KeyboardProc在这里截取键(在这种情况下,VK\u MEDIA\u PLAY\u PAUSE),并返回1,而不是调用CallNextHookEx。我用其他键(包括Windows键VK_LWIN)尝试过这个方法,效果非常好。在Windows 7下,我也不会遇到这种方法的问题,在Windows 7下,所有键,包括VK\u MED

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

通常,通过安装一个低级键盘挂钩(
WH\u keyboard\u LL
)可以很容易地锁定一个键,
KeyboardProc
在这里截取键(在这种情况下,
VK\u MEDIA\u PLAY\u PAUSE
),并返回1,而不是调用
CallNextHookEx
。我用其他键(包括Windows键
VK_LWIN
)尝试过这个方法,效果非常好。在Windows 7下,我也不会遇到这种方法的问题,在Windows 7下,所有键,包括
VK\u MEDIA\u PLAY\u PAUSE
都会被阻止

Windows8则是另一回事。当我的应用程序有输入焦点时,一切都按预期工作,这意味着
VK\u MEDIA\u PLAY\u PAUSE
键被阻止,没有其他应用程序响应它。然而,当我的应用程序失去焦点时,我的钩子过程被调用(这是通过发送
OutputDebugString
验证的),但其他应用程序响应键,即使我返回1。一旦我的应用程序再次获得焦点,一切都会被阻塞

经过一些调查,我发现多媒体键不仅会生成击键,还会生成
WM_APPCOMMAND
消息,因此我添加了
ShellProc(WH_SHELL)
hook,使用以下钩子过程:

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时,播放/暂停命令就会被阻止。一旦我失去焦点,程序就不会被调用/钩住

有人知道发生了什么事吗?正如我提到的,代码适用于其他键,而不是多媒体键。在Windows7中一切正常


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

来自MSDN文档,用于:

HSHELL_APPCOMMAND:用户完成了一个输入事件(例如,按下鼠标上的应用程序命令按钮或键盘上的应用程序命令键),并且应用程序没有处理该输入生成的WM_APPCOMMAND消息。[增加重点。]

强调的部分表明,只有在应用程序忽略WM_APPCOMMAND之后,才会调用钩子回调。换句话说,你太晚了

为了在飞行中捕捉信息,我想你需要一种不同类型的钩子。可能是WH_GETMESSAGE或WH_CALLWNDPROC


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

告诉我们你是如何设置钩子的。要设置钩子,我要调用:hsh=setWindowshookx(WH_SHELL,(HOOKPROC)ShellProc,hins,0);如果是这种情况(即太晚了),为什么当我的应用程序在前台时我能够钩住并阻止APPCOMMAND?另外,即使APPCOMMAND只是在之后才被调用,为什么我的应用程序不在前台时我的hook proc根本没有被调用?你的应用程序是设置hook的吗?你还在设置whu键盘和whu外壳吗?他们都试图阻止吗?另一个应用程序的比特数(32-/64-?)是否与您的相同?另一个应用程序是否与您的应用程序处于相同的完整性级别?根据这些问题的答案,我可以看到许多与观察到的行为和我的答案一致的场景。另一个应用程序是Windows应用商店应用程序吗?看起来您可能无法将全局挂钩加载到商店应用程序(或从商店应用程序加载)。请看,我的32位应用程序是设置挂钩的应用程序。它在具有uiAccess的系统帐户下运行。我试图阻止的应用程序是一个未提升的32位应用程序(MS Media Player)。两者都在同一个桌面上运行-不涉及商店应用程序。操作系统是64位Windows 8.1 Pro。我设置了WH_键盘和WH_外壳挂钩,但目前我正在为KeyboardProc返回CallNextHookEx,因为当我返回1时,它没有阻止VK_媒体播放暂停。你能解释一下这种行为吗?也许媒体播放器也使用了一个低级键盘挂钩,它恰好比你的更早出现在挂钩链中。您确定Windows 8.1附带的MS Media Player不是Windows应用商店应用程序吗?我不清楚桌面应用程序和商店应用程序是否一定是相互排斥的。