Windowsシステムの音量変化を監視する通知
5662 ワード
// Header File
#pragma once
#include
#include
#include
typedef void (CALLBACK* PFN_NOTIFYCALLBACK)(DWORD dwVolume, LPVOID lpContext);
class CVolumeCtrl : public IAudioEndpointVolumeCallback
{
public:
CVolumeCtrl(PFN_NOTIFYCALLBACK pCallback, LPVOID lpContext);
~CVolumeCtrl(void);
public:
inline BOOL VerifyValid(void) { return (NULL != this) ? m_bValid : FALSE; }
BOOL GetVolume(DWORD* pdwVolume);
BOOL SetVolume(DWORD dwVolume);
BOOL GetMute(BOOL* pbMute);
BOOL SetMute(BOOL bMute);
BOOL Notify(BOOL bRegister);
public:
STDMETHODIMP_(ULONG)AddRef() { return InterlockedIncrement(&m_lRefCount); }
STDMETHODIMP_(ULONG)Release()
{
LONG lRet = InterlockedDecrement(&m_lRefCount);
if (0 == lRet) { delete this; }
return lRet;
}
STDMETHODIMP QueryInterface(REFIID IID, void **ReturnValue)
{
if ((IID == IID_IUnknown) || (IID == __uuidof(IAudioEndpointVolumeCallback)))
{
*ReturnValue = static_cast(this);
AddRef();
return S_OK;
}
*ReturnValue = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotificationData)
{
if ((NULL != pNotificationData) && (NULL != m_pCallback))
{
DWORD dwVolume = (DWORD)round(pNotificationData->fMasterVolume * 100.0f);
m_pCallback(dwVolume, m_pContext);
}
return S_OK;
}
private:
BOOL Initialize(void);
void Uninitialize(void);
private:
LONG m_lRefCount;
IMMDeviceEnumerator* m_pEnumerator;
IMMDevice* m_pDevice;
IAudioEndpointVolume* m_pVolume;
BOOL m_bValid;
PFN_NOTIFYCALLBACK m_pCallback;
LPVOID m_pContext;
};
// Implement File
#include "stdafx.h"
#include "VolumeCtrl.h"
CVolumeCtrl::CVolumeCtrl(PFN_NOTIFYCALLBACK pCallback, LPVOID lpContext)
: m_pCallback(pCallback)
, m_pContext(lpContext)
, m_bValid(FALSE)
, m_lRefCount(1)
, m_pEnumerator(NULL)
, m_pDevice(NULL)
, m_pVolume(NULL)
{
CoInitialize(NULL);
do
{
if (!Initialize()) { Uninitialize(); break; }
// Completed
m_bValid = TRUE;
} while (0);
}
CVolumeCtrl::~CVolumeCtrl()
{
Uninitialize();
CoUninitialize();
}
BOOL CVolumeCtrl::GetVolume(DWORD* pdwVolume)
{
BOOL bRet = FALSE;
do
{
_ASSERT(NULL != pdwVolume);
_ASSERT(NULL != m_pVolume);
if (NULL == m_pVolume) { break; }
HRESULT hr = S_OK;
float fLevel = 0.0f;
if (FAILED(hr = m_pVolume->GetMasterVolumeLevelScalar(&fLevel))) { break; }
*pdwVolume = (DWORD)round(fLevel * 100.0f);
// Completed
bRet = TRUE;
} while (0);
return bRet;
}
BOOL CVolumeCtrl::SetVolume(DWORD dwVolume)
{
BOOL bRet = FALSE;
do
{
_ASSERT(NULL != m_pVolume);
if (NULL == m_pVolume) { LOG(ERR, TEXT("Interface Invalid!")); break; }
HRESULT hr = S_OK;
float fLevel = (float)dwVolume / 100.0f;
if (FAILED(hr = m_pVolume->SetMasterVolumeLevelScalar(fLevel, &GUID_NULL))) { break; }
// Completed
bRet = TRUE;
} while (0);
return bRet;
}
BOOL CVolumeCtrl::GetMute(BOOL* pbMute)
{
BOOL bRet = FALSE;
do
{
_ASSERT(NULL != pbMute);
_ASSERT(NULL != m_pVolume);
if (NULL == m_pVolume) { break; }
HRESULT hr = S_OK;
if (FAILED(hr = m_pVolume->GetMute(pbMute))) { break; }
// Completed
bRet = TRUE;
} while (0);
return bRet;
}
BOOL CVolumeCtrl::SetMute(BOOL bMute)
{
BOOL bRet = FALSE;
do
{
_ASSERT(NULL != m_pVolume);
if (NULL == m_pVolume) { break; }
HRESULT hr = S_OK;
if (FAILED(hr = m_pVolume->SetMute(bMute, &GUID_NULL))) { break; }
// Completed
bRet = TRUE;
} while (0);
return bRet;
}
BOOL CVolumeCtrl::Notify(BOOL bRegister)
{
BOOL bRet = FALSE;
do
{
_ASSERT(NULL != m_pVolume);
if (NULL == m_pVolume) { break; }
HRESULT hr = S_OK;
if (bRegister)
{
if (FAILED(hr = m_pVolume->RegisterControlChangeNotify(this))) { break; }
}
else
{
if (FAILED(hr = m_pVolume->UnregisterControlChangeNotify(this))) { break; }
}
// Completed
bRet = TRUE;
} while (0);
return bRet;
}
BOOL CVolumeCtrl::Initialize(void)
{
BOOL bRet = FALSE;
do
{
HRESULT hr = S_OK;
_ASSERT(NULL == m_pEnumerator);
if (FAILED(hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&m_pEnumerator))) { break; }
_ASSERT(NULL != m_pEnumerator);
_ASSERT(NULL == m_pDevice);
if (FAILED(hr = m_pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_pDevice))) { break; }
_ASSERT(NULL != m_pDevice);
_ASSERT(NULL == m_pVolume);
if (FAILED(hr = m_pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&m_pVolume))) { break; }
_ASSERT(NULL != m_pVolume);
// Completed
bRet = TRUE;
} while (0);
return bRet;
}
void CVolumeCtrl::Uninitialize(void)
{
do
{
if (NULL != m_pVolume) { Notify(FALSE); m_pVolume->Release(); m_pVolume = NULL; }
if (NULL != m_pDevice) { m_pDevice->Release(); m_pDevice = NULL; }
if (NULL != m_pEnumerator) { m_pEnumerator->Release(); m_pEnumerator = NULL; }
// Completed
} while (0);
}
// ,
void CALLBACK NotifyCallback(DWORD dwVolume, LPVOID lpContext)
{
// dwVolume : 。
// lpContext : , , HWND , NULL
}
//
CVolumeCtrl* pVolumeCtrl = new CVolumeCtrl(NotifyCallback, NULL);
ASSERT(NULL != pVolumeCtrl);
if(pVolumeCtrl->VerifyValid()) //
{
pVolumeCtrl->Noitfy(TRUE); //
pVolumeCtrl->SetVolume/GetVolume(...); // /
pVolumeCtrl->SetMute/GetMute(...); // /
}