mfc使用Slider控件控制系统的音量

mfc使用Slider控件控制系统的音量

文章转载自:http://blog.csdn.net/reggiekiller/article/details/5912875

===================================================================

 

之前想实现这个功能,找了很多资料,全都不给力,最后发现Microsoft给的那才是可以用的,总的来说就是使用mixer api来打开混音器设备、获得音频线路信息、然后设定属性。实现这个之后,就可以用在你写的程序比如播放器上面啦。

总共就下面几个函数:

通过这9个API,我们就可以来控制音频的输入和输出设备了,其实有关这几个函数的定义你可以在C:/Program Files/Microsoft Visual Studio/VC98/Include/mmsystem.h文件中找到。下面我简单介绍一下这几个函数,详细地介绍你可以参见msdn。

  mixerOpen和mixerClose函数用来打开和关闭混音器设备

  mixerGetNumDevs可以确定系统中有多少混音器设备

  mixerGetDevCaps函数可以确定混音器设备的能力

  mixerGetLineInfo可以检索指定音频线路的信息

  mixerGetLineControls用于检索一个或者多个与音频线路相关的控制的通用信息

  mixerGetControlDetails用于检索与某个音频线路相关的一个控制的属性

  mixerSetControlDetails用于设置制定控制的属性。

对话框工程(工程->设置->链接 添加winmm.lib,头文件包含mmsystem.h),添加一个slider控件,关联control变量m_volume

我把那个滑块设为了垂直样式,仿右下角那个小喇叭的风格:)

但是这样一来我发现一个问题,垂直样式默认刻度是上边小下边大,而我想实现的是下边为0刻度,上面为最大值,google一下无解决方案。

csdn就是智慧无穷,我被鄙视了。。。kemee童鞋说“..... 我是自己再做个运算的....比如0~100,不管什么数据要在控件上显示了,就和100先做个运算,再设置,这样0就显示100,100的时候就显示0了。。”,就是这么无须解释,我承认我脑袋很锈

给CSliderDlg添加成员变量:

MIXERCONTROLDETAILS_SIGNED volStruct;

MIXERCONTROLDETAILS mxcd;

MIXERLINECONTROLS mxlc;

MIXERLINE mxl;

MIXERCONTROL mxc;

HMIXER m_hmx;

在OnInitDialog中添加一下代码

  1. // TODO: Add extra initialization here
  2. unsigned long err;
  3. CString str;
  4. err = mixerOpen(&m_hmx,0,0,0,0);
  5. if(err)
  6. {
  7. MessageBox("ERROR:Can't open Mixer Device!");
  8. }
  9. //初始化MIXERLINE结构体
  10. ZeroMemory(&mxl,sizeof(mxl));
  11. mxl.cbStruct = sizeof(mxl);
  12. // 指出需要获取的通道,扬声器用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
  13. mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
  14. if(mixerGetLineInfo((HMIXEROBJ)m_hmx,&mxl,
  15. MIXER_GETLINEINFOF_COMPONENTTYPE))
  16. {
  17. MessageBox("Couldn't get the mixer line!");
  18. }
  19. // 取得控制器.
  20. ZeroMemory(&mxlc, sizeof(mxlc));
  21. mxlc.cbStruct = sizeof(mxlc);
  22. mxlc.dwLineID = mxl.dwLineID;
  23. mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
  24. mxlc.cControls =1;
  25. mxlc.cbmxctrl = sizeof(mxc);
  26. mxlc.pamxctrl = &mxc;
  27. ZeroMemory(&mxc, sizeof(mxc));
  28. mxc.cbStruct = sizeof(mxc);
  29. if(mixerGetLineControls((HMIXEROBJ)m_hmx,&mxlc,
  30. MIXER_GETLINECONTROLSF_ONEBYTYPE))
  31. {
  32. MessageBox("取得控制器失败!");
  33. }
  34. // 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.
  35. // 初始化MIXERCONTROLDETAILS结构体
  36. ZeroMemory(&mxcd, sizeof(mxcd));
  37. mxcd.cbStruct = sizeof(mxcd);
  38. mxcd.cbDetails = sizeof(volStruct);
  39. mxcd.dwControlID = mxc.dwControlID;
  40. mxcd.paDetails = &volStruct;
  41. mxcd.cChannels = 1;
  42. // 获得音量值
  43. if(mixerGetControlDetails((HMIXEROBJ)m_hmx, &mxcd,
  44. MIXER_GETCONTROLDETAILSF_VALUE))
  45. {
  46. MessageBox("无法获得音量");
  47. }
  48. //str.Format("%d %d %d",mxc.Bounds.dwMinimum,mxc.Bounds.dwMaximum,volStruct.lValue);
  49. //MessageBox(str);
  50. /*unsigned long mixerID;
  51. err = mixerGetID((struct HMIXEROBJ__ *)m_hmx, (unsigned int *)&mixerID, MIXER_OBJECTF_HMIXER);
  52. if (err)
  53. {
  54. MessageBox("ERROR: Can't get Mixer Device ID!");
  55. }
  56. else
  57. {
  58. str.Format("Mixer Device ID = %d/n", mixerID);
  59. MessageBox(str);
  60. }
  61. MIXERCAPS mixcaps;
  62. unsigned long iNumDevs, i;
  63. // 获取系统中混音器设备个数
  64. iNumDevs = mixerGetNumDevs();
  65. // 遍历所有的混音器并显示它们的ID和名称
  66. for (i = 0; i < iNumDevs; i++)
  67. {
  68. // 获取下一个混音器设备的信息
  69. if (!mixerGetDevCaps(i, &mixcaps, sizeof(MIXERCAPS)))
  70. {
  71. // 显示ID和名称
  72. str.Format("Device ID #%u: %s/r/n", i, mixcaps.szPname);
  73. MessageBox(str);
  74. }
  75. }*/
  76. m_volume.SetRange(mxc.Bounds.dwMinimum,mxc.Bounds.dwMaximum);
  77. m_volume.SetPos(mxc.Bounds.dwMaximum - volStruct.lValue);

