如何控制电脑(主机)的音量(注意不是程序的音量)?能支持 win7 和 win10

0

C语言怎么样控制主机的音量?不是程序的音量。代码最好能支持 win7 和 win10。网上关于这个的不太好找,找到了也看不懂,注释很少。

ava
huidong

2020-1-18

1

一般是通过 com 来设置系统主音量。如果你想读懂这部分代码,建议你先熟悉下 com 相关操作。

以下代码实现了读取、设置系统主音量,同时支持静音、取消静音。main 里面有简单的测试代码,可以直接编译运行查看效果。

// 获取、设置系统主音量
// 编译环境:Win10,VC2019
//
#include <mmdeviceapi.h>
#include <audioclient.h>
#include <endpointvolume.h>
#include <stdio.h>
#include <conio.h>


// 获取系统主音量 (范围:0~100)
int GetVolume()
{
	HRESULT hr;
	IMMDeviceEnumerator* pDeviceEnumerator = 0;
	IMMDevice* pDevice = 0;
	IAudioEndpointVolume* pAudioEndpointVolume = 0;
	IAudioClient* pAudioClient = 0;

	try
	{
		// 初始化接口
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pDeviceEnumerator);
		if (FAILED(hr)) throw "CoCreateInstance(MMDeviceEnumerator)";
		hr = pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDevice);
		if (FAILED(hr)) throw "GetDefaultAudioEndpoint";
		hr = pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pAudioEndpointVolume);
		if (FAILED(hr)) throw "Activate(IAudioEndpointVolume)";
		hr = pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient);
		if (FAILED(hr)) throw "Activate(IAudioClient)";

		// 获取系统主音量
		float fVolume;
		hr = pAudioEndpointVolume->GetMasterVolumeLevelScalar(&fVolume);
		if (FAILED(hr)) throw "GetMasterVolumeLevelScalar";

		// 释放接口
		pAudioClient->Release();
		pAudioEndpointVolume->Release();
		pDevice->Release();
		pDeviceEnumerator->Release();

		// 计算音量并返回
		int intVolume = int(fVolume * 100);
		if (intVolume > 100)    intVolume = 100;
		return intVolume;
	}
	catch (...)		// 捕获异常
	{
		if (pAudioClient) pAudioClient->Release();
		if (pAudioEndpointVolume) pAudioEndpointVolume->Release();
		if (pDevice) pDevice->Release();
		if (pDeviceEnumerator) pDeviceEnumerator->Release();
		throw;
	}
}


// 设置系统主音量 (范围:0~100)
void SetVolume(int level)
{
	HRESULT hr;
	IMMDeviceEnumerator* pDeviceEnumerator = 0;
	IMMDevice* pDevice = 0;
	IAudioEndpointVolume* pAudioEndpointVolume = 0;
	IAudioClient* pAudioClient = 0;

	try
	{
		// 初始化接口
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pDeviceEnumerator);
		if (FAILED(hr)) throw "CoCreateInstance(MMDeviceEnumerator)";
		hr = pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDevice);
		if (FAILED(hr)) throw "GetDefaultAudioEndpoint";
		hr = pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pAudioEndpointVolume);
		if (FAILED(hr)) throw "Active(IAudioEndpointVolume)";
		hr = pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient);
		if (FAILED(hr)) throw "Active(IAudioClient)";

		// 调整音量到有效范围
		if (level < 0) level = 0;
		if (level > 100) level = 100;

		// 设置系统主音量
		float fVolume;
		fVolume = level / 100.0f;
		hr = pAudioEndpointVolume->SetMasterVolumeLevelScalar(fVolume, &GUID_NULL);
		if (FAILED(hr)) throw "SetMasterVolumeLevelScalar";

		// 释放接口
		pAudioClient->Release();
		pAudioEndpointVolume->Release();
		pDevice->Release();
		pDeviceEnumerator->Release();
	}
	catch (...)		// 捕获异常
	{
		if (pAudioClient) pAudioClient->Release();
		if (pAudioEndpointVolume) pAudioEndpointVolume->Release();
		if (pDevice) pDevice->Release();
		if (pDeviceEnumerator) pDeviceEnumerator->Release();
		throw;
	}
}


// 设置静音/恢复静音
void SetMute(bool mute)
{
	HRESULT hr;
	IMMDeviceEnumerator* pDeviceEnumerator = 0;
	IMMDevice* pDevice = 0;
	IAudioEndpointVolume* pAudioEndpointVolume = 0;
	IAudioClient* pAudioClient = 0;

	try
	{
		// 初始化接口
		hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pDeviceEnumerator);
		if (FAILED(hr)) throw "CoCreateInstance(MMDeviceEnumerator)";
		hr = pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDevice);
		if (FAILED(hr)) throw "GetDefaultAudioEndpoint";
		hr = pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pAudioEndpointVolume);
		if (FAILED(hr)) throw "Active(IAudioEndpointVolume)";
		hr = pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient);
		if (FAILED(hr)) throw "Active(IAudioClient)";

		// 设置静音/取消静音
		hr = pAudioEndpointVolume->SetMute(mute, NULL);
		if (FAILED(hr)) throw "SetMute";

		// 释放接口
		pAudioClient->Release();
		pAudioEndpointVolume->Release();
		pDevice->Release();
		pDeviceEnumerator->Release();
	}
	catch (...)		// 捕获异常
	{
		if (pAudioClient) pAudioClient->Release();
		if (pAudioEndpointVolume) pAudioEndpointVolume->Release();
		if (pDevice) pDevice->Release();
		if (pDeviceEnumerator) pDeviceEnumerator->Release();
		throw;
	}
}


// 主函数
int main()
{
	// 初始化 com
	::CoInitialize(NULL);

	// 获取系统主音量
	printf("当前系统主音量 %d\n", GetVolume());

	// 设置系统主音量
	printf("按任意键将系统主音量设置为 50\n");
	_getch();
	SetVolume(50);

	// 设置静音
	printf("按任意键静音\n");
	_getch();
	SetMute(true);

	// 取消静音
	printf("按任意键取消静音\n");
	_getch();
	SetMute(false);

	// 释放 com
	::CoUninitialize();
}
ava
慢羊羊

2020-1-19

技术讨论社区