[SHELL32] Remove 2 redundant initializations
[reactos.git] / dll / cpl / mmsys / volume.c
1 /*
2 * PROJECT: ReactOS Multimedia Control Panel
3 * FILE: dll/cpl/mmsys/volume.c
4 * PURPOSE: ReactOS Multimedia Control Panel
5 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
6 * Johannes Anderwald <janderwald@reactos.com>
7 * Dmitry Chapyshev <dmitry@reactos.org>
8 */
9
10 #include "mmsys.h"
11
12 #include <shellapi.h>
13
14
15 typedef struct _IMGINFO
16 {
17 HBITMAP hBitmap;
18 INT cxSource;
19 INT cySource;
20 } IMGINFO, *PIMGINFO;
21
22
23 typedef struct _GLOBAL_DATA
24 {
25 HMIXER hMixer;
26 HICON hIconMuted;
27 HICON hIconUnMuted;
28 HICON hIconNoHW;
29
30 LONG muteVal;
31 DWORD muteControlID;
32
33 DWORD volumeControlID;
34 DWORD volumeChannels;
35 DWORD volumeMinimum;
36 DWORD volumeMaximum;
37 DWORD volumeStep;
38
39 DWORD maxVolume;
40 PMIXERCONTROLDETAILS_UNSIGNED volumeInitialValues;
41 PMIXERCONTROLDETAILS_UNSIGNED volumePreviousValues;
42 PMIXERCONTROLDETAILS_UNSIGNED volumeCurrentValues;
43
44 } GLOBAL_DATA, *PGLOBAL_DATA;
45
46
47 static VOID
48 InitImageInfo(PIMGINFO ImgInfo)
49 {
50 BITMAP bitmap;
51
52 ZeroMemory(ImgInfo, sizeof(*ImgInfo));
53
54 ImgInfo->hBitmap = LoadImage(hApplet,
55 MAKEINTRESOURCE(IDB_SPEAKIMG),
56 IMAGE_BITMAP,
57 0,
58 0,
59 LR_DEFAULTCOLOR);
60
61 if (ImgInfo->hBitmap != NULL)
62 {
63 GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
64
65 ImgInfo->cxSource = bitmap.bmWidth;
66 ImgInfo->cySource = bitmap.bmHeight;
67 }
68 }
69
70
71 VOID
72 GetMuteControl(PGLOBAL_DATA pGlobalData)
73 {
74 MIXERLINE mxln;
75 MIXERCONTROL mxc;
76 MIXERLINECONTROLS mxlctrl;
77
78 if (pGlobalData->hMixer == NULL)
79 return;
80
81 mxln.cbStruct = sizeof(MIXERLINE);
82 mxln.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
83
84 if (mixerGetLineInfo((HMIXEROBJ)pGlobalData->hMixer, &mxln, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE)
85 != MMSYSERR_NOERROR) return;
86
87 mxlctrl.cbStruct = sizeof(MIXERLINECONTROLS);
88 mxlctrl.dwLineID = mxln.dwLineID;
89 mxlctrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
90 mxlctrl.cControls = 1;
91 mxlctrl.cbmxctrl = sizeof(MIXERCONTROL);
92 mxlctrl.pamxctrl = &mxc;
93
94 if (mixerGetLineControls((HMIXEROBJ)pGlobalData->hMixer, &mxlctrl, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE)
95 != MMSYSERR_NOERROR) return;
96
97 pGlobalData->muteControlID = mxc.dwControlID;
98 }
99
100
101 VOID
102 GetMuteState(PGLOBAL_DATA pGlobalData)
103 {
104 MIXERCONTROLDETAILS_BOOLEAN mxcdMute;
105 MIXERCONTROLDETAILS mxcd;
106
107 if (pGlobalData->hMixer == NULL)
108 return;
109
110 mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
111 mxcd.dwControlID = pGlobalData->muteControlID;
112 mxcd.cChannels = 1;
113 mxcd.cMultipleItems = 0;
114 mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
115 mxcd.paDetails = &mxcdMute;
116
117 if (mixerGetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
118 != MMSYSERR_NOERROR)
119 return;
120
121 pGlobalData->muteVal = mxcdMute.fValue;
122 }
123
124
125 VOID
126 SwitchMuteState(PGLOBAL_DATA pGlobalData)
127 {
128 MIXERCONTROLDETAILS_BOOLEAN mxcdMute;
129 MIXERCONTROLDETAILS mxcd;
130
131 mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
132 mxcd.dwControlID = pGlobalData->muteControlID;
133 mxcd.cChannels = 1;
134 mxcd.cMultipleItems = 0;
135 mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
136 mxcd.paDetails = &mxcdMute;
137
138 mxcdMute.fValue = !pGlobalData->muteVal;
139 if (mixerSetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE)
140 != MMSYSERR_NOERROR)
141 return;
142
143 pGlobalData->muteVal = mxcdMute.fValue;
144 }
145
146
147 VOID
148 GetVolumeControl(PGLOBAL_DATA pGlobalData)
149 {
150 MIXERLINE mxln;
151 MIXERCONTROL mxc;
152 MIXERLINECONTROLS mxlc;
153
154 if (pGlobalData->hMixer == NULL)
155 return;
156
157 mxln.cbStruct = sizeof(MIXERLINE);
158 mxln.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
159 if (mixerGetLineInfo((HMIXEROBJ)pGlobalData->hMixer, &mxln, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE)
160 != MMSYSERR_NOERROR)
161 return;
162
163 pGlobalData->volumeChannels = mxln.cChannels;
164
165 mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
166 mxlc.dwLineID = mxln.dwLineID;
167 mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
168 mxlc.cControls = 1;
169 mxlc.cbmxctrl = sizeof(MIXERCONTROL);
170 mxlc.pamxctrl = &mxc;
171 if (mixerGetLineControls((HMIXEROBJ)pGlobalData->hMixer, &mxlc, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE)
172 != MMSYSERR_NOERROR)
173 return;
174
175 pGlobalData->volumeMinimum = mxc.Bounds.dwMinimum;
176 pGlobalData->volumeMaximum = mxc.Bounds.dwMaximum;
177 pGlobalData->volumeControlID = mxc.dwControlID;
178 pGlobalData->volumeStep = (pGlobalData->volumeMaximum - pGlobalData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN);
179
180 pGlobalData->volumeInitialValues = HeapAlloc(GetProcessHeap(),
181 0,
182 mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
183 if (pGlobalData->volumeInitialValues == NULL)
184 return;
185
186 pGlobalData->volumePreviousValues = HeapAlloc(GetProcessHeap(),
187 0,
188 mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
189 if (pGlobalData->volumePreviousValues == NULL)
190 return;
191
192 pGlobalData->volumeCurrentValues = HeapAlloc(GetProcessHeap(),
193 0,
194 mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
195 if (pGlobalData->volumeCurrentValues == NULL)
196 return;
197 }
198
199
200 VOID
201 GetVolumeValue(
202 PGLOBAL_DATA pGlobalData,
203 BOOL bInit)
204 {
205 MIXERCONTROLDETAILS mxcd;
206 DWORD i;
207
208 if (pGlobalData->hMixer == NULL)
209 return;
210
211 mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
212 mxcd.dwControlID = pGlobalData->volumeControlID;
213 mxcd.cChannels = pGlobalData->volumeChannels;
214 mxcd.cMultipleItems = 0;
215 mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
216 mxcd.paDetails = pGlobalData->volumePreviousValues;
217
218 if (mixerGetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
219 != MMSYSERR_NOERROR)
220 return;
221
222 pGlobalData->maxVolume = 0;
223 for (i = 0; i < pGlobalData->volumeChannels; i++)
224 {
225 pGlobalData->volumeCurrentValues[i].dwValue = pGlobalData->volumePreviousValues[i].dwValue;
226
227 if (pGlobalData->volumePreviousValues[i].dwValue > pGlobalData->maxVolume)
228 pGlobalData->maxVolume = pGlobalData->volumePreviousValues[i].dwValue;
229
230 if (bInit)
231 pGlobalData->volumeInitialValues[i].dwValue = pGlobalData->volumeCurrentValues[i].dwValue;
232 }
233 }
234
235
236 VOID
237 SetVolumeValue(PGLOBAL_DATA pGlobalData,
238 DWORD dwPosition)
239 {
240 MIXERCONTROLDETAILS mxcd;
241 DWORD dwVolume, i;
242
243 if (pGlobalData->hMixer == NULL)
244 return;
245
246 if (dwPosition == VOLUME_MIN)
247 dwVolume = pGlobalData->volumeMinimum;
248 else if (dwPosition == VOLUME_MAX)
249 dwVolume = pGlobalData->volumeMaximum;
250 else
251 dwVolume = (dwPosition * pGlobalData->volumeStep) + pGlobalData->volumeMinimum;
252
253 for (i = 0; i < pGlobalData->volumeChannels; i++)
254 {
255 if (pGlobalData->volumePreviousValues[i].dwValue == pGlobalData->maxVolume)
256 {
257 pGlobalData->volumeCurrentValues[i].dwValue = dwVolume;
258 }
259 else
260 {
261 pGlobalData->volumeCurrentValues[i].dwValue =
262 pGlobalData->volumePreviousValues[i].dwValue * dwVolume / pGlobalData-> maxVolume;
263 }
264 }
265
266 mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
267 mxcd.dwControlID = pGlobalData->volumeControlID;
268 mxcd.cChannels = pGlobalData->volumeChannels;
269 mxcd.cMultipleItems = 0;
270 mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
271 mxcd.paDetails = pGlobalData->volumeCurrentValues;
272
273 if (mixerSetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE)
274 != MMSYSERR_NOERROR)
275 return;
276 }
277
278
279 static
280 VOID
281 RestoreVolumeValue(
282 PGLOBAL_DATA pGlobalData)
283 {
284 MIXERCONTROLDETAILS mxcd;
285
286 if (pGlobalData->hMixer == NULL)
287 return;
288
289 mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
290 mxcd.dwControlID = pGlobalData->volumeControlID;
291 mxcd.cChannels = pGlobalData->volumeChannels;
292 mxcd.cMultipleItems = 0;
293 mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
294 mxcd.paDetails = pGlobalData->volumeInitialValues;
295
296 mixerSetControlDetails((HMIXEROBJ)pGlobalData->hMixer,
297 &mxcd,
298 MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);
299 }
300
301
302 static
303 VOID
304 SetSystrayVolumeIconState(BOOL bEnabled)
305 {
306 HWND hwndTaskBar;
307
308 hwndTaskBar = FindWindowW(L"SystemTray_Main", NULL);
309 if (hwndTaskBar == NULL)
310 return;
311
312 SendMessageW(hwndTaskBar, WM_USER + 220, 4, bEnabled);
313 }
314
315 static
316 BOOL
317 GetSystrayVolumeIconState(VOID)
318 {
319 HWND hwndTaskBar;
320
321 hwndTaskBar = FindWindowW(L"SystemTray_Main", NULL);
322 if (hwndTaskBar == NULL)
323 {
324 return FALSE;
325 }
326
327 return (BOOL)SendMessageW(hwndTaskBar, WM_USER + 221, 4, 0);
328 }
329
330 VOID
331 InitVolumeControls(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
332 {
333 UINT NumMixers;
334 MIXERCAPS mxc;
335 TCHAR szNoDevices[256];
336
337 LoadString(hApplet, IDS_NO_DEVICES, szNoDevices, _countof(szNoDevices));
338
339 SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(VOLUME_MIN, VOLUME_MAX));
340 SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETTICFREQ, VOLUME_TICFREQ, 0);
341 SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPAGESIZE, 0, VOLUME_PAGESIZE);
342
343 NumMixers = mixerGetNumDevs();
344 if (!NumMixers)
345 {
346 EnableWindow(GetDlgItem(hwndDlg, IDC_VOLUME_TRACKBAR), FALSE);
347 EnableWindow(GetDlgItem(hwndDlg, IDC_VOLUME_LOW), FALSE);
348 EnableWindow(GetDlgItem(hwndDlg, IDC_VOLUME_HIGH), FALSE);
349 EnableWindow(GetDlgItem(hwndDlg, IDC_MUTE_CHECKBOX), FALSE);
350 EnableWindow(GetDlgItem(hwndDlg, IDC_ICON_IN_TASKBAR), FALSE);
351 EnableWindow(GetDlgItem(hwndDlg, IDC_ADVANCED_BTN), FALSE);
352 EnableWindow(GetDlgItem(hwndDlg, IDC_SPEAKER_VOL_BTN), FALSE);
353 EnableWindow(GetDlgItem(hwndDlg, IDC_ADVANCED2_BTN), FALSE);
354 SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconNoHW);
355 SetDlgItemText(hwndDlg, IDC_DEVICE_NAME, szNoDevices);
356 return;
357 }
358
359 if (mixerOpen(&pGlobalData->hMixer, 0, PtrToUlong(hwndDlg), 0, MIXER_OBJECTF_MIXER | CALLBACK_WINDOW) != MMSYSERR_NOERROR)
360 {
361 MessageBox(hwndDlg, _T("Cannot open mixer"), NULL, MB_OK);
362 return;
363 }
364
365 ZeroMemory(&mxc, sizeof(MIXERCAPS));
366 if (mixerGetDevCaps(PtrToUint(pGlobalData->hMixer), &mxc, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR)
367 {
368 MessageBox(hwndDlg, _T("mixerGetDevCaps failed"), NULL, MB_OK);
369 return;
370 }
371
372 CheckDlgButton(hwndDlg,
373 IDC_ICON_IN_TASKBAR,
374 GetSystrayVolumeIconState() ? BST_CHECKED : BST_UNCHECKED);
375
376 GetMuteControl(pGlobalData);
377 GetMuteState(pGlobalData);
378 if (pGlobalData->muteVal)
379 {
380 SendDlgItemMessage(hwndDlg, IDC_MUTE_CHECKBOX, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
381 SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconMuted);
382 }
383 else
384 {
385 SendDlgItemMessage(hwndDlg, IDC_MUTE_CHECKBOX, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
386 SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconUnMuted);
387 }
388
389 GetVolumeControl(pGlobalData);
390 GetVolumeValue(pGlobalData, TRUE);
391
392 SendDlgItemMessage(hwndDlg, IDC_DEVICE_NAME, WM_SETTEXT, 0, (LPARAM)mxc.szPname);
393 SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pGlobalData->maxVolume - pGlobalData->volumeMinimum) / pGlobalData->volumeStep);
394 }
395
396 VOID
397 SaveData(HWND hwndDlg)
398 {
399 BOOL bShowIcon;
400
401 bShowIcon = (IsDlgButtonChecked(hwndDlg, IDC_ICON_IN_TASKBAR) == BST_CHECKED);
402
403 SetSystrayVolumeIconState(bShowIcon);
404 }
405
406 VOID
407 LaunchSoundControl(HWND hwndDlg)
408 {
409 if ((INT_PTR)ShellExecuteW(NULL, L"open", L"sndvol32.exe", NULL, NULL, SW_SHOWNORMAL) > 32)
410 return;
411 MessageBox(hwndDlg, _T("Cannot run sndvol32.exe"), NULL, MB_OK);
412 }
413
414 /* Volume property page dialog callback */
415 //static INT_PTR CALLBACK
416 INT_PTR CALLBACK
417 VolumeDlgProc(HWND hwndDlg,
418 UINT uMsg,
419 WPARAM wParam,
420 LPARAM lParam)
421 {
422 static IMGINFO ImgInfo;
423 PGLOBAL_DATA pGlobalData;
424 UNREFERENCED_PARAMETER(lParam);
425 UNREFERENCED_PARAMETER(wParam);
426
427 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
428
429 switch(uMsg)
430 {
431 case MM_MIXM_LINE_CHANGE:
432 {
433 GetMuteState(pGlobalData);
434 if (pGlobalData->muteVal)
435 {
436 SendDlgItemMessage(hwndDlg, IDC_MUTE_CHECKBOX, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
437 SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconMuted);
438 }
439 else
440 {
441 SendDlgItemMessage(hwndDlg, IDC_MUTE_CHECKBOX, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
442 SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconUnMuted);
443 }
444 break;
445 }
446 case MM_MIXM_CONTROL_CHANGE:
447 {
448 GetVolumeValue(pGlobalData, FALSE);
449 SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pGlobalData->maxVolume - pGlobalData->volumeMinimum) / pGlobalData->volumeStep);
450 break;
451 }
452 case WM_INITDIALOG:
453 {
454 pGlobalData = (GLOBAL_DATA*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBAL_DATA));
455 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
456
457 pGlobalData->hIconUnMuted = LoadImage(hApplet, MAKEINTRESOURCE(IDI_CPLICON), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
458 pGlobalData->hIconMuted = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MUTED_ICON), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
459 pGlobalData->hIconNoHW = LoadImage(hApplet, MAKEINTRESOURCE(IDI_NO_HW), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
460
461 InitImageInfo(&ImgInfo);
462 InitVolumeControls(hwndDlg, pGlobalData);
463 break;
464 }
465
466 case WM_DRAWITEM:
467 {
468 LPDRAWITEMSTRUCT lpDrawItem;
469 lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
470 if(lpDrawItem->CtlID == IDC_SPEAKIMG)
471 {
472 HDC hdcMem;
473 LONG left;
474
475 /* Position image in centre of dialog */
476 left = (lpDrawItem->rcItem.right - ImgInfo.cxSource) / 2;
477
478 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
479 if (hdcMem != NULL)
480 {
481 SelectObject(hdcMem, ImgInfo.hBitmap);
482 BitBlt(lpDrawItem->hDC,
483 left,
484 lpDrawItem->rcItem.top,
485 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
486 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
487 hdcMem,
488 0,
489 0,
490 SRCCOPY);
491 DeleteDC(hdcMem);
492 }
493 }
494 break;
495 }
496
497 case WM_COMMAND:
498 {
499 switch (LOWORD(wParam))
500 {
501 case IDC_MUTE_CHECKBOX:
502 if (HIWORD(wParam) == BN_CLICKED)
503 {
504 SwitchMuteState(pGlobalData);
505 if (pGlobalData->muteVal)
506 {
507 SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconMuted);
508 }
509 else
510 {
511 SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconUnMuted);
512 }
513
514 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
515 }
516 break;
517
518 case IDC_ICON_IN_TASKBAR:
519 if (HIWORD(wParam) == BN_CLICKED)
520 {
521 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
522 }
523 break;
524
525 case IDC_ADVANCED_BTN:
526 LaunchSoundControl(hwndDlg);
527 break;
528
529 case IDC_SPEAKER_VOL_BTN:
530 SpeakerVolume(hwndDlg);
531 break;
532 }
533 break;
534 }
535
536 case WM_HSCROLL:
537 {
538 HWND hVolumeTrackbar = GetDlgItem(hwndDlg, IDC_VOLUME_TRACKBAR);
539 if (hVolumeTrackbar == (HWND)lParam)
540 {
541 switch (LOWORD(wParam))
542 {
543 case TB_THUMBPOSITION:
544 break;
545
546 case TB_ENDTRACK:
547 PlaySound((LPCTSTR)SND_ALIAS_SYSTEMDEFAULT, NULL, SND_ALIAS_ID | SND_ASYNC);
548 break;
549
550 default:
551 SetVolumeValue(pGlobalData,
552 (DWORD)SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_GETPOS, 0, 0));
553 break;
554 }
555 }
556 break;
557 }
558
559 case WM_DESTROY:
560 if (pGlobalData)
561 {
562 if (pGlobalData->volumeCurrentValues)
563 HeapFree(GetProcessHeap(), 0, pGlobalData->volumeCurrentValues);
564
565 if (pGlobalData->volumePreviousValues)
566 HeapFree(GetProcessHeap(), 0, pGlobalData->volumePreviousValues);
567
568 if (pGlobalData->volumeInitialValues)
569 HeapFree(GetProcessHeap(), 0, pGlobalData->volumeInitialValues);
570
571 mixerClose(pGlobalData->hMixer);
572 DestroyIcon(pGlobalData->hIconMuted);
573 DestroyIcon(pGlobalData->hIconUnMuted);
574 DestroyIcon(pGlobalData->hIconNoHW);
575 HeapFree(GetProcessHeap(), 0, pGlobalData);
576 }
577 break;
578
579 case WM_NOTIFY:
580 switch (((LPNMHDR)lParam)->code)
581 {
582 case PSN_APPLY:
583 SaveData(hwndDlg);
584 break;
585
586 case PSN_RESET:
587 RestoreVolumeValue(pGlobalData);
588 break;
589 }
590 return TRUE;
591 }
592
593 return FALSE;
594 }