然后在OnVScroll中(注意,是OnVScroll,不是OnHScroll,因为控件是垂直样式的!)

  1. void CSliderDlg::OnVScroll(UINT nSBCode,UINT nPos, CScrollBar* pScrollBar)
  2. {
  3. // TODO: Add your message handler code here and/or call default
  4. if((CWnd*)pScrollBar == (CWnd*)&m_volume)
  5. {
  6. int pos = mxc.Bounds.dwMaximum - m_volume.GetPos();
  7. CString str;
  8. str.Format("%d",pos);
  9. //MessageBox(str);
  10. volStruct.lValue = pos; //想要设置的值
  11. mixerSetControlDetails((HMIXEROBJ)m_hmx, &mxcd,
  12. MIXER_SETCONTROLDETAILSF_VALUE);
  13. }
  14. CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
  15. }

成功,运行试一下吧!

 

 

下面文章内容来自:http://dev.21tx.com/2005/11/17/14840_2.html

=================================================================

3、下面演示一下如何设置Volume设备的静音

  这里提供了两个函数,GetMute用来获取系统设置中是否对某个音频线路进行了静音操作,SetMute是用来对系统的某个音频线路进行静音操作。

BOOL CMixer::SetMute(DWORD dwSrcType, BOOL bValue)
{
 MIXERLINE mxl;
 if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
  return FALSE;

 MIXERCONTROL mxc;
 if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_MUTE))
  return FALSE;

 MIXERCONTROLDETAILS mxcd;
 MIXERCONTROLDETAILS_BOOLEAN mxcd_f;

 mxcd.cbStruct = sizeof(mxcd);
 mxcd.dwControlID = mxc.dwControlID;
 mxcd.cChannels = 1;
 mxcd.cMultipleItems = 0;
 mxcd.cbDetails = sizeof(mxcd_f);
 mxcd.paDetails = &mxcd_f;
 
 mxcd_f.fValue = bValue;

 if (! SetControlDetails(&mxcd, MIXER_OBJECTF_MIXER))
  return FALSE;

 return TRUE;
}

BOOL CMixer::GetMute(DWORD dwSrcType, BOOL* PBValue)
{
 MIXERLINE mxl;
 if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
  return FALSE;

 MIXERCONTROL mxc;
 if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT ))
  return FALSE;

 MIXERCONTROLDETAILS mxcd;
 MIXERCONTROLDETAILS_BOOLEAN mxcd_f;

 mxcd.cbStruct = sizeof(mxcd);
 mxcd.dwControlID = mxc.dwControlID;
 mxcd.cChannels = 1;
 mxcd.cMultipleItems = 0;
 mxcd.cbDetails = sizeof(mxcd_f);
 mxcd.paDetails = &mxcd_f;

 if (! GetControlDetails(&mxcd, MIXER_GETCONTROLDETAILSF_VALUE))
  return FALSE;

 *pbValue = mxcd_f.fValue;

 return TRUE;
}

  如果用这两个函数呢,下面我演示了如何设置和获取Volume音频线路的静音操作。

BOOL bValue = TRUE;
SetMute(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, bValue);
GetMute(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &bValue);

  4、下面看看当系统的设置改变时,mixer是如何通知我们的吧。

  还记得我前面讲过的,当我们调用mixeropen时可以传递一个窗口的句柄作为回调窗口,当系统的设置改变,比如音量改变,某个音频线路被静音时,mixer都会给我们的回调窗口发送消息的。

  一般只有两个消息,如下

afx_msg void OnMLChange(WPARAM wParam, LPARAM lParam);
afx_msg void OnMCChange(WPARAM wParam, LPARAM lParam);

ON_MESSAGE(MM_MIXM_LINE_CHANGE, OnMLChange)
ON_MESSAGE(MM_MIXM_CONTROL_CHANGE, OnMCChange)

  其中MM_MIXM_CONTROL_CHANGE 消息中,发送消息的两个参数代表的意思如下

wParam = (WPARAM) hMixer
lParam = (LPARAM) dwControlID

  在MM_MIXM_LINE_CHANGE 消息中,发送消息的参数代表的意思如下

wParam = (WPARAM) hMixer
lParam = (LPARAM) dwLineID

  在我们的应用程序中,我们可以在这两个消息处理函数中调整我们的设置,以对应于系统的改变,比如你的代码可以这样写:

void CMixerControlDlg::OnMCChange(WPARAM wParam, LPARAM lParam)
{
 DWORD dwLValue;
 DWORD dwRValue;
 GetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &dwLValue,&dwRValue);
 //GetVolume函数的定义见下面,然后根据返回的值调整滑动条的位置
 m_SliderVolR.SetPos(MAX_VOL_VALUE - dwLValue);
 m_SliderVolL.SetPos(MAX_VOL_VALUE - dwRValue);
 //你也可以在这里调用GetMute查看Volume是否被静音,
}

  如此你的程序就可以自动的响应系统设置的改变了。

  关于mixer API的应用开发就介绍到这里,记着最后要关闭mixer如此:mixerClose(m_hmx);

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值