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>
10 typedef struct _DIALOG_DATA
13 DWORD volumeControlID
;
21 PMIXERCONTROLDETAILS_UNSIGNED volumeInitValues
;
22 PMIXERCONTROLDETAILS_UNSIGNED volumeCurrentValues
;
25 } DIALOG_DATA
, *PDIALOG_DATA
;
39 GetCursorPos(&ptCursor
);
41 GetWindowRect(hwnd
, &rcWindow
);
43 GetWindowRect(GetDesktopWindow(), &rcScreen
);
45 cx
= rcWindow
.right
- rcWindow
.left
;
46 cy
= rcWindow
.bottom
- rcWindow
.top
;
48 if (ptCursor
.y
+ cy
> rcScreen
.bottom
)
53 if (ptCursor
.x
+ cx
> rcScreen
.right
)
58 SetWindowPos(hwnd
, HWND_TOPMOST
, x
, y
, 0, 0, SWP_NOSIZE
);
65 PDIALOG_DATA pDialogData
,
70 MIXERLINECONTROLS mxlctrl
;
71 MIXERCONTROLDETAILS mxcd
;
72 MIXERCONTROLDETAILS_BOOLEAN mxcdBool
;
76 if (mixerOpen(&pDialogData
->hMixer
, 0, PtrToUlong(hwndDlg
), 0, MIXER_OBJECTF_MIXER
| CALLBACK_WINDOW
) != MMSYSERR_NOERROR
)
79 /* Retrieve the mixer information */
80 mxln
.cbStruct
= sizeof(MIXERLINE
);
81 mxln
.dwComponentType
= MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
;
83 if (mixerGetLineInfo((HMIXEROBJ
)pDialogData
->hMixer
, &mxln
, MIXER_OBJECTF_HMIXER
| MIXER_GETLINEINFOF_COMPONENTTYPE
) != MMSYSERR_NOERROR
)
86 pDialogData
->volumeChannels
= mxln
.cChannels
;
88 /* Retrieve the line information */
89 mxlctrl
.cbStruct
= sizeof(MIXERLINECONTROLS
);
90 mxlctrl
.dwLineID
= mxln
.dwLineID
;
91 mxlctrl
.dwControlType
= MIXERCONTROL_CONTROLTYPE_VOLUME
;
92 mxlctrl
.cControls
= 1;
93 mxlctrl
.cbmxctrl
= sizeof(MIXERCONTROL
);
94 mxlctrl
.pamxctrl
= &mxc
;
96 if (mixerGetLineControls((HMIXEROBJ
)pDialogData
->hMixer
, &mxlctrl
, MIXER_OBJECTF_HMIXER
| MIXER_GETLINECONTROLSF_ONEBYTYPE
) != MMSYSERR_NOERROR
)
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
);
104 /* Allocate a buffer for all channel volume values */
105 pDialogData
->volumeInitValues
= HeapAlloc(GetProcessHeap(),
107 mxln
.cChannels
* sizeof(MIXERCONTROLDETAILS_UNSIGNED
));
108 if (pDialogData
->volumeInitValues
== NULL
)
111 pDialogData
->volumeCurrentValues
= HeapAlloc(GetProcessHeap(),
113 mxln
.cChannels
* sizeof(MIXERCONTROLDETAILS_UNSIGNED
));
114 if (pDialogData
->volumeCurrentValues
== NULL
)
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;
122 mxcd
.cbDetails
= sizeof(MIXERCONTROLDETAILS_UNSIGNED
);
123 mxcd
.paDetails
= pDialogData
->volumeInitValues
;
125 if (mixerGetControlDetails((HMIXEROBJ
)pDialogData
->hMixer
, &mxcd
, MIXER_OBJECTF_HMIXER
| MIXER_GETCONTROLDETAILSF_VALUE
) != MMSYSERR_NOERROR
)
128 pDialogData
->maxVolume
= pDialogData
->volumeInitValues
[0].dwValue
;
129 pDialogData
->maxChannel
= 0;
130 for (i
= 1; i
< pDialogData
->volumeChannels
; i
++)
132 if (pDialogData
->volumeInitValues
[i
].dwValue
> pDialogData
->maxVolume
)
134 pDialogData
->maxVolume
= pDialogData
->volumeInitValues
[i
].dwValue
;
135 pDialogData
->maxChannel
= i
;
139 /* Initialize the volume trackbar */
140 SendDlgItemMessage(hwndDlg
, IDC_LINE_SLIDER_VERT
, TBM_SETRANGE
, TRUE
, MAKELONG(VOLUME_MIN
, VOLUME_MAX
));
141 SendDlgItemMessage(hwndDlg
, IDC_LINE_SLIDER_VERT
, TBM_SETPAGESIZE
, 0, VOLUME_PAGE_SIZE
);
142 SendDlgItemMessage(hwndDlg
, IDC_LINE_SLIDER_VERT
, TBM_SETPOS
, TRUE
, VOLUME_MAX
-(pDialogData
->maxVolume
- pDialogData
->volumeMinimum
) / pDialogData
->volumeStep
);
144 /* Retrieve the mute control information */
145 mxlctrl
.cbStruct
= sizeof(MIXERLINECONTROLS
);
146 mxlctrl
.dwLineID
= mxln
.dwLineID
;
147 mxlctrl
.dwControlType
= MIXERCONTROL_CONTROLTYPE_MUTE
;
148 mxlctrl
.cControls
= 1;
149 mxlctrl
.cbmxctrl
= sizeof(MIXERCONTROL
);
150 mxlctrl
.pamxctrl
= &mxc
;
152 if (mixerGetLineControls((HMIXEROBJ
)pDialogData
->hMixer
, &mxlctrl
, MIXER_OBJECTF_HMIXER
| MIXER_GETLINECONTROLSF_ONEBYTYPE
) != MMSYSERR_NOERROR
)
155 pDialogData
->muteControlID
= mxc
.dwControlID
;
157 /* Retrieve the mute value */
158 mxcd
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
159 mxcd
.dwControlID
= mxc
.dwControlID
;
161 mxcd
.cMultipleItems
= 0;
162 mxcd
.cbDetails
= sizeof(MIXERCONTROLDETAILS_BOOLEAN
);
163 mxcd
.paDetails
= &mxcdBool
;
165 if (mixerGetControlDetails((HMIXEROBJ
)pDialogData
->hMixer
, &mxcd
, MIXER_OBJECTF_HMIXER
| MIXER_GETCONTROLDETAILSF_VALUE
) != MMSYSERR_NOERROR
)
168 /* Initialize the mute checkbox */
169 SendDlgItemMessage(hwndDlg
, IDC_LINE_SWITCH
, BM_SETCHECK
, (WPARAM
)(mxcdBool
.fValue
? BST_CHECKED
: BST_UNCHECKED
), 0);
176 PDIALOG_DATA pDialogData
,
181 MIXERCONTROLDETAILS mxcd
;
182 MIXERCONTROLDETAILS_BOOLEAN mxcdMute
;
184 if ((LOWORD(wParam
) == IDC_LINE_SWITCH
) &&
185 (HIWORD(wParam
) == BN_CLICKED
))
187 mxcd
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
188 mxcd
.dwControlID
= pDialogData
->muteControlID
;
190 mxcd
.cMultipleItems
= 0;
191 mxcd
.cbDetails
= sizeof(MIXERCONTROLDETAILS_BOOLEAN
);
192 mxcd
.paDetails
= &mxcdMute
;
194 mxcdMute
.fValue
= (SendMessage((HWND
)lParam
, BM_GETCHECK
, 0, 0) == BST_CHECKED
);
196 mixerSetControlDetails((HMIXEROBJ
)pDialogData
->hMixer
,
198 MIXER_OBJECTF_HMIXER
| MIXER_SETCONTROLDETAILSF_VALUE
);
206 PDIALOG_DATA pDialogData
,
211 MIXERCONTROLDETAILS mxcd
;
212 DWORD dwPos
, dwVolume
, i
;
214 switch (LOWORD(wParam
))
218 dwPos
= VOLUME_MAX
- (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_LINE_SLIDER_VERT
, TBM_GETPOS
, 0, 0);
219 dwVolume
= (dwPos
* pDialogData
->volumeStep
) + pDialogData
->volumeMinimum
;
221 for (i
= 0; i
< pDialogData
->volumeChannels
; i
++)
223 if (i
== pDialogData
->maxChannel
)
225 pDialogData
->volumeCurrentValues
[i
].dwValue
= dwVolume
;
229 pDialogData
->volumeCurrentValues
[i
].dwValue
=
230 pDialogData
->volumeInitValues
[i
].dwValue
* dwVolume
/ pDialogData
-> maxVolume
;
234 mxcd
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
235 mxcd
.dwControlID
= pDialogData
->volumeControlID
;
236 mxcd
.cChannels
= pDialogData
->volumeChannels
;
237 mxcd
.cMultipleItems
= 0;
238 mxcd
.cbDetails
= sizeof(MIXERCONTROLDETAILS_UNSIGNED
);
239 mxcd
.paDetails
= pDialogData
->volumeCurrentValues
;
241 mixerSetControlDetails((HMIXEROBJ
)pDialogData
->hMixer
,
243 MIXER_OBJECTF_HMIXER
| MIXER_SETCONTROLDETAILSF_VALUE
);
247 PlaySound((LPCTSTR
)SND_ALIAS_SYSTEMDEFAULT
, NULL
, SND_ASYNC
| SND_ALIAS_ID
);
265 PDIALOG_DATA pDialogData
;
267 pDialogData
= (PDIALOG_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
272 OnTrayInitDialog(hwndDlg
, wParam
, lParam
);
274 pDialogData
= (PDIALOG_DATA
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DIALOG_DATA
));
275 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pDialogData
);
278 OnTrayInitMixer(pDialogData
, hwndDlg
);
283 OnCommand(pDialogData
, hwndDlg
, wParam
, lParam
);
288 OnVScroll(pDialogData
, hwndDlg
, wParam
, lParam
);
294 if (pDialogData
->volumeInitValues
)
295 HeapFree(GetProcessHeap(), 0, pDialogData
->volumeInitValues
);
297 if (pDialogData
->volumeCurrentValues
)
298 HeapFree(GetProcessHeap(), 0, pDialogData
->volumeCurrentValues
);
300 if (pDialogData
->hMixer
)
301 mixerClose(pDialogData
->hMixer
);
303 HeapFree(GetProcessHeap(), 0, pDialogData
);
305 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)NULL
);
310 if (LOWORD(wParam
) == WA_INACTIVE
)
311 EndDialog(hwndDlg
, IDOK
);