Win7系统下C++实现客户端程序单独静音功能
本文主要是作为学习笔记而编写的,同时也希望能帮助需要的人!!实现这个功能是为了解决公司浏览器中Win7下不能静音的BUG。搜索了很多网页,都没有找到这方面的实现!但我心里很清楚,一定是有方法解决这个问题的。所以,在心情还算良好的情况下,静下心来查看MSDN的英文介绍,果然让我找到了这个!Core Audio API——Win7系统以后才有的。而该库的相关中文介绍,可以参考以下文章:
1. http://caicaioffice.blog.163.com/blog/static/1417910220094154269427/
2.http://caicaioffice.blog.163.com/blog/static/14179102200941542637752/
通过看上面的文章,虽然能够实现设备音量的控制,但貌似还是木有针对一个程序来控制其静音,所以,只能靠MSDN帮忙了!
要实现客户端程序真正的单独静音,我们必须考虑以下两点:
1. 从客户端程序设置单独静音
提到客户端程序音量控制,首先就需要获取程序IAudioSessionManager会话(Session)。然后再通过调用会话对应的ISimpleAudioVolume中的SetMute函数,就可以设置客户端程序是否静音了。整个代码都先给出:
在TxMuted.h文件中的代码:
View Code
1 #ifndef TXMUTED_H
2 #define TXMUTED_H
3
4 #include "Mmdeviceapi.h"
5 #include "Audiopolicy.h"
6
7 // 初始化静音
8 IMMDeviceEnumerator* TxInitMuted();
9
10 // 释放
11 bool TxUnMuted();
12
13 // 设置静音
14 bool TxSetMuted(bool bMuted);
15
16 // 是否为Win7系统
17 BOOL IsWindows7();
18
19 #endif
在TxMuted.cpp中的代码
View Code
1 #include "StdAfx.h"
2 #include "TxMuted.h"
3 #include "MutedSessionEvent.h"
4
5 extern volatile bool g_bMuted;
6
7 static IMMDeviceEnumerator* m_pEnumerator = NULL;
8 static IMMDevice* m_pDeviceOut = NULL;
9 static IAudioSessionManager* m_AudioSessionManager = NULL;
10 static IAudioSessionControl* m_AudioSessionControl = NULL;
11 static CMutedSessionEvents * m_pMutedSessionEvents = NULL;
12
13 BOOL IsWindows7()
14 {
15 OSVERSIONINFO osinfo;
16 osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
17
18 if (!GetVersionEx(&osinfo))
19 return FALSE;
20
21 DWORD dwPlatformId = osinfo.dwPlatformId;
22 DWORD dwMinorVersion = osinfo.dwMinorVersion;
23 DWORD dwMajorVersion = osinfo.dwMajorVersion;
24 DWORD dwBuildNumber= osinfo.dwBuildNumber & 0xFFFF; // Win 95 needs this
25
26 if (dwPlatformId == 2)
27 {
28 if ((dwMajorVersion == 6) && (dwMinorVersion == 1))
29 {
30 return TRUE;
31 }
32 }
33 return FALSE;
34 }
35
36 IMMDeviceEnumerator*TxInitMuted()
37 {
38 CoInitializeEx( NULL , COINIT_MULTITHREADED );
39
40 HRESULT hr;
41
42 //实例化 MMDeviceEnumerator 枚举器
43 hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&m_pEnumerator);
44 if(FAILED(hr))
45 {
46 return NULL;
47 }
48
49 // 默认设备的IMMDevice接口
50 hr = m_pEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &m_pDeviceOut);
51 if (FAILED(hr)) return false;
52
53 // 得到音频会话接口IAudioSessionManager
54 hr = m_pDeviceOut->Activate(__uuidof(m_AudioSessionManager), CLSCTX_ALL, NULL, (void**)&m_AudioSessionManager);
55 if (FAILED(hr)) return false;
56
57 // 设置会话(Session)参数
58 hr = m_AudioSessionManager->GetAudioSessionControl(NULL,0,&m_AudioSessionControl);
59 if (FAILED(hr)) return false;
60
61 // 设置声音改变参数通知
62 m_pMutedSessionEvents = new CMutedSessionEvents(m_AudioSessionManager);
63 hr = m_AudioSessionControl->RegisterAudioSessionNotification(m_pMutedSessionEvents);
64 if (FAILED(hr)) return false;
65
66 return m_pEnumerator;
67 }
68
69 bool TxUnMuted()
70 {
71 // ---- 解注册声音改变参数通知
72 if (m_AudioSessionControl!=NULL&&m_pMutedSessionEvents!=NULL)
73 {
74 m_AudioSessionControl->UnregisterAudioSessionNotification(m_pMutedSessionEvents);
75 }
76
77 // ---- 释放内存空间
78 if (m_AudioSessionControl != NULL)
79 {
80 m_AudioSessionControl->Release();
81 m_AudioSessionControl = NULL;
82 }
83 if (m_pMutedSessionEvents != NULL)
84 {
85 m_pMutedSessionEvents->Release();
86 m_pMutedSessionEvents = NULL;
87 }
88 if (m_pDeviceOut != NULL)
89 {
90 m_pDeviceOut->Release();
91 m_pDeviceOut = NULL;
92 }
93 if(m_AudioSessionManager != NULL)
94 {
95 m_AudioSessionManager->Release();
96 m_AudioSessionManager = NULL;
97 }
98 if (m_pEnumerator != NULL)
99 {
100 m_pEnumerator->Release();
101 m_pEnumerator = NULL;
102 }
103
104 CoUninitialize();
105
106 return true;
107 }
108
109 bool TxSetMuted(bool bMuted)
110 {
111 HRESULT hr = S_FALSE;
112
113 // 获得音量、静音控制接口
114 ISimpleAudioVolume *pAudioVolume = NULL;
115 hr = m_AudioSessionManager->GetSimpleAudioVolume(NULL,0,&pAudioVolume);
116 if (FAILED(hr)) return false;
117
118 if(SUCCEEDED(hr))
119 {
120 pAudioVolume->SetMute(bMuted, &GUID_NULL);
121
122 // 更改全局静音状态
123 g_bMuted = bMuted;
124 }
125
126 if (pAudioVolume != NULL)
127 {
128 pAudioVolume->Release();
129 pAudioVolume = NULL;
130 }
131 return true;
132 }
2.不允许用户从系统合成器中改变程序静音状态
对于这个功能,就得涉及到IAudioSessionEvents接口啦!主要是参考MSDN上的例子做的。废话不多说,直接贴代码了!
在MutedSessionEvents.h文件中的代码
View Code
1 #ifndef MUTEDSESSIONEVENT_H
2 #define MUTEDSESSIONEVENT_H
3
4 #include
5 #include
6
7 class CMutedSessionEvents : public IAudioSessionEvents
8 {
9 public:
10 CMutedSessionEvents(IAudioSessionManager* pAudioSessionManager );
11 ~CMutedSessionEvents(){}
12
13 // IUnknown methods -- AddRef, Release, and QueryInterface
14
15 ULONG STDMETHODCALLTYPE AddRef(){return InterlockedIncrement(&_cRef);}
16
17 ULONG STDMETHODCALLTYPE Release();
18
19 HRESULT STDMETHODCALLTYPE QueryInterface(
20 REFIIDriid,
21 VOID**ppvInterface);
22
23 // Notification methods for audio session events
24
25 HRESULT STDMETHODCALLTYPE OnDisplayNameChanged(
26 LPCWSTR NewDisplayName,
27 LPCGUID EventContext)
28 {
29 return S_OK;
30 }
31
32 HRESULT STDMETHODCALLTYPE OnIconPathChanged(
33 LPCWSTR NewIconPath,
34 LPCGUID EventContext)
35 {
36 return S_OK;
37 }
38
39 HRESULT STDMETHODCALLTYPE OnSimpleVolumeChanged(
40 float NewVolume,
41 BOOL NewMute,
42 LPCGUID EventContext);
43
44 HRESULT STDMETHODCALLTYPE OnChannelVolumeChanged(
45 DWORD ChannelCount,
46 float NewChannelVolumeArray[],
47 DWORD ChangedChannel,
48 LPCGUID EventContext)
49 {
50 return S_OK;
51 }
52
53 HRESULT STDMETHODCALLTYPE OnGroupingParamChanged(
54 LPCGUID NewGroupingParam,
55 LPCGUID EventContext)
56 {
57 return S_OK;
58 }
59
60 HRESULT STDMETHODCALLTYPE OnStateChanged(
61 AudioSessionState NewState)
62 {
63 return S_OK;
64 }
65
66 HRESULT STDMETHODCALLTYPE OnSessionDisconnected(
67 AudioSessionDisconnectReason DisconnectReason)
68 {
69 return S_OK;
70 }
71
72 bool TxSetMuted(bool bMuted);
73
74 private:
75 LONG _cRef;
76
77 private:
78 IAudioSessionManager* m_AudioSessionManager;
79 };
80
81 #endif
在MutedSessionEvents.cpp文件中的代码
View Code
1 #include "stdafx.h"
2 #include "MutedSessionEvent.h"
3
4 extern volatile bool g_bMuted;
5
6 CMutedSessionEvents::CMutedSessionEvents(IAudioSessionManager* pAudioSessionManager)
7 {
8 m_AudioSessionManager = pAudioSessionManager;
9 _cRef = 1;
10 }
11
12 ULONG STDMETHODCALLTYPE CMutedSessionEvents::Release()
13 {
14 ULONG ulRef = InterlockedDecrement(&_cRef);
15 if (0 == ulRef)
16 {
17 delete this;
18 }
19 return ulRef;
20 }
21
22 HRESULT STDMETHODCALLTYPE CMutedSessionEvents::QueryInterface(
23 REFIIDriid,
24 VOID**ppvInterface)
25 {
26 if (IID_IUnknown == riid)
27 {
28 AddRef();
29 *ppvInterface = (IUnknown*)this;
30 }
31 else if (__uuidof(IAudioSessionEvents) == riid)
32 {
33 AddRef();
34 *ppvInterface = (IAudioSessionEvents*)this;
35 }
36 else
37 {
38 *ppvInterface = NULL;
39 return E_NOINTERFACE;
40 }
41 return S_OK;
42 }
43
44 HRESULT STDMETHODCALLTYPE CMutedSessionEvents::OnSimpleVolumeChanged(
45 float NewVolume,
46 BOOL NewMute,
47 LPCGUID EventContext)
48 {
49 // 防止其它程序对静音篡改
50 if ((BOOL)g_bMuted != NewMute)
51 {
52 TxSetMuted(g_bMuted);
53 }
54
55 return S_OK;
56 }
57
58 bool CMutedSessionEvents::TxSetMuted(bool bMuted)
59 {
60 HRESULT hr = S_FALSE;
61
62 // 获得音量、静音控制接口
63 ISimpleAudioVolume *pAudioVolume = NULL;
64 hr = m_AudioSessionManager->GetSimpleAudioVolume(NULL,0,&pAudioVolume);
65 if (FAILED(hr)) return false;
66
67 if(SUCCEEDED(hr))
68 {
69 pAudioVolume->SetMute(bMuted, &GUID_NULL);
70
71 // 更改全局静音状态
72 g_bMuted = bMuted;
73 }
74
75 if (pAudioVolume != NULL)
76 {
77 pAudioVolume->Release();
78 pAudioVolume = NULL;
79 }
80 return true;
81 }
好啦!以上代码为本人亲测后的代码,可以使用的!如果有什么问题,欢迎来指出~~ 请勿拍砖!!
页:
[1]