标签归档:WM_APPCOMMAND

.NET下使用全局Shell Hook

今天我解决了一个长期困扰我的问题,那就是如何在.NET程序中使用全局Shell Hook。

豆瓣电台需要响应用户按下键盘上的“播放/暂停”键与“下一首”键,无论豆瓣电台的窗口是否处于活动状态。

响应多媒体指令的最佳方法就是处理WM_APPCOMMAND消息,但WM_APPCOMMAND消息只在窗口处于活动状态时才会触发,当窗口处于非活动状态时,WM_APPCOMMAND是不会触发的。从某种角度上来说,WM_APPCOMMAND消息不是全局广播的。另一个办法是使用全局Shell Hook,使用SetWindowsHookEx函数添加一个类型为WH_SHELL的全局钩子,并在Shell钩子的回调函数中处理wParam参数为HSHELL_APPCOMMAND的消息。一切看起来很美好,不是吗?别急,下面才是重点。豆瓣电台使用C#编写,生成的代码当然为托管代码,而包含全局钩子的代码必须编译为本机DLL,所以单纯使用托管代码是无法安装全局钩子的(见此文的“在 .NET 框架中不支持全局挂钩”一节)。难道要逼我用C++写个DLL?注册热键的方法也不太好,因为热键有唯一性,可能会出现热键冲突。

继续阅读