ReactOS  0.4.13-dev-235-g7373cb3
tray.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Sound Volume Control
4  * FILE: base/applications/sndvol32/tray.c
5  * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
6  */
7 
8 #include "sndvol32.h"
9 
10 typedef struct _DIALOG_DATA
11 {
12  HMIXER hMixer;
18 
23 
26 
27 
28 static VOID
30  HWND hwnd,
31  WPARAM wParam,
32  LPARAM lParam)
33 {
34  POINT ptCursor;
35  RECT rcWindow;
36  RECT rcScreen;
37  LONG x, y, cx, cy;
38 
39  GetCursorPos(&ptCursor);
40 
41  GetWindowRect(hwnd, &rcWindow);
42 
43  GetWindowRect(GetDesktopWindow(), &rcScreen);
44 
45  cx = rcWindow.right - rcWindow.left;
46  cy = rcWindow.bottom - rcWindow.top;
47 
48  if (ptCursor.y + cy > rcScreen.bottom)
49  y = ptCursor.y - cy;
50  else
51  y = ptCursor.y;
52 
53  if (ptCursor.x + cx > rcScreen.right)
54  x = ptCursor.x - cx;
55  else
56  x = ptCursor.x;
57 
59 }
60 
61 
62 static
63 VOID
65  PDIALOG_DATA pDialogData,
66  HWND hwndDlg)
67 {
68  MIXERLINE mxln;
69  MIXERCONTROL mxc;
70  MIXERLINECONTROLS mxlctrl;
73  DWORD i;
74 
75  /* Open the mixer */
76  if (mixerOpen(&pDialogData->hMixer, 0, PtrToUlong(hwndDlg), 0, MIXER_OBJECTF_MIXER | CALLBACK_WINDOW) != MMSYSERR_NOERROR)
77  return;
78 
79  /* Retrieve the mixer information */
80  mxln.cbStruct = sizeof(MIXERLINE);
82 
84  return;
85 
86  pDialogData->volumeChannels = mxln.cChannels;
87 
88  /* Retrieve the line information */
89  mxlctrl.cbStruct = sizeof(MIXERLINECONTROLS);
90  mxlctrl.dwLineID = mxln.dwLineID;
92  mxlctrl.cControls = 1;
93  mxlctrl.cbmxctrl = sizeof(MIXERCONTROL);
94  mxlctrl.pamxctrl = &mxc;
95 
97  return;
98 
99  pDialogData->volumeControlID = mxc.dwControlID;
100  pDialogData->volumeMinimum = mxc.Bounds.dwMinimum;
101  pDialogData->volumeMaximum = mxc.Bounds.dwMaximum;
102  pDialogData->volumeStep = (pDialogData->volumeMaximum - pDialogData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN);
103 
104  /* Allocate a buffer for all channel volume values */
105  pDialogData->volumeInitValues = HeapAlloc(GetProcessHeap(),
106  0,
107  mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
108  if (pDialogData->volumeInitValues == NULL)
109  return;
110 
112  0,
113  mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
114  if (pDialogData->volumeCurrentValues == NULL)
115  return;
116 
117  /* Retrieve the channel volume values */
118  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
119  mxcd.dwControlID = mxc.dwControlID;
120  mxcd.cChannels = mxln.cChannels;
121  mxcd.cMultipleItems = 0;
123  mxcd.paDetails = pDialogData->volumeInitValues;
124 
126  return;
127 
128  pDialogData->maxVolume = 0;
129  for (i = 0; i < pDialogData->volumeChannels; i++)
130  {
131  pDialogData->volumeCurrentValues[i].dwValue = pDialogData->volumeInitValues[i].dwValue;
132 
133  if (pDialogData->volumeInitValues[i].dwValue > pDialogData->maxVolume)
134  pDialogData->maxVolume = pDialogData->volumeInitValues[i].dwValue;
135  }
136 
137  /* Initialize the volume trackbar */
140  SendDlgItemMessage(hwndDlg, IDC_LINE_SLIDER_VERT, TBM_SETPOS, TRUE, VOLUME_MAX -(pDialogData->maxVolume - pDialogData->volumeMinimum) / pDialogData->volumeStep);
141 
142  /* Retrieve the mute control information */
143  mxlctrl.cbStruct = sizeof(MIXERLINECONTROLS);
144  mxlctrl.dwLineID = mxln.dwLineID;
146  mxlctrl.cControls = 1;
147  mxlctrl.cbmxctrl = sizeof(MIXERCONTROL);
148  mxlctrl.pamxctrl = &mxc;
149 
151  return;
152 
153  pDialogData->muteControlID = mxc.dwControlID;
154 
155  /* Retrieve the mute value */
156  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
157  mxcd.dwControlID = mxc.dwControlID;
158  mxcd.cChannels = 1;
159  mxcd.cMultipleItems = 0;
160  mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
161  mxcd.paDetails = &mxcdBool;
162 
164  return;
165 
166  /* Initialize the mute checkbox */
168 }
169 
170 
171 static
172 VOID
174  PDIALOG_DATA pDialogData,
175  HWND hwndDlg,
176  WPARAM wParam,
177  LPARAM lParam)
178 {
179  MIXERCONTROLDETAILS mxcd;
181 
182  if ((LOWORD(wParam) == IDC_LINE_SWITCH) &&
183  (HIWORD(wParam) == BN_CLICKED))
184  {
185  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
186  mxcd.dwControlID = pDialogData->muteControlID;
187  mxcd.cChannels = 1;
188  mxcd.cMultipleItems = 0;
189  mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
190  mxcd.paDetails = &mxcdMute;
191 
192  mxcdMute.fValue = (SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED);
193 
194  mixerSetControlDetails((HMIXEROBJ)pDialogData->hMixer,
195  &mxcd,
197  }
198 }
199 
200 
201 static
202 VOID
204  PDIALOG_DATA pDialogData,
205  HWND hwndDlg,
206  WPARAM wParam,
207  LPARAM lParam)
208 {
209  MIXERCONTROLDETAILS mxcd;
210  DWORD dwPosition, dwVolume, i;
211 
212  switch (LOWORD(wParam))
213  {
214  case TB_THUMBPOSITION:
215  break;
216 
217  case TB_ENDTRACK:
219  break;
220 
221  default:
222  dwPosition = VOLUME_MAX - (DWORD)SendDlgItemMessage(hwndDlg, IDC_LINE_SLIDER_VERT, TBM_GETPOS, 0, 0);
223 
224  if (dwPosition == VOLUME_MIN)
225  dwVolume = pDialogData->volumeMinimum;
226  else if (dwPosition == VOLUME_MAX)
227  dwVolume = pDialogData->volumeMaximum;
228  else
229  dwVolume = (dwPosition * pDialogData->volumeStep) + pDialogData->volumeMinimum;
230 
231  for (i = 0; i < pDialogData->volumeChannels; i++)
232  {
233  if (pDialogData->volumeInitValues[i].dwValue == pDialogData->maxVolume)
234  {
235  pDialogData->volumeCurrentValues[i].dwValue = dwVolume;
236  }
237  else
238  {
239  pDialogData->volumeCurrentValues[i].dwValue =
240  pDialogData->volumeInitValues[i].dwValue * dwVolume / pDialogData-> maxVolume;
241  }
242  }
243 
244  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
245  mxcd.dwControlID = pDialogData->volumeControlID;
246  mxcd.cChannels = pDialogData->volumeChannels;
247  mxcd.cMultipleItems = 0;
249  mxcd.paDetails = pDialogData->volumeCurrentValues;
250 
251  mixerSetControlDetails((HMIXEROBJ)pDialogData->hMixer,
252  &mxcd,
254  break;
255  }
256 }
257 
258 
259 
260 INT_PTR
261 CALLBACK
263  HWND hwndDlg,
264  UINT uMsg,
265  WPARAM wParam,
266  LPARAM lParam)
267 {
268  PDIALOG_DATA pDialogData;
269 
270  pDialogData = (PDIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
271 
272  switch (uMsg)
273  {
274  case WM_INITDIALOG:
275  OnTrayInitDialog(hwndDlg, wParam, lParam);
276 
278  SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pDialogData);
279 
280  if (pDialogData)
281  OnTrayInitMixer(pDialogData, hwndDlg);
282  break;
283 
284  case WM_COMMAND:
285  if (pDialogData)
286  OnCommand(pDialogData, hwndDlg, wParam, lParam);
287  break;
288 
289  case WM_VSCROLL:
290  if (pDialogData)
291  OnVScroll(pDialogData, hwndDlg, wParam, lParam);
292  break;
293 
294  case WM_DESTROY:
295  if (pDialogData)
296  {
297  if (pDialogData->volumeInitValues)
298  HeapFree(GetProcessHeap(), 0, pDialogData->volumeInitValues);
299 
300  if (pDialogData->volumeCurrentValues)
301  HeapFree(GetProcessHeap(), 0, pDialogData->volumeCurrentValues);
302 
303  if (pDialogData->hMixer)
304  mixerClose(pDialogData->hMixer);
305 
306  HeapFree(GetProcessHeap(), 0, pDialogData);
307  pDialogData = NULL;
309  }
310  break;
311 
312  case WM_ACTIVATE:
313  if (LOWORD(wParam) == WA_INACTIVE)
314  EndDialog(hwndDlg, IDOK);
315  break;
316  }
317 
318  return 0;
319 }
320 
321 /* EOF */
#define IDC_LINE_SLIDER_VERT
Definition: resources.h:25
static VOID OnVScroll(PDIALOG_DATA pDialogData, HWND hwndDlg, WPARAM wParam, LPARAM lParam)
Definition: tray.c:203
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
Definition: winmm.c:684
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define MIXER_GETCONTROLDETAILSF_VALUE
Definition: mmsystem.h:412
#define TRUE
Definition: types.h:120
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
#define IDOK
Definition: winuser.h:824
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
struct tMIXERCONTROLDETAILS_UNSIGNED MIXERCONTROLDETAILS_UNSIGNED
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
DWORD volumeControlID
Definition: tray.c:13
struct _DIALOG_DATA DIALOG_DATA
#define mixerGetLineInfo
Definition: mmsystem.h:2843
DWORD volumeStep
Definition: tray.c:17
static VOID OnTrayInitMixer(PDIALOG_DATA pDialogData, HWND hwndDlg)
Definition: tray.c:64
#define CALLBACK
Definition: compat.h:27
#define TBM_SETRANGE
Definition: commctrl.h:2009
UINT WINAPI mixerClose(HMIXER hMix)
Definition: winmm.c:389
#define mixerGetLineControls
Definition: mmsystem.h:2844
LONG top
Definition: windef.h:292
DWORD maxChannel
Definition: tray.c:20
static VOID OnCommand(PDIALOG_DATA pDialogData, HWND hwndDlg, WPARAM wParam, LPARAM lParam)
Definition: tray.c:173
PMIXERCONTROLDETAILS_UNSIGNED volumeInitValues
Definition: tray.c:21
#define HWND_TOPMOST
Definition: winuser.h:1194
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define TBM_SETPOS
Definition: commctrl.h:2008
#define VOLUME_MAX
Definition: sndvol32.h:19
#define MIXER_GETLINEINFOF_COMPONENTTYPE
Definition: mmsystem.h:347
UINT_PTR WPARAM
Definition: windef.h:207
#define SendDlgItemMessage
Definition: winuser.h:5708
LONG left
Definition: windef.h:291
MIXERLINEA MIXERLINE
Definition: mmsystem.h:2814
int32_t INT_PTR
Definition: typedefs.h:62
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2635
LONG right
Definition: windef.h:293
#define DWORD
Definition: nt_native.h:44
#define SetWindowLongPtr
Definition: treelist.c:70
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
WPARAM wParam
Definition: combotst.c:138
struct _DIALOG_DATA * PDIALOG_DATA
MIXERCONTROLA MIXERCONTROL
Definition: mmsystem.h:2815
static VOID OnTrayInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam)
Definition: tray.c:29
#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
#define MIXER_SETCONTROLDETAILSF_VALUE
Definition: mmsystem.h:415
LPMIXERCONTROLA pamxctrl
Definition: mmsystem.h:1338
long LONG
Definition: pedump.c:60
#define TBM_GETPOS
Definition: commctrl.h:2003
MIXERLINECONTROLSA MIXERLINECONTROLS
Definition: mmsystem.h:2816
DWORD volumeChannels
Definition: tray.c:14
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define TBM_SETPAGESIZE
Definition: commctrl.h:2023
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:622
LONG_PTR LPARAM
Definition: windef.h:208
#define BM_GETCHECK
Definition: winuser.h:1879
UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: winmm.c:342
DWORD maxVolume
Definition: tray.c:19
#define PtrToUlong(u)
Definition: config.h:107
#define WM_DESTROY
Definition: winuser.h:1591
#define SND_ALIAS_SYSTEMDEFAULT
Definition: mmsystem.h:175
DWORD dwLineID
Definition: mmsystem.h:1235
#define BM_SETCHECK
Definition: winuser.h:1882
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
union tagMIXERCONTROLA::@2906 Bounds
#define for
Definition: utility.h:88
#define BN_CLICKED
Definition: winuser.h:1886
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SND_ASYNC
Definition: mmsystem.h:154
PMIXERCONTROLDETAILS_UNSIGNED volumeCurrentValues
Definition: tray.c:22
#define MIXER_OBJECTF_HMIXER
Definition: mmsystem.h:301
#define TB_ENDTRACK
Definition: commctrl.h:2053
#define DWLP_USER
Definition: winuser.h:866
DWORD cChannels
Definition: mmsystem.h:1239
#define WM_COMMAND
Definition: winuser.h:1716
#define BST_UNCHECKED
Definition: winuser.h:199
HMIXER hMixer
Definition: tray.c:12
#define SWP_NOSIZE
Definition: winuser.h:1230
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
struct tMIXERCONTROLDETAILS_BOOLEAN MIXERCONTROLDETAILS_BOOLEAN
DWORD muteControlID
Definition: tray.c:24
#define PlaySound
Definition: mmsystem.h:2832
#define MIXERCONTROL_CONTROLTYPE_MUTE
Definition: mmsystem.h:384
#define WM_ACTIVATE
Definition: winuser.h:1594
#define MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
Definition: mmsystem.h:319
DWORD cbStruct
Definition: mmsystem.h:1232
DWORD volumeMaximum
Definition: tray.c:16
DWORD volumeMinimum
Definition: tray.c:15
#define VOLUME_MIN
Definition: sndvol32.h:18
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
struct tMIXERCONTROLDETAILS MIXERCONTROLDETAILS
unsigned int UINT
Definition: ndis.h:50
#define mixerGetControlDetails
Definition: mmsystem.h:2845
#define MIXER_GETLINECONTROLSF_ONEBYTYPE
Definition: mmsystem.h:410
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define BST_CHECKED
Definition: winuser.h:197
DWORD dwComponentType
Definition: mmsystem.h:1238
_Out_opt_ int * cx
Definition: commctrl.h:570
#define SendMessage
Definition: winuser.h:5709
INT_PTR CALLBACK TrayDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: tray.c:262
#define HIWORD(l)
Definition: typedefs.h:246
LONG bottom
Definition: windef.h:294
#define VOLUME_PAGE_SIZE
Definition: sndvol32.h:21
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define WA_INACTIVE
Definition: winuser.h:2576
#define GetWindowLongPtr
Definition: treelist.c:73
#define TB_THUMBPOSITION
Definition: commctrl.h:2049
#define WM_INITDIALOG
Definition: winuser.h:1715
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
#define WM_VSCROLL
Definition: winuser.h:1720
#define IDC_LINE_SWITCH
Definition: resources.h:23