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
;
23 } DIALOG_DATA
, *PDIALOG_DATA
;
37 GetCursorPos(&ptCursor
);
39 GetWindowRect(hwnd
, &rcWindow
);
41 GetWindowRect(GetDesktopWindow(), &rcScreen
);
43 cx
= rcWindow
.right
- rcWindow
.left
;
44 cy
= rcWindow
.bottom
- rcWindow
.top
;
46 if (ptCursor
.y
+ cy
> rcScreen
.bottom
)
51 if (ptCursor
.x
+ cx
> rcScreen
.right
)
56 SetWindowPos(hwnd
, HWND_TOPMOST
, x
, y
, 0, 0, SWP_NOSIZE
);
58 /* Disable the controls for now */
59 EnableWindow(GetDlgItem(hwnd
, IDC_LINE_SWITCH
), FALSE
);
66 PDIALOG_DATA pDialogData
,
71 MIXERLINECONTROLS mxlctrl
;
72 MIXERCONTROLDETAILS mxcd
;
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
);
149 PDIALOG_DATA pDialogData
,
154 MIXERCONTROLDETAILS mxcd
;
155 DWORD dwPos
, dwVolume
, i
;
157 switch (LOWORD(wParam
))
161 dwPos
= VOLUME_MAX
- (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_LINE_SLIDER_VERT
, TBM_GETPOS
, 0, 0);
162 dwVolume
= (dwPos
* pDialogData
->volumeStep
) + pDialogData
->volumeMinimum
;
164 for (i
= 0; i
< pDialogData
->volumeChannels
; i
++)
166 if (i
== pDialogData
->maxChannel
)
168 pDialogData
->volumeCurrentValues
[i
].dwValue
= dwVolume
;
172 pDialogData
->volumeCurrentValues
[i
].dwValue
=
173 pDialogData
->volumeInitValues
[i
].dwValue
* dwVolume
/ pDialogData
-> maxVolume
;
177 mxcd
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
178 mxcd
.dwControlID
= pDialogData
->volumeControlID
;
179 mxcd
.cChannels
= pDialogData
->volumeChannels
;
180 mxcd
.cMultipleItems
= 0;
181 mxcd
.cbDetails
= sizeof(MIXERCONTROLDETAILS_UNSIGNED
);
182 mxcd
.paDetails
= pDialogData
->volumeCurrentValues
;
184 mixerSetControlDetails((HMIXEROBJ
)pDialogData
->hMixer
,
186 MIXER_OBJECTF_HMIXER
| MIXER_SETCONTROLDETAILSF_VALUE
);
190 PlaySound((LPCTSTR
)SND_ALIAS_SYSTEMDEFAULT
, NULL
, SND_ASYNC
| SND_ALIAS_ID
);
208 PDIALOG_DATA pDialogData
;
210 pDialogData
= (PDIALOG_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
215 OnTrayInitDialog(hwndDlg
, wParam
, lParam
);
217 pDialogData
= (PDIALOG_DATA
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DIALOG_DATA
));
218 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pDialogData
);
221 OnTrayInitMixer(pDialogData
, hwndDlg
);
226 OnVScroll(pDialogData
, hwndDlg
, wParam
, lParam
);
232 if (pDialogData
->volumeInitValues
)
233 HeapFree(GetProcessHeap(), 0, pDialogData
->volumeInitValues
);
235 if (pDialogData
->volumeCurrentValues
)
236 HeapFree(GetProcessHeap(), 0, pDialogData
->volumeCurrentValues
);
238 if (pDialogData
->hMixer
)
239 mixerClose(pDialogData
->hMixer
);
241 HeapFree(GetProcessHeap(), 0, pDialogData
);
243 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)NULL
);
248 if (LOWORD(wParam
) == WA_INACTIVE
)
249 EndDialog(hwndDlg
, IDOK
);