天天看點

VC++打開或關閉目标程序的聲音(附源碼)

VC++常用功能開發彙總(專欄文章清單,歡迎訂閱,持續更新...)

VC++打開或關閉目标程式的聲音(附源碼)

https://blog.csdn.net/chenlycly/article/details/124272585C++軟體異常排查從入門到精通系列教程(專欄文章清單,歡迎訂閱,持續更新...)

VC++打開或關閉目标程式的聲音(附源碼)

https://blog.csdn.net/chenlycly/article/details/125529931        本文講述如何将某個程序的聲音打開或關閉掉,這個功能在某些場合下可能會用到,在此給大家做個分享。

1、在系統設定頁面中将程序的揚聲器打開或關閉

        以Win10系統為例,在系統桌面的右下角托盤圖示區域中找到系統音量圖示,右鍵點選該圖示,彈出如下的右鍵菜單:

VC++打開或關閉目标程式的聲音(附源碼)

點選“打開音量合成器”菜單項,打開使用揚聲器的程序清單頁面,如下所示:

VC++打開或關閉目标程式的聲音(附源碼)

以操作企業微信程序為例,點選下面的聲音圖示,即可将企業微信程序的聲音關閉或打開。如果将企業微信程序的聲音關閉,則聽不到企業微信程序的所有聲音。

注意,此處是關閉單個程序的聲音,不是關閉系統的聲音(将揚聲器的音量設定為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;
}
           

繼續閱讀