ReactOS  0.4.14-dev-49-gfb4591c
speakervolume.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Multimedia Control Panel
3  * FILE: dll/cpl/mmsys/speakervolume.c
4  * PURPOSE: ReactOS Multimedia Control Panel
5  * PROGRAMMER: Eric Kohl <eric.kohl@reactos.com>
6  */
7 
8 #include "mmsys.h"
9 
10 typedef struct _PAGE_DATA
11 {
12  HMIXER hMixer;
21 
22 
23 static
24 BOOL
26  PPAGE_DATA pPageData,
27  HWND hwndDlg)
28 {
29  TCHAR szBuffer[256];
30  MIXERLINE mxln;
31  MIXERCONTROL mxc;
32  MIXERLINECONTROLS mxlctrl;
34  INT i, j;
35 
36  /* Open the mixer */
37  if (mixerOpen(&pPageData->hMixer, 0, PtrToUlong(hwndDlg), 0, MIXER_OBJECTF_MIXER | CALLBACK_WINDOW) != MMSYSERR_NOERROR)
38  {
39  MessageBox(hwndDlg, _T("Cannot open mixer"), NULL, MB_OK);
40  return FALSE;
41  }
42 
43  /* Retrieve the mixer information */
44  mxln.cbStruct = sizeof(MIXERLINE);
46 
48  return FALSE;
49 
50  pPageData->volumeChannels = mxln.cChannels;
51 
52  /* Retrieve the line information */
53  mxlctrl.cbStruct = sizeof(MIXERLINECONTROLS);
54  mxlctrl.dwLineID = mxln.dwLineID;
56  mxlctrl.cControls = 1;
57  mxlctrl.cbmxctrl = sizeof(MIXERCONTROL);
58  mxlctrl.pamxctrl = &mxc;
59 
61  return FALSE;
62 
63  pPageData->volumeControlID = mxc.dwControlID;
64  pPageData->volumeMinimum = mxc.Bounds.dwMinimum;
65  pPageData->volumeMaximum = mxc.Bounds.dwMaximum;
66  pPageData->volumeStep = (pPageData->volumeMaximum - pPageData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN);
67 
68  /* Allocate a buffer for all channel volume values */
69  pPageData->volumeValues = HeapAlloc(GetProcessHeap(),
70  0,
72  if (pPageData->volumeValues == NULL)
73  return FALSE;
74 
75  /* Retrieve the channel volume values */
76  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
77  mxcd.dwControlID = mxc.dwControlID;
78  mxcd.cChannels = mxln.cChannels;
79  mxcd.cMultipleItems = 0;
81  mxcd.paDetails = pPageData->volumeValues;
82 
84  return FALSE;
85 
86  /* Initialize the channels */
87  for (i = 0; i < min(mxln.cChannels, 5); i++)
88  {
89  j = i * 4;
90 
91  /* Set the channel name */
92  LoadString(hApplet, IDS_SPEAKER_LEFT + i, szBuffer, _countof(szBuffer));
93  SetWindowText(GetDlgItem(hwndDlg, 9472 + j), szBuffer);
94 
95  /* Initialize the channel trackbar */
97  SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETTICFREQ, VOLUME_TICFREQ, 0);
99  SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pPageData->volumeValues[i].dwValue - pPageData->volumeMinimum) / pPageData->volumeStep);
100  }
101 
102  /* Hide the unused controls */
103  for (i = mxln.cChannels; i < 8; i++)
104  {
105  j = i * 4;
106  ShowWindow(GetDlgItem(hwndDlg, 9472 + j), SW_HIDE);
107  ShowWindow(GetDlgItem(hwndDlg, 9473 + j), SW_HIDE);
108  ShowWindow(GetDlgItem(hwndDlg, 9474 + j), SW_HIDE);
109  ShowWindow(GetDlgItem(hwndDlg, 9475 + j), SW_HIDE);
110  }
111 
112  return TRUE;
113 }
114 
115 
116 static
117 VOID
119  PPAGE_DATA pPageData,
120  HWND hwndDlg)
121 {
122  MIXERCONTROLDETAILS mxcd;
123  INT i, j;
124 
125  /* Retrieve the channel volume values */
126  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
127  mxcd.dwControlID = pPageData->volumeControlID;
128  mxcd.cChannels = pPageData->volumeChannels;
129  mxcd.cMultipleItems = 0;
131  mxcd.paDetails = pPageData->volumeValues;
132 
134  return;
135 
136  for (i = 0; i < pPageData->volumeChannels; i++)
137  {
138  j = i * 4;
139 
140  SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pPageData->volumeValues[i].dwValue - pPageData->volumeMinimum) / pPageData->volumeStep);
141  }
142 }
143 
144 
145 static
146 VOID
148  PPAGE_DATA pPageData,
149  HWND hwndDlg,
150  WPARAM wParam,
151  LPARAM lParam)
152 {
153  MIXERCONTROLDETAILS mxcd;
154  DWORD dwValue, dwPosition;
155  INT id, idx, i, j;
156 
158  if (id < 9475 && id > 9503)
159  return;
160 
161  if ((id - 9475) % 4 != 0)
162  return;
163 
164  dwPosition = (DWORD)SendDlgItemMessage(hwndDlg, id, TBM_GETPOS, 0, 0);
165 
166  if (dwPosition == VOLUME_MIN)
167  dwValue = pPageData->volumeMinimum;
168  else if (dwPosition == VOLUME_MAX)
169  dwValue = pPageData->volumeMaximum;
170  else
171  dwValue = (dwPosition * pPageData->volumeStep) + pPageData->volumeMinimum;
172 
173  if (pPageData->volumeSync)
174  {
175  for (i = 0; i < pPageData->volumeChannels; i++)
176  {
177  j = 9475 + (i * 4);
178  if (j != id)
179  SendDlgItemMessage(hwndDlg, j, TBM_SETPOS, (WPARAM)TRUE, dwPosition);
180 
181  pPageData->volumeValues[i].dwValue = dwValue;
182  }
183  }
184  else
185  {
186  idx = (id - 9475) / 4;
187  pPageData->volumeValues[idx].dwValue = dwValue;
188  }
189 
190  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
191  mxcd.dwControlID = pPageData->volumeControlID;
192  mxcd.cChannels = pPageData->volumeChannels;
193  mxcd.cMultipleItems = 0;
195  mxcd.paDetails = pPageData->volumeValues;
196 
198  return;
199 }
200 
201 
202 static
203 VOID
205  PPAGE_DATA pPageData,
206  HWND hwndDlg)
207 {
208  MIXERCONTROLDETAILS mxcd;
209  DWORD dwValue, i;
210 
211  dwValue = ((VOLUME_MAX - VOLUME_MIN) / 2 * pPageData->volumeStep) + pPageData->volumeMinimum;
212 
213  for (i = 0; i < pPageData->volumeChannels; i++)
214  pPageData->volumeValues[i].dwValue = dwValue;
215 
216  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
217  mxcd.dwControlID = pPageData->volumeControlID;
218  mxcd.cChannels = pPageData->volumeChannels;
219  mxcd.cMultipleItems = 0;
221  mxcd.paDetails = pPageData->volumeValues;
222 
224  return;
225 }
226 
227 
228 INT_PTR
229 CALLBACK
231  HWND hwndDlg,
232  UINT uMsg,
233  WPARAM wParam,
234  LPARAM lParam)
235 {
236  PPAGE_DATA pPageData;
237 
239 
240  pPageData = (PPAGE_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
241 
242  switch(uMsg)
243  {
244  case WM_INITDIALOG:
246  SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPageData);
247 
248  if (pPageData)
249  {
250  OnInitDialog(pPageData, hwndDlg);
251  }
252  break;
253 
254  case WM_DESTROY:
255  if (pPageData)
256  {
257  if (pPageData->volumeValues)
258  HeapFree(GetProcessHeap(), 0, pPageData->volumeValues);
259 
260  if (pPageData->hMixer)
261  mixerClose(pPageData->hMixer);
262 
263  HeapFree(GetProcessHeap(), 0, pPageData);
264  pPageData = NULL;
266  }
267  break;
268 
269  case WM_HSCROLL:
270  if (pPageData)
271  {
272  OnHScroll(pPageData, hwndDlg, wParam, lParam);
273  PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
274  }
275  break;
276 
277  case WM_COMMAND:
278  switch (LOWORD(wParam))
279  {
280  case 9504:
281  if (HIWORD(wParam) == BN_CLICKED)
282  pPageData->volumeSync = (SendDlgItemMessage(hwndDlg, 9504, BM_GETCHECK, 0, 0) == BST_CHECKED);
283  break;
284 
285  case 9505:
286  OnSetDefaults(pPageData, hwndDlg);
287  PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
288  break;
289  }
290  break;
291 
292  case WM_NOTIFY:
293  return TRUE;
294 
296  if (pPageData)
297  OnMixerControlChange(pPageData, hwndDlg);
298  break;
299  }
300 
301  return FALSE;
302 }
303 
304 
305 INT_PTR
307  HWND hwndDlg)
308 {
309  PROPSHEETPAGE psp[1];
310  PROPSHEETHEADER psh;
311  TCHAR Caption[256];
312 
313  LoadString(hApplet, IDS_SPEAKER_VOLUME, Caption, _countof(Caption));
314 
315  ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
316  psh.dwSize = sizeof(PROPSHEETHEADER);
317  psh.dwFlags = PSH_PROPSHEETPAGE;
318  psh.hwndParent = hwndDlg;
319  psh.hInstance = hApplet;
320  psh.pszCaption = Caption;
321  psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
322  psh.nStartPage = 0;
323  psh.ppsp = psp;
324 
326  psp[0].dwFlags |= PSP_USETITLE;
327  psp[0].pszTitle = Caption;
328 
329  return (LONG)(PropertySheet(&psh) != -1);
330 }
UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
Definition: winmm.c:684
INT_PTR SpeakerVolume(HWND hwndDlg)
#define MIXER_GETCONTROLDETAILSF_VALUE
Definition: mmsystem.h:412
#define TRUE
Definition: types.h:120
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
static VOID OnHScroll(PPAGE_DATA pPageData, HWND hwndDlg, WPARAM wParam, LPARAM lParam)
struct tMIXERCONTROLDETAILS_UNSIGNED MIXERCONTROLDETAILS_UNSIGNED
#define IDS_SPEAKER_VOLUME
Definition: resource.h:73
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define SW_HIDE
Definition: winuser.h:762
#define _countof(array)
Definition: fontsub.cpp:30
#define mixerGetLineInfo
Definition: mmsystem.h:2843
#define INT
Definition: polytest.cpp:20
#define CALLBACK
Definition: compat.h:27
#define IDD_MULTICHANNEL
Definition: resource.h:29
#define TBM_SETRANGE
Definition: commctrl.h:2009
UINT WINAPI mixerClose(HMIXER hMix)
Definition: winmm.c:389
#define mixerGetLineControls
Definition: mmsystem.h:2844
DWORD volumeMaximum
Definition: speakervolume.c:16
#define ZeroMemory
Definition: winbase.h:1635
#define TBM_SETPOS
Definition: commctrl.h:2008
#define VOLUME_MAX
Definition: sndvol32.h:19
HINSTANCE hApplet
Definition: access.c:17
#define MIXER_GETLINEINFOF_COMPONENTTYPE
Definition: mmsystem.h:347
UINT_PTR WPARAM
Definition: windef.h:207
#define SendDlgItemMessage
Definition: winuser.h:5743
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
MIXERLINEA MIXERLINE
Definition: mmsystem.h:2814
int32_t INT_PTR
Definition: typedefs.h:62
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:56
#define SetWindowLongPtr
Definition: treelist.c:70
WPARAM wParam
Definition: combotst.c:138
MIXERCONTROLA MIXERCONTROL
Definition: mmsystem.h:2815
HMIXER hMixer
Definition: speakervolume.c:12
#define MIXER_OBJECTF_MIXER
Definition: mmsystem.h:300
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
DWORD volumeStep
Definition: speakervolume.c:17
#define MIXER_SETCONTROLDETAILSF_VALUE
Definition: mmsystem.h:415
LPMIXERCONTROLA pamxctrl
Definition: mmsystem.h:1338
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define TBM_GETPOS
Definition: commctrl.h:2003
MIXERLINECONTROLSA MIXERLINECONTROLS
Definition: mmsystem.h:2816
unsigned int idx
Definition: utils.c:41
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define TBM_SETPAGESIZE
Definition: commctrl.h:2023
static VOID OnSetDefaults(PPAGE_DATA pPageData, HWND hwndDlg)
smooth NULL
Definition: ftsmooth.c:416
struct _PAGE_DATA * PPAGE_DATA
#define PROPSHEETHEADER
Definition: prsht.h:374
LONG_PTR LPARAM
Definition: windef.h:208
static VOID OnMixerControlChange(PPAGE_DATA pPageData, HWND hwndDlg)
#define BM_GETCHECK
Definition: winuser.h:1900
UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: winmm.c:342
#define TBM_SETTICFREQ
Definition: commctrl.h:2022
#define VOLUME_PAGESIZE
Definition: mmsys.h:43
#define PtrToUlong(u)
Definition: config.h:107
#define WM_DESTROY
Definition: winuser.h:1591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
char TCHAR
Definition: xmlstorage.h:189
DWORD dwLineID
Definition: mmsystem.h:1235
#define _T(x)
Definition: vfdio.h:22
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL volumeSync
Definition: speakervolume.c:19
if(!(yy_init))
Definition: macro.lex.yy.c:714
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define VOLUME_TICFREQ
Definition: mmsys.h:42
#define PropSheet_Changed(d, w)
Definition: prsht.h:326
#define BN_CLICKED
Definition: winuser.h:1907
unsigned long DWORD
Definition: ntddk_ex.h:95
static BOOL OnInitDialog(PPAGE_DATA pPageData, HWND hwndDlg)
Definition: speakervolume.c:25
#define MIXER_OBJECTF_HMIXER
Definition: mmsystem.h:301
static VOID InitPropSheetPage(PROPSHEETPAGE *psp, PSERVICEPROPSHEET dlgInfo, WORD idDlg, DLGPROC DlgProc)
Definition: propsheet.c:15
#define DWLP_USER
Definition: winuser.h:866
DWORD cChannels
Definition: mmsystem.h:1239
#define MessageBox
Definition: winuser.h:5723
PMIXERCONTROLDETAILS_UNSIGNED volumeValues
Definition: speakervolume.c:18
#define WM_COMMAND
Definition: winuser.h:1722
#define PSP_USETITLE
Definition: prsht.h:26
struct _PAGE_DATA PAGE_DATA
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
HWND WINAPI GetParent(_In_ HWND)
INT_PTR CALLBACK SpeakerVolumeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
DWORD volumeMinimum
Definition: speakervolume.c:15
#define MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
Definition: mmsystem.h:319
DWORD cbStruct
Definition: mmsystem.h:1232
#define PSH_PROPSHEETPAGE
Definition: prsht.h:43
#define VOLUME_MIN
Definition: sndvol32.h:18
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
struct tMIXERCONTROLDETAILS MIXERCONTROLDETAILS
#define SetWindowText
Definition: winuser.h:5758
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define mixerGetControlDetails
Definition: mmsystem.h:2845
#define WM_HSCROLL
Definition: winuser.h:1725
#define MB_OK
Definition: winuser.h:784
#define MIXER_GETLINECONTROLSF_ONEBYTYPE
Definition: mmsystem.h:410
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
union tagMIXERCONTROLA::@2915 Bounds
#define BST_CHECKED
Definition: winuser.h:197
DWORD dwComponentType
Definition: mmsystem.h:1238
#define PropertySheet
Definition: prsht.h:382
DWORD volumeChannels
Definition: speakervolume.c:14
#define HIWORD(l)
Definition: typedefs.h:246
GLenum GLuint id
Definition: glext.h:5579
DWORD volumeControlID
Definition: speakervolume.c:13
#define GetWindowLongPtr
Definition: treelist.c:73
#define IDS_SPEAKER_LEFT
Definition: resource.h:74
#define WM_INITDIALOG
Definition: winuser.h:1721
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
#define GWLP_ID
Definition: winuser.h:854
#define LoadString
Definition: winuser.h:5720
#define PROPSHEETPAGE
Definition: prsht.h:371
#define WM_NOTIFY
Definition: richedit.h:61
#define MM_MIXM_CONTROL_CHANGE
Definition: mmsystem.h:83