头文件声明(CSWVolumeController.h):
#pragma once
#include "Mmsystem.h"
#define MAX_VOLUME 100
class CSWVolumeController: public IAudioEndpointVolumeCallback
{
public:
CSWVolumeController();
virtual ~CSWVolumeController();
protected:
LONG m_nRef;
HWND m_hParentWnd;
int m_nMaxVolume;
int m_nCurVolume;
IMMDeviceEnumerator* m_pDeviceEnumerator;
IMMDevice* m_pDevice;
IAudioEndpointVolume* m_pAudioEndpointVolume;
IAudioClient* m_pAudioClient;
STDMETHODIMP_(ULONG)AddRef()
{
return InterlockedIncrement(&m_nRef);
}
STDMETHODIMP_(ULONG)Release()
{
LONG nRef = InterlockedDecrement(&m_nRef);
if (nRef == 0)
delete this;
return nRef;
}
STDMETHODIMP QueryInterface(REFIID riid, void **ppvInterface) //这个函数也不知道有什么作用?
{
if ( riid == IID_IUnknown )
{
AddRef();
*ppvInterface = static_cast<IUnknown*>(this);
}
else if ( riid == __uuidof(IAudioEndpointVolumeCallback) )
{
AddRef();
*ppvInterface = static_cast<IAudioEndpointVolumeCallback*>(this);
return S_OK;
}
else
{
*ppvInterface = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
STDMETHODIMP OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify)
{
if ( pNotify == NULL )
{
return E_INVALIDARG;
}
m_nCurVolume = (UINT32)(MAX_VOLUME*pNotify->fMasterVolume + 0.5);
return S_OK;
}
void SetMaxVolume(int nVolume);
public:
void SetVolume(int nVolume);
int GetVolume();
};
源码实现(CSWVolumeController.cpp):
// SWVolumeController.cpp : 实现文件
//
#include "stdafx.h"
#include "SWVolumeController.h"
//
CSWVolumeController::CSWVolumeController(): m_nRef(1)
{
CoInitialize(0);
m_hParentWnd = NULL;
m_nMaxVolume = MAX_VOLUME;
m_pDeviceEnumerator = NULL;
m_pDevice = NULL;
m_pAudioEndpointVolume = NULL;
m_pAudioClient = NULL;
HRESULT hr = E_NOTIMPL;
try{
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),NULL,CLSCTX_ALL,__uuidof(IMMDeviceEnumerator),(void**)&m_pDeviceEnumerator);
if(FAILED(hr)) throw "CoCreateInstance";
hr = m_pDeviceEnumerator->GetDefaultAudioEndpoint(eRender,eMultimedia,&m_pDevice);
if(FAILED(hr)) throw "GetDefaultAudioEndpoint";
hr = m_pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void**)&m_pAudioEndpointVolume);
if(FAILED(hr)) throw "pDevice->Active";
hr = m_pDevice->Activate(__uuidof(IAudioClient),CLSCTX_ALL,NULL,(void**)&m_pAudioClient);
if(FAILED(hr)) throw "pDevice->Active";
m_pAudioEndpointVolume->RegisterControlChangeNotify((IAudioEndpointVolumeCallback*)this);
}
catch(...){
if(m_pAudioClient) m_pAudioClient->Release();
if(m_pAudioEndpointVolume) m_pAudioEndpointVolume->Release();
if(m_pDevice) m_pDevice->Release();
if(m_pDeviceEnumerator) m_pDeviceEnumerator->Release();
throw;
}
m_nCurVolume = GetVolume();
}
CSWVolumeController::~CSWVolumeController()
{
if(m_pAudioClient) m_pAudioClient->Release();
if(m_pAudioEndpointVolume) m_pAudioEndpointVolume->Release();
if(m_pDevice) m_pDevice->Release();
if(m_pDeviceEnumerator) m_pDeviceEnumerator->Release();
CoUninitialize();
}
void CSWVolumeController::SetMaxVolume(int nVolume)
{
if ( m_nMaxVolume != nVolume )
{
m_nMaxVolume = nVolume;
}
}
void CSWVolumeController::SetVolume(int nVolume)
{
if ( m_nCurVolume != nVolume )
{
m_nCurVolume = nVolume >= m_nMaxVolume ? m_nMaxVolume : nVolume;
float fVolume;
fVolume = (float)m_nCurVolume/MAX_VOLUME;
HRESULT hr = m_pAudioEndpointVolume->SetMasterVolumeLevelScalar(fVolume,&GUID_NULL);
if(FAILED(hr)) throw "SetMasterVolumeLevelScalar";
}
}
int CSWVolumeController::GetVolume()
{
HRESULT hr = E_NOTIMPL;
try{
float fVolume;
hr = m_pAudioEndpointVolume->GetMasterVolumeLevelScalar(&fVolume);
if(FAILED(hr)) throw "SetMasterVolumeLevelScalar";
BOOL bMute;
hr = m_pAudioEndpointVolume->GetMute(&bMute);
if ( bMute )
m_nCurVolume = 0;
int intVolume = fVolume*MAX_VOLUME + 1;
if (intVolume>MAX_VOLUME)
intVolume =MAX_VOLUME;
m_nCurVolume = intVolume;
}
catch(...){
throw;
}
return m_nCurVolume;
}
这里主要是引用IAudioEndpointVolume接口,该接口还有几个常用功能接口,例如:
// 获取是否静音
HRESULT STDMETHODCALLTYPE GetMute( _Out_ BOOL *pbMute)
// 设置静音
HRESULT STDMETHODCALLTYPE SetMute( _In_ BOOL bMute, LPCGUID pguidEventContext)
// 获取音量范围
HRESULT STDMETHODCALLTYPE GetVolumeRange(
_Out_ float *pflVolumeMindB,
_Out_ float *pflVolumeMaxdB,
_Out_ float *pflVolumeIncrementdB)