Windows音量变化通知 - 系统音量监控
Endpoint Volume Controls
本次使用win32 api的Endpoint Volume Controls实现当系统音量变化时程序收到通知,环境为win10 64位。
[1] 实现IAudioEndpointVolumeCallback接口
实现IAudioEndpointVolumeCallback接口,重点是OnNotify方法。
/* Epvolume.h */
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
// Client's proprietary event-context GUID
extern GUID g_guidMyContext;
class CAudioEndpointVolumeCallback : public IAudioEndpointVolumeCallback
{
LONG _cRef;
public:
CAudioEndpointVolumeCallback() :
_cRef(1)
{
}
~CAudioEndpointVolumeCallback()
{
}
// IUnknown methods -- AddRef, Release, and QueryInterface
ULONG STDMETHODCALLTYPE AddRef() //增加引用计数
{
return InterlockedIncrement(&_cRef);
}
ULONG STDMETHODCALLTYPE Release() //减少引用计数
{
ULONG ulRef = InterlockedDecrement(&_cRef);
if (0 == ulRef)
{
delete this;
}
return ulRef;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID** ppvInterface)//查询组件实现接口
{
if (IID_IUnknown == riid)
{
AddRef();
*ppvInterface = (IUnknown*)this;
}
else if (__uuidof(IAudioEndpointVolumeCallback) == riid)
{
AddRef();
*ppvInterface = (IAudioEndpointVolumeCallback*)this;
}
else
{
*ppvInterface = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
// Callback method for endpoint-volume-change notifications.
//接口 - 通知方法实现
HRESULT STDMETHODCALLTYPE OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify)
{
if (pNotify == NULL)
{
return E_INVALIDARG;
}
if (pNotify->guidEventContext != g_guidMyContext)
{
float fVolume = pNotify->fMasterVolume; //主音量级别
}
return S_OK;
}
};
[2] 主函数
主函数作用是创建实例,初始化,注册事件和注销。
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include "Epvolume.h"
GUID g_guidMyContext = GUID_NULL;
static IAudioEndpointVolume* g_pEndptVol = NULL;
#define SAFE_RELEASE(punk) if((punk) != NULL){ (punk)->Release(); (punk) = NULL; }
int main()
{
HRESULT hr = S_OK;
IMMDeviceEnumerator* pEnumerator = NULL;
IMMDevice* pDevice = NULL;
CAudioEndpointVolumeCallback EPVolEvents;
//初始化
CoInitialize(NULL);
//创建GUID
hr = CoCreateGuid(&g_guidMyContext);
// Get enumerator for audio endpoint devices.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator);
// Get default audio-rendering device.
hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
//激活
hr = pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&g_pEndptVol);
//注册控件变化通知
hr = g_pEndptVol->RegisterControlChangeNotify((IAudioEndpointVolumeCallback*)&EPVolEvents);
//消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) //从消息队列中取消息
{
TranslateMessage(&msg); //转换消息
DispatchMessage(&msg); //派发消息
}
//释放
SAFE_RELEASE(pEnumerator)
SAFE_RELEASE(pDevice)
SAFE_RELEASE(g_pEndptVol)
CoUninitialize();
return 0;
}
总结
总的来说,我们实现了利用Endpoint Volume Controls来监控系统音量的功能,但实际上该控件并不知有这一个功能,还可以用来做一个音量控制面板实现调节音量的功能。阅读官方文档,学习更多知识。