[SNDVOL32] Disable the Mute checkbox for all lines that do not have a mute switch...
[reactos.git] / base / applications / sndvol32 / dialog.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Sound Volume Control
4 * FILE: base/applications/sndvol32/dialog.c
5 * PROGRAMMERS: Johannes Anderwald
6 */
7
8 #include "sndvol32.h"
9
10
11 VOID
12 ConvertRect(LPRECT lpRect, UINT xBaseUnit, UINT yBaseUnit)
13 {
14 lpRect->left = MulDiv(lpRect->left, xBaseUnit, 4);
15 lpRect->right = MulDiv(lpRect->right, xBaseUnit, 4);
16 lpRect->top = MulDiv(lpRect->top, yBaseUnit, 8);
17 lpRect->bottom = MulDiv(lpRect->bottom, yBaseUnit, 8);
18 }
19
20 LPVOID
21 LoadDialogResource(
22 IN HMODULE hModule,
23 IN LPCWSTR ResourceName,
24 OUT LPDWORD ResourceLength)
25 {
26 HRSRC hSrc;
27 HGLOBAL hRes;
28 PVOID Result;
29
30 /* find resource */
31 hSrc = FindResourceW(hModule, ResourceName, (LPCWSTR)RT_DIALOG);
32
33 if (!hSrc)
34 {
35 /* failed to find resource */
36 return NULL;
37 }
38
39 /* now load the resource */
40 hRes = LoadResource(hAppInstance, hSrc);
41 if (!hRes)
42 {
43 /* failed to load resource */
44 return NULL;
45 }
46
47 /* now lock the resource */
48 Result = LockResource(hRes);
49
50 if (!Result)
51 {
52 /* failed to lock resource */
53 return NULL;
54 }
55
56 if (ResourceLength)
57 {
58 /* store output length */
59 *ResourceLength = SizeofResource(hAppInstance, hSrc);
60 }
61
62 /* done */
63 return Result;
64 }
65
66 LPWORD
67 AddDialogControl(
68 IN HWND hwndDialog,
69 OUT HWND *OutWnd,
70 IN LPRECT DialogOffset,
71 IN PDLGITEMTEMPLATE DialogItem,
72 IN DWORD DialogIdMultiplier,
73 IN HFONT hFont,
74 IN UINT xBaseUnit,
75 IN UINT yBaseUnit,
76 IN UINT MixerId)
77 {
78 RECT rect;
79 LPWORD Offset;
80 LPWSTR ClassName, WindowName = NULL;
81 HWND hwnd;
82 DWORD wID;
83 INT nSteps, i;
84
85 /* initialize client rectangle */
86 rect.left = DialogItem->x;
87 rect.top = DialogItem->y;
88 rect.right = DialogItem->x + DialogItem->cx;
89 rect.bottom = DialogItem->y + DialogItem->cy;
90
91 /* Convert Dialog units to pixes */
92 ConvertRect(&rect, xBaseUnit, yBaseUnit);
93
94 rect.left += DialogOffset->left;
95 rect.right += DialogOffset->left;
96 rect.top += DialogOffset->top;
97 rect.bottom += DialogOffset->top;
98
99 /* move offset after dialog item */
100 Offset = (LPWORD)(DialogItem + 1);
101
102 if (*Offset == 0xFFFF)
103 {
104 /* class is encoded as type */
105 Offset++;
106
107 /* get control type */
108 switch(*Offset)
109 {
110 case 0x80:
111 ClassName = L"button";
112 WindowName = (LPWSTR)(Offset + 1);
113 break ;
114 case 0x82:
115 ClassName = L"static";
116 WindowName = (LPWSTR)(Offset + 1);
117 break;
118 default:
119 /* FIXME */
120 assert(0);
121 ClassName = NULL;
122 }
123 }
124 else
125 {
126 /* class name is encoded as string */
127 ClassName = (LPWSTR)Offset;
128
129 /* move offset to the end of class string */
130 Offset += wcslen(ClassName);
131
132 /* get window name */
133 WindowName = (LPWSTR)(Offset + 1);
134 }
135
136 /* move offset past class type/string */
137 Offset++;
138
139 if (DialogItem->id == MAXWORD)
140 {
141 /* id is not important */
142 wID = DialogItem->id;
143 }
144 else
145 {
146 /* calculate id */
147 wID = DialogItem->id * (DialogIdMultiplier + 1);
148
149 }
150
151 /* now create the window */
152 hwnd = CreateWindowExW(DialogItem->dwExtendedStyle,
153 ClassName,
154 WindowName,
155 DialogItem->style,
156 rect.left,
157 rect.top,
158 rect.right - rect.left,
159 rect.bottom - rect.top,
160 hwndDialog,
161 UlongToPtr(wID),
162 hAppInstance,
163 NULL);
164
165 /* sanity check */
166 assert(hwnd);
167
168 /* store window */
169 *OutWnd = hwnd;
170
171 /* check if this the track bar */
172 if (!wcsicmp(ClassName, L"msctls_trackbar32"))
173 {
174 if (DialogItem->style & TBS_VERT)
175 {
176 /* Vertical trackbar: Volume */
177
178 /* set up range */
179 SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(VOLUME_MIN, VOLUME_MAX));
180
181 /* set up page size */
182 SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)VOLUME_PAGE_SIZE);
183
184 /* set position */
185 SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0);
186
187 /* Calculate and set ticks */
188 nSteps = (VOLUME_MAX / (VOLUME_TICKS + 1));
189 if (VOLUME_MAX % (VOLUME_TICKS + 1) != 0)
190 nSteps++;
191 for (i = nSteps; i < VOLUME_MAX; i += nSteps)
192 SendMessage(hwnd, TBM_SETTIC, 0, (LPARAM)i);
193 }
194 else
195 {
196 /* Horizontal trackbar: Balance */
197
198 /* set up range */
199 SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, BALANCE_STEPS));
200
201 /* set up page size */
202 SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)BALANCE_PAGE_SIZE);
203
204 /* set position */
205 SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)BALANCE_STEPS / 2);
206
207 /* Calculate and set ticks */
208 nSteps = (BALANCE_STEPS / (BALANCE_TICKS + 1));
209 if (BALANCE_STEPS % (BALANCE_TICKS + 1) != 0)
210 nSteps++;
211 for (i = nSteps; i < BALANCE_STEPS; i += nSteps)
212 SendMessage(hwnd, TBM_SETTIC, 0, (LPARAM)i);
213 }
214 }
215 else if (!wcsicmp(ClassName, L"static"))
216 {
217 /* Set font */
218 SendMessageW(hwnd, WM_SETFONT, (WPARAM)hFont, TRUE);
219 }
220 else if (!wcsicmp(ClassName, L"button"))
221 {
222 if (DialogItem->style & BS_AUTOCHECKBOX)
223 {
224 if (MixerId == PLAY_MIXER)
225 {
226 /* Disable checkboxes by default, if we are in play mode */
227 EnableWindow(hwnd, FALSE);
228 }
229 }
230
231 /* Set font */
232 SendMessageW(hwnd, WM_SETFONT, (WPARAM)hFont, TRUE);
233 }
234
235 //ShowWindow(hwnd, SW_SHOWNORMAL);
236
237 if (WindowName != NULL)
238 {
239 /* move offset past window name */
240 Offset += wcslen(WindowName) + 1;
241 }
242
243 /* check if there is additional data */
244 if (*Offset == 0)
245 {
246 /* no additional data */
247 Offset++;
248 }
249 else
250 {
251 /* FIXME: Determine whether this should be "Offset += 1 + *Offset" to explicitly skip the data count too. */
252 /* skip past additional data */
253 Offset += *Offset;
254 }
255
256 /* make sure next template is word-aligned */
257 Offset = (LPWORD)(((ULONG_PTR)Offset + 3) & ~3);
258
259 /* done */
260 return Offset;
261 }
262
263 VOID
264 LoadDialogControls(
265 IN PMIXER_WINDOW MixerWindow,
266 LPRECT DialogOffset,
267 WORD ItemCount,
268 PDLGITEMTEMPLATE DialogItem,
269 DWORD DialogIdMultiplier,
270 UINT xBaseUnit,
271 UINT yBaseUnit)
272 {
273 LPWORD Offset;
274 WORD Index;
275
276 /* sanity check */
277 assert(ItemCount);
278
279 if (MixerWindow->Window)
280 MixerWindow->Window = (HWND*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerWindow->Window, (MixerWindow->WindowCount + ItemCount) * sizeof(HWND));
281 else
282 MixerWindow->Window = (HWND*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ItemCount * sizeof(HWND));
283 if (!MixerWindow->Window)
284 {
285 /* no memory */
286 return;
287 }
288
289 /* enumerate now all controls */
290 for (Index = 0; Index < ItemCount; Index++)
291 {
292 /* add controls */
293 Offset = AddDialogControl(MixerWindow->hWnd,
294 &MixerWindow->Window[MixerWindow->WindowCount],
295 DialogOffset,
296 DialogItem,
297 DialogIdMultiplier,
298 MixerWindow->hFont,
299 xBaseUnit,
300 yBaseUnit,
301 MixerWindow->MixerId);
302
303 /* sanity check */
304 assert(Offset);
305
306 /* move dialog item to new offset */
307 DialogItem =(PDLGITEMTEMPLATE)Offset;
308
309 /* increment window count */
310 MixerWindow->WindowCount++;
311 }
312 }
313
314 VOID
315 LoadDialog(
316 IN HMODULE hModule,
317 IN PMIXER_WINDOW MixerWindow,
318 IN LPCWSTR DialogResId,
319 IN DWORD Index)
320 {
321 LPDLGTEMPLATE DlgTemplate;
322 PDLGITEMTEMPLATE DlgItem;
323 RECT dialogRect;
324 LPWORD Offset;
325 WORD FontSize;
326 WCHAR FontName[100];
327 WORD Length;
328 int width;
329
330 DWORD units = GetDialogBaseUnits();
331 UINT xBaseUnit = LOWORD(units);
332 UINT yBaseUnit = HIWORD(units);
333
334 /* first load the dialog resource */
335 DlgTemplate = (LPDLGTEMPLATE)LoadDialogResource(hModule, DialogResId, NULL);
336 if (!DlgTemplate)
337 {
338 /* failed to load resource */
339 return;
340 }
341
342 /* Now walk past the dialog header */
343 Offset = (LPWORD)(DlgTemplate + 1);
344
345 /* FIXME: support menu */
346 assert(*Offset == 0);
347 Offset++;
348
349 /* FIXME: support classes */
350 assert(*Offset == 0);
351 Offset++;
352
353 /* FIXME: support titles */
354 assert(*Offset == 0);
355 Offset++;
356
357 /* get font size */
358 FontSize = *Offset;
359 Offset++;
360
361 /* calculate font length */
362 Length = wcslen((LPWSTR)Offset) + 1;
363 assert(Length < (sizeof(FontName) / sizeof(WCHAR)));
364
365 /* copy font */
366 wcscpy(FontName, (LPWSTR)Offset);
367
368 if (DlgTemplate->style & DS_SETFONT)
369 {
370 HDC hDC;
371
372 hDC = GetDC(0);
373
374 if (!MixerWindow->hFont)
375 {
376 int pixels = MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
377 MixerWindow->hFont = CreateFontW(-pixels, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, FontName);
378 }
379
380 if (MixerWindow->hFont)
381 {
382 SIZE charSize;
383 HFONT hOldFont;
384
385 hOldFont = SelectObject(hDC, MixerWindow->hFont);
386 charSize.cx = GdiGetCharDimensions(hDC, NULL, &charSize.cy);
387 if (charSize.cx)
388 {
389 xBaseUnit = charSize.cx;
390 yBaseUnit = charSize.cy;
391 }
392 SelectObject(hDC, hOldFont);
393 }
394 }
395
396 // assert(MixerWindow->hFont);
397
398 /* move offset after font name */
399 Offset += Length;
400
401 /* offset is now at first dialog item control */
402 DlgItem = (PDLGITEMTEMPLATE)Offset;
403
404 dialogRect.left = 0;
405 dialogRect.right = DlgTemplate->cx;
406 dialogRect.top = 0;
407 dialogRect.bottom = DlgTemplate->cy;
408
409 ConvertRect(&dialogRect, xBaseUnit, yBaseUnit);
410
411 width = dialogRect.right - dialogRect.left;
412
413 dialogRect.left += MixerWindow->rect.right;
414 dialogRect.right += MixerWindow->rect.right;
415 dialogRect.top += MixerWindow->rect.top;
416 dialogRect.bottom += MixerWindow->rect.top;
417
418 MixerWindow->rect.right += width;
419 if ((dialogRect.bottom - dialogRect.top) > (MixerWindow->rect.bottom - MixerWindow->rect.top))
420 MixerWindow->rect.bottom = MixerWindow->rect.top + dialogRect.bottom - dialogRect.top;
421
422 /* now add the controls */
423 LoadDialogControls(MixerWindow, &dialogRect, DlgTemplate->cdit, DlgItem, Index, xBaseUnit, yBaseUnit);
424 }
425
426 BOOL
427 CALLBACK
428 EnumConnectionsCallback(
429 PSND_MIXER Mixer,
430 DWORD LineID,
431 LPMIXERLINE Line,
432 PVOID Context)
433 {
434 WCHAR LineName[MIXER_LONG_NAME_CHARS];
435 DWORD Flags;
436 DWORD wID;
437 UINT ControlCount = 0, Index;
438 LPMIXERCONTROL Control = NULL;
439 HWND hDlgCtrl;
440 PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
441 PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
442
443 if (Line->cControls == 0)
444 return TRUE;
445
446 /* get line name */
447 if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
448 {
449 /* failed to get line name */
450 LineName[0] = L'\0';
451 }
452
453 pVolumeDetails = HeapAlloc(GetProcessHeap(),
454 0,
455 Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
456 if (pVolumeDetails == NULL)
457 goto done;
458
459 /* check if line is found in registry settings */
460 if (ReadLineConfig(PrefContext->DeviceName,
461 LineName,
462 Line->szName,
463 &Flags))
464 {
465 /* is it selected */
466 if (Flags != 0x4)
467 {
468 int dlgId;
469
470 if ((Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) ||
471 (Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES))
472 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_MASTER : IDD_NORMAL_MASTER;
473 else
474 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_LINE : IDD_NORMAL_LINE;
475
476 /* load dialog resource */
477 LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(dlgId), PrefContext->Count);
478
479 /* get id */
480 wID = (PrefContext->Count + 1) * IDC_LINE_NAME;
481
482 /* set line name */
483 SetDlgItemTextW(PrefContext->MixerWindow->hWnd, wID, Line->szName);
484
485 /* query controls */
486 if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) != FALSE)
487 {
488 /* now go through all controls and update their states */
489 for (Index = 0; Index < Line->cControls; Index++)
490 {
491 if ((Control[Index].dwControlType & MIXERCONTROL_CT_CLASS_MASK) == MIXERCONTROL_CT_CLASS_SWITCH)
492 {
493 MIXERCONTROLDETAILS_BOOLEAN Details;
494
495 /* get volume control details */
496 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
497 {
498 /* update dialog control */
499 wID = (PrefContext->Count + 1) * IDC_LINE_SWITCH;
500
501 /* get dialog control */
502 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
503
504 if (hDlgCtrl != NULL)
505 {
506 /* Enable the 'Mute' checkbox, if we are in play mode */
507 if (Mixer->MixerId == PLAY_MIXER)
508 EnableWindow(hDlgCtrl, TRUE);
509
510 /* check state */
511 if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != Details.fValue)
512 {
513 /* update control state */
514 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)Details.fValue, 0);
515 }
516 }
517 }
518 }
519 else if ((Control[Index].dwControlType & MIXERCONTROL_CT_CLASS_MASK) == MIXERCONTROL_CT_CLASS_FADER)
520 {
521 /* get volume control details */
522 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
523 {
524 /* update dialog control */
525 DWORD volumePosition, volumeStep, maxVolume, i;
526 DWORD balancePosition, balanceStep;
527
528 volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
529
530 maxVolume = 0;
531 for (i = 0; i < Line->cChannels; i++)
532 {
533 if (pVolumeDetails[i].dwValue > maxVolume)
534 maxVolume = pVolumeDetails[i].dwValue;
535 }
536
537 volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
538
539 if (Line->cChannels == 1)
540 {
541 balancePosition = BALANCE_CENTER;
542 }
543 else if (Line->cChannels == 2)
544 {
545 if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
546 {
547 balancePosition = BALANCE_CENTER;
548 }
549 else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
550 {
551 balancePosition = BALANCE_RIGHT;
552 }
553 else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
554 {
555 balancePosition = BALANCE_LEFT;
556 }
557 else
558 {
559 balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
560
561 if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
562 {
563 balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
564 balancePosition = BALANCE_RIGHT - balancePosition;
565 }
566 else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
567 {
568 balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
569 balancePosition = BALANCE_LEFT + balancePosition;
570 }
571 }
572 }
573
574 /* Set the volume trackbar */
575 wID = (PrefContext->Count + 1) * IDC_LINE_SLIDER_VERT;
576
577 /* get dialog control */
578 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
579
580 if (hDlgCtrl != NULL)
581 {
582 /* check state */
583 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
584
585 if (OldPosition != (VOLUME_MAX - volumePosition))
586 {
587 /* update control state */
588 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - volumePosition);
589 }
590 }
591
592 if (Line->cChannels == 1)
593 {
594 /* Disable the balance trackbar for mono channels */
595 wID = (PrefContext->Count + 1) * IDC_LINE_SLIDER_HORZ;
596
597 /* get dialog control */
598 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
599 if (hDlgCtrl != NULL)
600 {
601 EnableWindow(hDlgCtrl, FALSE);
602 }
603 }
604 else if (Line->cChannels == 2)
605 {
606 /* Set the balance trackbar */
607 wID = (PrefContext->Count + 1) * IDC_LINE_SLIDER_HORZ;
608
609 /* get dialog control */
610 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
611
612 if (hDlgCtrl != NULL)
613 {
614 /* check state */
615 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
616
617 if (OldPosition != balancePosition)
618 {
619 /* update control state */
620 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, balancePosition);
621 }
622 }
623 }
624 }
625 }
626 }
627
628 /* free controls */
629 HeapFree(GetProcessHeap(), 0, Control);
630 }
631
632 /* increment dialog count */
633 PrefContext->Count++;
634 }
635 }
636
637 done:
638 /* Free the volume details */
639 if (pVolumeDetails)
640 HeapFree(GetProcessHeap(), 0, pVolumeDetails);
641
642 return TRUE;
643 }
644
645 VOID
646 LoadDialogCtrls(
647 PPREFERENCES_CONTEXT PrefContext)
648 {
649 HWND hDlgCtrl;
650 RECT statusRect;
651
652 /* set dialog count to zero */
653 PrefContext->Count = 0;
654
655 SetRectEmpty(&PrefContext->MixerWindow->rect);
656
657 /* enumerate controls */
658 SndMixerEnumConnections(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, EnumConnectionsCallback, (PVOID)PrefContext);
659
660 if (PrefContext->MixerWindow->hStatusBar)
661 {
662 GetWindowRect(PrefContext->MixerWindow->hStatusBar, &statusRect);
663 PrefContext->MixerWindow->rect.bottom += (statusRect.bottom - statusRect.top);
664 }
665
666 /* now move the window */
667 AdjustWindowRect(&PrefContext->MixerWindow->rect, WS_DLGFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, TRUE);
668 SetWindowPos(PrefContext->MixerWindow->hWnd, HWND_TOP, PrefContext->MixerWindow->rect.left, PrefContext->MixerWindow->rect.top, PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left, PrefContext->MixerWindow->rect.bottom - PrefContext->MixerWindow->rect.top, SWP_NOMOVE | SWP_NOZORDER);
669
670 /* get last line separator */
671 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, IDC_LINE_SEP * PrefContext->Count);
672
673 if (hDlgCtrl != NULL)
674 {
675 /* hide last separator */
676 ShowWindow(hDlgCtrl, SW_HIDE);
677 }
678 }
679
680 VOID
681 UpdateDialogLineSwitchControl(
682 PPREFERENCES_CONTEXT PrefContext,
683 LPMIXERLINE Line,
684 LONG fValue)
685 {
686 DWORD Index;
687 DWORD wID;
688 HWND hDlgCtrl;
689 WCHAR LineName[MIXER_LONG_NAME_CHARS];
690
691 /* find the index of this line */
692 for (Index = 0; Index < PrefContext->Count; Index++)
693 {
694 /* get id */
695 wID = (Index + 1) * IDC_LINE_NAME;
696
697 if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
698 {
699 /* failed to retrieve id */
700 continue;
701 }
702
703 /* check if the line name matches */
704 if (!wcsicmp(LineName, Line->szName))
705 {
706 /* found matching line name */
707 wID = (Index + 1) * IDC_LINE_SWITCH;
708
709 /* get dialog control */
710 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
711
712 if (hDlgCtrl != NULL)
713 {
714 /* check state */
715 if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != fValue)
716 {
717 /* update control state */
718 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)fValue, 0);
719 }
720 }
721 break;
722 }
723 }
724 }
725
726 VOID
727 UpdateDialogLineSliderControl(
728 PPREFERENCES_CONTEXT PrefContext,
729 LPMIXERLINE Line,
730 DWORD dwDialogID,
731 DWORD Position)
732 {
733 DWORD Index;
734 DWORD wID;
735 HWND hDlgCtrl;
736 WCHAR LineName[MIXER_LONG_NAME_CHARS];
737
738 /* find the index of this line */
739 for (Index = 0; Index < PrefContext->Count; Index++)
740 {
741 /* get id */
742 wID = (Index + 1) * IDC_LINE_NAME;
743
744 if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
745 {
746 /* failed to retrieve id */
747 continue;
748 }
749
750 /* check if the line name matches */
751 if (!wcsicmp(LineName, Line->szName))
752 {
753 /* found matching line name */
754 wID = (Index + 1) * dwDialogID;
755
756 /* get dialog control */
757 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
758
759 if (hDlgCtrl != NULL)
760 {
761 /* check state */
762 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
763 if (OldPosition != Position)
764 {
765 /* update control state */
766 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, Position);
767 }
768 }
769 break;
770 }
771 }
772 }