然后添加以下修改以适合 QT 标头(将其命名为:PolicyConfig.h)
// ----------------------------------------------------------------------------
// PolicyConfig.h
// Undocumented COM-interface IPolicyConfig.
// Use for set default audio render endpoint
// @author EreTIk
// ----------------------------------------------------------------------------
#pragma once
#include "winnt.h"
//#include <QAxAggregated>
class DECLSPEC_UUID("f8679f50-850a-41cf-9c72-430f290290c8") IPolicyConfig;
class DECLSPEC_UUID("870af99c-171d-4f9e-af0d-e63df40c2bc9") CPolicyConfigClient;
// ----------------------------------------------------------------------------
// class CPolicyConfigClient
// {870af99c-171d-4f9e-af0d-e63df40c2bc9}
//
// interface IPolicyConfig
// {f8679f50-850a-41cf-9c72-430f290290c8}
//
// Query interface:
// CComPtr<IPolicyConfig> PolicyConfig;
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigClient));
//
// @compatible: Windows 7 and Later
// ----------------------------------------------------------------------------
class IPolicyConfig : public IUnknown
{
public:
virtual HRESULT GetMixFormat(
PCWSTR,
WAVEFORMATEX **
);
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
PCWSTR,
INT,
WAVEFORMATEX **
);
virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat(
PCWSTR
);
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
PCWSTR,
WAVEFORMATEX *,
WAVEFORMATEX *
);
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
PCWSTR,
INT,
PINT64,
PINT64
);
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
PCWSTR,
PINT64
);
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
PCWSTR,
struct DeviceShareMode *
);
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
PCWSTR,
struct DeviceShareMode *
);
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
__in PCWSTR wszDeviceId,
__in ERole eRole
);
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
PCWSTR,
INT
);
};
class DECLSPEC_UUID("568b9108-44bf-40b4-9006-86afe5b5a620") IPolicyConfigVista;
class DECLSPEC_UUID("294935CE-F637-4E7C-A41B-AB255460B862") CPolicyConfigVistaClient;
// ----------------------------------------------------------------------------
// class CPolicyConfigVistaClient
// {294935CE-F637-4E7C-A41B-AB255460B862}
//
// interface IPolicyConfigVista
// {568b9108-44bf-40b4-9006-86afe5b5a620}
//
// Query interface:
// CComPtr<IPolicyConfigVista> PolicyConfig;
// PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigVistaClient));
//
// @compatible: Windows Vista and Later
// ----------------------------------------------------------------------------
class IPolicyConfigVista : public IUnknown
{
public:
virtual HRESULT GetMixFormat(
PCWSTR,
WAVEFORMATEX **
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat(
PCWSTR,
INT,
WAVEFORMATEX **
);
virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat(
PCWSTR,
WAVEFORMATEX *,
WAVEFORMATEX *
);
virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod(
PCWSTR,
INT,
PINT64,
PINT64
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod(
PCWSTR,
PINT64
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetShareMode(
PCWSTR,
struct DeviceShareMode *
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE SetShareMode(
PCWSTR,
struct DeviceShareMode *
); // not available on Windows 7, use method from IPolicyConfig
virtual HRESULT STDMETHODCALLTYPE GetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetPropertyValue(
PCWSTR,
const PROPERTYKEY &,
PROPVARIANT *
);
virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint(
__in PCWSTR wszDeviceId,
__in ERole eRole
);
virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility(
PCWSTR,
INT
); // not available on Windows 7, use method from IPolicyConfig
};
实现文件(命名为 DefaultOutput.cpp):
#include <stdio.h>
#include <wchar.h>
#include <tchar.h>
#include "windows.h"
#include "Mmdeviceapi.h"
#include "PolicyConfig.h"
#include "Propidl.h"
#include "Functiondiscoverykeys_devpkey.h"
#include "defaultoutput.h"
QHash<QString, QString> DefaultOutput::enumOutputDevices()
{
QHash<QString, QString> list;
try
{
HRESULT hr = CoInitialize( NULL );
if( FAILED( hr ) )
return list;
IMMDeviceEnumerator *pEnum = NULL;
// Create a multimedia device enumerator.
hr = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL, CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ), (void**)&pEnum );
if( FAILED( hr ) )
return list;
IMMDeviceCollection *pDevices;
// Enumerate the output devices.
hr = pEnum->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &pDevices );
if( FAILED( hr ) )
return list;
UINT count;
pDevices->GetCount(&count);
if( FAILED( hr ) )
return list;
for( UINT i = 0; i < count; i++ )
{
IMMDevice *pDevice;
hr = pDevices->Item( i, &pDevice );
if( SUCCEEDED( hr ) )
{
LPWSTR wstrID = NULL;
hr = pDevice->GetId( &wstrID );
if( SUCCEEDED( hr ) )
{
IPropertyStore* pStore;
hr = pDevice->OpenPropertyStore( STGM_READ, &pStore );
if( SUCCEEDED( hr ) )
{
PROPVARIANT friendlyName;
PropVariantInit( &friendlyName );
hr = pStore->GetValue( PKEY_Device_FriendlyName, &friendlyName );
if( SUCCEEDED( hr ) )
{
QString qid = QString::fromStdU16String( (char16_t*)wstrID );
QString qname = QString::fromStdU16String( (char16_t*)friendlyName.pwszVal );
list[qid] = qname;
PropVariantClear( &friendlyName );
}
pStore->Release();
}
}
pDevice->Release();
}
}
pDevices->Release();
pEnum->Release();
return list;
}
catch( ... )
{
return list;
}
}
bool DefaultOutput::changeOutputDevice( QString id )
{
try
{
IPolicyConfigVista* pPolicyConfig;
ERole reserved = eConsole;
HRESULT hr = CoCreateInstance( __uuidof( CPolicyConfigVistaClient ), NULL, CLSCTX_ALL, __uuidof( IPolicyConfigVista ), (LPVOID*)&pPolicyConfig );
if( SUCCEEDED( hr ) )
{
hr = pPolicyConfig->SetDefaultEndpoint( (PCWSTR)id.toStdU16String().data(), reserved );
pPolicyConfig->Release();
return SUCCEEDED( hr );
}
else
return false;
}
catch( ... )
{
return false;
}
}