设为首页 收藏本站
查看: 798|回复: 0

Win7系统下C++实现客户端程序单独静音功能

[复制链接]

尚未签到

发表于 2015-5-15 10:51:06 | 显示全部楼层 |阅读模式
  本文主要是作为学习笔记而编写的,同时也希望能帮助需要的人!!
  实现这个功能是为了解决公司浏览器中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文件中的代码:


DSC0000.gif DSC0001.gif 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           REFIID  riid,
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     REFIID  riid,
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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-67149-1-1.html 上篇帖子: 使用移动硬盘快速安装win7(附BIOS设置) 下篇帖子: win7 下设置java环境变量
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表