Vista、Win7、Win8系統對系統音量監聽以及靜音操作
windows自從vista後有了一套新的關於操作底層音訊的API即Core Audio APIS.通過對這個機制的研究,自己簡單寫個關於對Windows系統音量的控制,這裡包括如何監聽系統音量變化、改變系統的音量以及如何設定與解除靜音。
具體的原始碼如下:
/*******************匯入的標頭檔案*********************/
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <Tchar.h>
#include <functiondiscoverykeys.h>
#include <strsafe.h>
/********需要實現監聽系統音量變化介面IAudioEndpointVolumeCallback**********/
///
///實現對系統音量的監聽必須重現實現音量回調介面IAudioEndpointVolumeCallback
///主要實現介面IAudioEndpointVolumeCallback監聽系統音量的函式是OnNotify
///
class CVolumeNotification : public IAudioEndpointVolumeCallback
{
LONG m_RefCount;
~CVolumeNotification(void) {};
public:
CVolumeNotification() : m_RefCount(1)
{
}
//實現IAudioEndpointVolumeCallback介面的AddRef的函式
STDMETHODIMP_(ULONG)AddRef() {
return InterlockedIncrement(&m_RefCount);
}
//實現IAudioEndpointVolumeCallback介面的Release函式
STDMETHODIMP_(ULONG)Release()
{
LONG ref = InterlockedDecrement(&m_RefCount);
if (ref == 0)
delete this;
return ref;
}
//實現IAudioEndpointVolumeCallback介面的QueryInterface函式
STDMETHODIMP QueryInterface(REFIID IID, void **ReturnValue)
{
if (IID == IID_IUnknown || IID== __uuidof(IAudioEndpointVolumeCallback))
{
*ReturnValue = static_cast<IUnknown*>(this);
AddRef();
return S_OK;
}
*ReturnValue = NULL;
return E_NOINTERFACE;
}
///實現IAudioEndpointVolumeCallback介面的通知函式OnNotify
///OnNotify函式不斷監聽系統音量的變化
STDMETHODIMP OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA NotificationData)
{
//NotificationData->fMasterVolume
UINT volume = (UINT)((NotificationData->fMasterVolume)*100);
printf_s("volume: %d \n", volume); //列印不斷變化的系統的音量
return S_OK;
}
};
/*******************類VolumeListener實現對系統音量的控制*********************/
class VolumeListener
{
public:
static VolumeListener* getInstance();
//初始化工作
bool initVolumeListener();
//清理工作
void clearVolumeListener();
//註冊對系統音量的監聽
bool RegisterEndpointNotification();
//設定系統音量到最大
void setMaxVolume();
//設定系統音量到最小
void setMinVolume();
//調大音量
void setVolumeUp();
//調小音量
void setVolumeDown();
//設定靜音 引數isMute為true表示靜音 false解除靜音
void setMute(bool isMute);
//獲取當前系統音量
UINT getCurrentVloume();
protected:
VolumeListener();
private:
//該類實現單例模式
static VolumeListener* listener;
//控制系統音量和靜音的介面IAudioEndpointVolume
IAudioEndpointVolume *endpointVolume;
//監聽系統音量變化的回撥類變數
CVolumeNotification *volumeNotification;
};
//靜態成員
VolumeListener* VolumeListener::listener = NULL;
//單例模式
VolumeListener* VolumeListener::getInstance()
{
if(listener == NULL)
{
listener = new VolumeListener();
}
return listener;
}
//構造器
VolumeListener::VolumeListener():endpointVolume(NULL), volumeNotification(NULL)
{
}
//初始化工作
bool VolumeListener::initVolumeListener()
{
CoInitialize(NULL);
HRESULT hr;
IMMDevice *defaultDevice = NULL;
IMMDeviceEnumerator *deviceEnumerator = NULL;
//Instantiate an endpoint volume object.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
if(hr != S_OK)
{
printf_s("Instantiate an endpoint volume object error\n");
return false;
}
//eRender 輸出音訊裝置(放聲) eCapture輸入音訊裝置(錄聲)
hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
if(hr != S_OK)
{
printf_s("GetDefaultAudioEndpoint error\n");
return false;
}
//CVolumeNotification *volumeNotification = new CVolumeNotification();
hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
if(hr != S_OK)
{
printf_s("get IAudioEndpointVolume error\n");
return false;
}
return true;
}
//清理工作
void VolumeListener::clearVolumeListener()
{
if(endpointVolume)
{
if(volumeNotification){
endpointVolume->UnregisterControlChangeNotify(volumeNotification);
volumeNotification->Release();
}
endpointVolume->Release();
}
CoUninitialize();
if(listener)
delete listener;
listener = NULL;
}
//註冊對系統音量的監聽
bool VolumeListener::RegisterEndpointNotification()
{
HRESULT hr;
if(endpointVolume)
{
volumeNotification = new CVolumeNotification();
hr = endpointVolume->RegisterControlChangeNotify(volumeNotification);
if(hr != S_OK)
{
printf_s("RegisterEndpointNotification error\n");
return false;
}
}
return true;
}
//設定系統音量到最大
void VolumeListener::setMaxVolume()
{
UINT currentStep, stepCount;
if(endpointVolume)
{
endpointVolume->GetVolumeStepInfo(¤tStep, &stepCount);
this->setMute(false);
for(UINT index = currentStep; index < stepCount; index++)
{
setVolumeUp();
}
}
}
//設定系統音量到最小
void VolumeListener::setMinVolume()
{
UINT currentStep, stepCount;
if(endpointVolume)
{
endpointVolume->GetVolumeStepInfo(¤tStep, &stepCount);
endpointVolume->SetMute(FALSE, NULL);
for(UINT index = currentStep; index > 0; index--)
{
setVolumeDown();
}
}
}
//調大音量
void VolumeListener::setVolumeUp()
{
if(endpointVolume)
{
endpointVolume->VolumeStepUp(NULL);
}
}
//調小音量
void VolumeListener::setVolumeDown()
{
if(endpointVolume)
{
endpointVolume->VolumeStepDown(NULL);
}
}
//設定靜音 引數isMute為true表示靜音 false解除靜音
void VolumeListener::setMute(bool isMute)
{
if(endpointVolume)
{
if(isMute)
endpointVolume->SetMute(TRUE, NULL); //靜音
else
endpointVolume->SetMute(FALSE, NULL); //解除靜音
}
}
//獲取當前系統音量
UINT VolumeListener::getCurrentVloume()
{
UINT currentStep, stepCount, currentVolume;
currentVolume = 0;
if(endpointVolume)
{
endpointVolume->GetVolumeStepInfo(¤tStep, &stepCount);
currentVolume = (UINT)((currentStep*1.0 / stepCount)*100);
}
return currentVolume;
}