VolumeDlg.cpp
上传用户:sdpcwz
上传日期:2009-12-14
资源大小:1237k
文件大小:8k
源码类别:

书籍源码

开发平台:

Visual C++

  1. // VolumeDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Volume.h"
  5. #include "VolumeDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CAboutDlg dialog used for App About
  13. class CAboutDlg : public CDialog
  14. {
  15. public:
  16. CAboutDlg();
  17. // Dialog Data
  18. //{{AFX_DATA(CAboutDlg)
  19. enum { IDD = IDD_ABOUTBOX };
  20. //}}AFX_DATA
  21. // ClassWizard generated virtual function overrides
  22. //{{AFX_VIRTUAL(CAboutDlg)
  23. protected:
  24. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  25. //}}AFX_VIRTUAL
  26. // Implementation
  27. protected:
  28. //{{AFX_MSG(CAboutDlg)
  29. //}}AFX_MSG
  30. DECLARE_MESSAGE_MAP()
  31. };
  32. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  33. {
  34. //{{AFX_DATA_INIT(CAboutDlg)
  35. //}}AFX_DATA_INIT
  36. }
  37. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  38. {
  39. CDialog::DoDataExchange(pDX);
  40. //{{AFX_DATA_MAP(CAboutDlg)
  41. //}}AFX_DATA_MAP
  42. }
  43. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  44. //{{AFX_MSG_MAP(CAboutDlg)
  45. // No message handlers
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CVolumeDlg dialog
  50. CVolumeDlg::CVolumeDlg(CWnd* pParent /*=NULL*/)
  51. : CDialog(CVolumeDlg::IDD, pParent)
  52. {
  53. //{{AFX_DATA_INIT(CVolumeDlg)
  54. //}}AFX_DATA_INIT
  55. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  56. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  57. }
  58. void CVolumeDlg::DoDataExchange(CDataExchange* pDX)
  59. {
  60. CDialog::DoDataExchange(pDX);
  61. //{{AFX_DATA_MAP(CVolumeDlg)
  62. DDX_Control(pDX, IDC_SLIDER, m_ctrlSlider);
  63. //}}AFX_DATA_MAP
  64. }
  65. BEGIN_MESSAGE_MAP(CVolumeDlg, CDialog)
  66. //{{AFX_MSG_MAP(CVolumeDlg)
  67. ON_WM_SYSCOMMAND()
  68. ON_WM_PAINT()
  69. ON_WM_QUERYDRAGICON()
  70. ON_WM_DESTROY()
  71. ON_WM_HSCROLL()
  72. ON_MESSAGE(MM_MIXM_CONTROL_CHANGE, OnMixerCtrlChange)
  73. //}}AFX_MSG_MAP
  74. END_MESSAGE_MAP()
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CVolumeDlg message handlers
  77. BOOL CVolumeDlg::OnInitDialog()
  78. {
  79. CDialog::OnInitDialog();
  80. // Add "About..." menu item to system menu.
  81. // IDM_ABOUTBOX must be in the system command range.
  82. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  83. ASSERT(IDM_ABOUTBOX < 0xF000);
  84. CMenu* pSysMenu = GetSystemMenu(FALSE);
  85. if (pSysMenu != NULL)
  86. {
  87. CString strAboutMenu;
  88. strAboutMenu.LoadString(IDS_ABOUTBOX);
  89. if (!strAboutMenu.IsEmpty())
  90. {
  91. pSysMenu->AppendMenu(MF_SEPARATOR);
  92. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  93. }
  94. }
  95. // Set the icon for this dialog.  The framework does this automatically
  96. //  when the application's main window is not a dialog
  97. SetIcon(m_hIcon, TRUE); // Set big icon
  98. SetIcon(m_hIcon, FALSE); // Set small icon
  99. // TODO: Add extra initialization here
  100. //初始化混合器设备
  101. if (amdInitialize())
  102. {
  103. // get the Control ID and the names
  104. //获得音量控制控件的ID和名称
  105. amdGetMasterVolumeControl();
  106. //初始化滚动条
  107. m_ctrlSlider.SetRange(m_dwMinimum, m_dwMaximum);
  108. // 获得当前音量值,并设置滚动条的初始位置
  109. DWORD dwVal;
  110. if(amdGetMasterVolumeValue(dwVal))
  111. m_ctrlSlider.SetPos(dwVal);
  112. UpdateData(FALSE);
  113. }
  114. return TRUE;  // return TRUE  unless you set the focus to a control
  115. }
  116. void CVolumeDlg::OnSysCommand(UINT nID, LPARAM lParam)
  117. {
  118. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  119. {
  120. CAboutDlg dlgAbout;
  121. dlgAbout.DoModal();
  122. }
  123. else
  124. {
  125. CDialog::OnSysCommand(nID, lParam);
  126. }
  127. }
  128. // If you add a minimize button to your dialog, you will need the code below
  129. //  to draw the icon.  For MFC applications using the document/view model,
  130. //  this is automatically done for you by the framework.
  131. void CVolumeDlg::OnPaint() 
  132. {
  133. if (IsIconic())
  134. {
  135. CPaintDC dc(this); // device context for painting
  136. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  137. // Center icon in client rectangle
  138. int cxIcon = GetSystemMetrics(SM_CXICON);
  139. int cyIcon = GetSystemMetrics(SM_CYICON);
  140. CRect rect;
  141. GetClientRect(&rect);
  142. int x = (rect.Width() - cxIcon + 1) / 2;
  143. int y = (rect.Height() - cyIcon + 1) / 2;
  144. // Draw the icon
  145. dc.DrawIcon(x, y, m_hIcon);
  146. }
  147. else
  148. {
  149. CDialog::OnPaint();
  150. }
  151. }
  152. // The system calls this to obtain the cursor to display while the user drags
  153. //  the minimized window.
  154. HCURSOR CVolumeDlg::OnQueryDragIcon()
  155. {
  156. return (HCURSOR) m_hIcon;
  157. }
  158. void CVolumeDlg::OnDestroy() 
  159. {
  160. amdUninitialize();
  161. CDialog::OnDestroy();
  162. }
  163. void CVolumeDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  164. {
  165. //根据滚动条的位置设置音量
  166. if (pScrollBar != NULL)
  167. amdSetMasterVolumeValue(((CSliderCtrl *)pScrollBar)->GetPos());
  168. CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
  169. }
  170. LONG CVolumeDlg::OnMixerCtrlChange(UINT wParam, LONG lParam)
  171. {
  172. //响应控件音量改变的消息,然后获得当前音量并设置滚动条
  173. if ((HMIXER)wParam == m_hMixer && (DWORD)lParam == m_dwVolumeControlID)
  174. {
  175. DWORD dwVal;
  176. if (amdGetMasterVolumeValue(dwVal))
  177. m_ctrlSlider.SetPos(dwVal);
  178. }
  179. return 0L;
  180. }
  181. BOOL CVolumeDlg::amdInitialize()
  182. {
  183. // get the number of mixer devices present in the system
  184. //获取当前混合设备数量 
  185. m_nNumMixers = ::mixerGetNumDevs();
  186. m_hMixer = NULL;
  187. ::ZeroMemory(&m_mxcaps, sizeof(MIXERCAPS));
  188. if (m_nNumMixers != 0)
  189. {
  190. //打开混合设备
  191. if (::mixerOpen(&m_hMixer,
  192. 0,
  193. (DWORD)this->GetSafeHwnd(),
  194. NULL,
  195. MIXER_OBJECTF_MIXER | CALLBACK_WINDOW)
  196. != MMSYSERR_NOERROR)
  197. return FALSE;
  198. // 获取混合器性能 
  199. if (::mixerGetDevCaps((UINT)m_hMixer, &m_mxcaps, sizeof(MIXERCAPS))
  200. != MMSYSERR_NOERROR)
  201. return FALSE;
  202. }
  203. return TRUE;
  204. }
  205. BOOL CVolumeDlg::amdUninitialize()
  206. {
  207. BOOL bSucc = TRUE;
  208. if (m_hMixer != NULL)
  209. {
  210. //关闭混合器
  211. bSucc = ::mixerClose(m_hMixer) == MMSYSERR_NOERROR;
  212. m_hMixer = NULL;
  213. }
  214. return bSucc;
  215. }
  216. //获得控件
  217. BOOL CVolumeDlg::amdGetMasterVolumeControl()
  218. {
  219. m_strDstLineName.Empty();
  220. m_strVolumeControlName.Empty();
  221. if (m_hMixer == NULL)
  222. return FALSE;
  223. //获得混合器性能
  224. MIXERLINE mxl;
  225. mxl.cbStruct = sizeof(MIXERLINE);
  226. mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
  227. if (::mixerGetLineInfo((HMIXEROBJ)m_hMixer,
  228.    &mxl,
  229.    MIXER_OBJECTF_HMIXER |
  230.    MIXER_GETLINEINFOF_COMPONENTTYPE)
  231. != MMSYSERR_NOERROR)
  232. return FALSE;
  233. MIXERCONTROL mxc;
  234. MIXERLINECONTROLS mxlc;
  235. mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
  236. mxlc.dwLineID = mxl.dwLineID;
  237. mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
  238. mxlc.cControls = 1;
  239. mxlc.cbmxctrl = sizeof(MIXERCONTROL);
  240. mxlc.pamxctrl = &mxc;
  241. //获得混合器线控件
  242. if (::mixerGetLineControls((HMIXEROBJ)m_hMixer,
  243.    &mxlc,
  244.    MIXER_OBJECTF_HMIXER |
  245.    MIXER_GETLINECONTROLSF_ONEBYTYPE)
  246. != MMSYSERR_NOERROR)
  247. return FALSE;
  248. //记录控件的信息
  249. m_strDstLineName = mxl.szName;
  250. m_strVolumeControlName = mxc.szName;
  251. m_dwMinimum = mxc.Bounds.dwMinimum;
  252. m_dwMaximum = mxc.Bounds.dwMaximum;
  253. m_dwVolumeControlID = mxc.dwControlID;
  254. return TRUE;
  255. }
  256. //获得音量
  257. BOOL CVolumeDlg::amdGetMasterVolumeValue(DWORD &dwVal) const
  258. {
  259. if (m_hMixer == NULL ||
  260. m_strDstLineName.IsEmpty() || m_strVolumeControlName.IsEmpty())
  261. return FALSE;
  262. MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
  263. MIXERCONTROLDETAILS mxcd;
  264. mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  265. mxcd.dwControlID = m_dwVolumeControlID;
  266. mxcd.cChannels = 1;
  267. mxcd.cMultipleItems = 0;
  268. mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
  269. mxcd.paDetails = &mxcdVolume;
  270. //获取指定混合器控件 
  271. if (::mixerGetControlDetails((HMIXEROBJ)m_hMixer,
  272.  &mxcd,
  273.  MIXER_OBJECTF_HMIXER |
  274.  MIXER_GETCONTROLDETAILSF_VALUE)
  275. != MMSYSERR_NOERROR)
  276. return FALSE;
  277. dwVal = mxcdVolume.dwValue;
  278. return TRUE;
  279. }
  280. //设置音量
  281. BOOL CVolumeDlg::amdSetMasterVolumeValue(DWORD dwVal) const
  282. {
  283. if (m_hMixer == NULL ||
  284. m_strDstLineName.IsEmpty() || m_strVolumeControlName.IsEmpty())
  285. return FALSE;
  286. MIXERCONTROLDETAILS_UNSIGNED mxcdVolume = { dwVal };
  287. MIXERCONTROLDETAILS mxcd;
  288. mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  289. mxcd.dwControlID = m_dwVolumeControlID;
  290. mxcd.cChannels = 1;
  291. mxcd.cMultipleItems = 0;
  292. mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
  293. mxcd.paDetails = &mxcdVolume;
  294. //放置混合器控件 
  295. if (::mixerSetControlDetails((HMIXEROBJ)m_hMixer,
  296.  &mxcd,
  297.  MIXER_OBJECTF_HMIXER |
  298.  MIXER_SETCONTROLDETAILSF_VALUE)
  299. != MMSYSERR_NOERROR)
  300. return FALSE;
  301. return TRUE;
  302. }