1. 程式人生 > >Vista、Win7、Win8系統對系統音量監聽以及靜音操作

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(&currentStep, &stepCount);

this->setMute(false);

for(UINT index = currentStep; index < stepCount; index++)

{

setVolumeUp();

}

}

}

//設定系統音量到最小
void VolumeListener::setMinVolume()
{

UINT currentStep, stepCount;

if(endpointVolume)

{

endpointVolume->GetVolumeStepInfo(&currentStep, &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(&currentStep, &stepCount);

currentVolume = (UINT)((currentStep*1.0 / stepCount)*100);

}

return currentVolume;

}