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