VC++常用功能開發彙總(專欄文章清單,歡迎訂閱,持續更新...)
https://blog.csdn.net/chenlycly/article/details/124272585C++軟體異常排查從入門到精通系列教程(專欄文章清單,歡迎訂閱,持續更新...)
https://blog.csdn.net/chenlycly/article/details/125529931 本文講述如何将某個程序的聲音打開或關閉掉,這個功能在某些場合下可能會用到,在此給大家做個分享。
1、在系統設定頁面中将程序的揚聲器打開或關閉
以Win10系統為例,在系統桌面的右下角托盤圖示區域中找到系統音量圖示,右鍵點選該圖示,彈出如下的右鍵菜單:
點選“打開音量合成器”菜單項,打開使用揚聲器的程序清單頁面,如下所示:
以操作企業微信程序為例,點選下面的聲音圖示,即可将企業微信程序的聲音關閉或打開。如果将企業微信程序的聲音關閉,則聽不到企業微信程序的所有聲音。
注意,此處是關閉單個程序的聲音,不是關閉系統的聲音(将揚聲器的音量設定為0)!
2、通過代碼實作程序揚聲器打開或關閉
Windows系統支援以COM元件的方式通路系統中的音視訊裝置,我們可以先擷取所有的音頻播放裝置,然後周遊裝置下對應的程序清單,然後通過程序id去周遊程序清單,找到目标程序後,對程序的聲音進行關閉和打開操作。
以開關本程序的聲音為例,完整的實作代碼如下:
BOOL SetCurrentSpeakerMute(BOOL bQuiet)
{
HRESULT hr = S_OK;
IMMDeviceCollection *pMultiDevice = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionEnumerator *pSessionEnum = NULL;
IAudioSessionManager2 *pASManager = NULL;
IMMDeviceEnumerator *pEnumerator = NULL;
const IID IID_ISimpleAudioVolume = __uuidof(ISimpleAudioVolume);
const IID IID_IAudioSessionControl2 = __uuidof(IAudioSessionControl2);
CoInitialize(NULL);
// Get enumerator for audio endpoint devices.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
NULL, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator),
(void**)&pEnumerator);
if (FAILED(hr))
return FALSE;
// 1、擷取音頻播放裝置
hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pMultiDevice);
if (FAILED(hr))
return FALSE;
UINT deviceCount = 0;
hr = pMultiDevice->GetCount(&deviceCount);
if (FAILED(hr))
return FALSE;
// 2、周遊音頻播放裝置
for (UINT ii = 0; ii < deviceCount; ii++)
{
pDevice = NULL;
hr = pMultiDevice->Item(ii, &pDevice);
if (FAILED(hr))
return FALSE;
hr = pDevice->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL, NULL, (void**)&pASManager);
if (FAILED(hr))
return FALSE;
hr = pASManager->GetSessionEnumerator(&pSessionEnum);
if (FAILED(hr))
return FALSE;
int nCount;
hr = pSessionEnum->GetCount(&nCount);
for (int i = 0; i < nCount; i++)
{
IAudioSessionControl *pSessionCtrl;
hr = pSessionEnum->GetSession(i, &pSessionCtrl);
if (FAILED(hr))
continue;
// 3、擷取音頻播放控制對象
IAudioSessionControl2 *pSessionCtrl2;
hr = pSessionCtrl->QueryInterface(IID_IAudioSessionControl2, (void **)&pSessionCtrl2);
if (FAILED(hr))
continue;
ULONG pid;
hr = pSessionCtrl2->GetProcessId(&pid);
if (FAILED(hr))
continue;
ISimpleAudioVolume *pSimplevol;
hr = pSessionCtrl2->QueryInterface(IID_ISimpleAudioVolume, (void **)&pSimplevol);
if (FAILED(hr))
continue;
// 4、對比擷取音頻播放控制對象的程序id,判斷是不是本程序的
if (pid == GetCurrentProcessId())
{
// 将目标程序靜音
pSimplevol->SetMute(bQuiet, &GUID_NULL);
}
if (pSimplevol != NULL)
{
pSimplevol->Release();
}
if (pSessionCtrl2 != NULL)
{
pSessionCtrl2->Release();
}
if (pSessionCtrl != NULL)
{
pSessionCtrl->Release();
}
}
}
if (pSessionEnum != NULL) pSessionEnum->Release();
if (pASManager != NULL) pASManager->Release();
if (pDevice != NULL) pDevice->Release();
if (pMultiDevice != NULL) pMultiDevice->Release();
if (pEnumerator != NULL) pEnumerator->Release();
CoUninitialize();
return TRUE;
}
上面是調用IAudioMute::SetMute接口将聲音打開或者關閉。如果要擷取目前程序的靜音狀态,則調用IAudioMute::GetMute接口,對應的代碼如下:
BOOL GetCurrentSpeakerMuteStatus()
{
BOOL bQuiet = FALSE;
HRESULT hr = S_OK;
IMMDeviceCollection *pMultiDevice = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionEnumerator *pSessionEnum = NULL;
IAudioSessionManager2 *pASManager = NULL;
IMMDeviceEnumerator *pEnumerator = NULL;
const IID IID_ISimpleAudioVolume = __uuidof(ISimpleAudioVolume);
const IID IID_IAudioSessionControl2 = __uuidof(IAudioSessionControl2);
CoInitialize(NULL);
// Get enumerator for audio endpoint devices.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
NULL, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator),
(void**)&pEnumerator);
if (FAILED(hr))
return FALSE;
hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pMultiDevice);
if (FAILED(hr))
return FALSE;
UINT deviceCount = 0;
hr = pMultiDevice->GetCount(&deviceCount);
if (FAILED(hr))
return FALSE;
for (UINT ii = 0; ii < deviceCount; ii++)
{
pDevice = NULL;
hr = pMultiDevice->Item(ii, &pDevice);
if (FAILED(hr))
return FALSE;
hr = pDevice->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL, NULL, (void**)&pASManager);
if (FAILED(hr))
return FALSE;
hr = pASManager->GetSessionEnumerator(&pSessionEnum);
if (FAILED(hr))
return FALSE;
int nCount;
hr = pSessionEnum->GetCount(&nCount);
for (int i = 0; i < nCount; i++)
{
IAudioSessionControl *pSessionCtrl;
hr = pSessionEnum->GetSession(i, &pSessionCtrl);
if (FAILED(hr))
continue;
IAudioSessionControl2 *pSessionCtrl2;
hr = pSessionCtrl->QueryInterface(IID_IAudioSessionControl2, (void **)&pSessionCtrl2);
if (FAILED(hr))
continue;
ULONG pid;
hr = pSessionCtrl2->GetProcessId(&pid);
if (FAILED(hr))
continue;
ISimpleAudioVolume *pSimplevol;
hr = pSessionCtrl2->QueryInterface(IID_ISimpleAudioVolume, (void **)&pSimplevol);
if (FAILED(hr))
continue;
// 擷取靜音狀态
if (pid == GetCurrentProcessId())
{
pSimplevol->GetMute(&bQuiet);
}
}
}
pEnumerator->Release();
return bQuiet;
}