[SNDVOL32] Fix the window height issue when the line selection changes and implement...
[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 /* Disable the volume trackbar by default */
179 EnableWindow(hwnd, FALSE);
180
181 /* set up range */
182 SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(VOLUME_MIN, VOLUME_MAX));
183
184 /* set up page size */
185 SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)VOLUME_PAGE_SIZE);
186
187 /* set position */
188 SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0);
189
190 /* Calculate and set ticks */
191 nSteps = (VOLUME_MAX / (VOLUME_TICKS + 1));
192 if (VOLUME_MAX % (VOLUME_TICKS + 1) != 0)
193 nSteps++;
194 for (i = nSteps; i < VOLUME_MAX; i += nSteps)
195 SendMessage(hwnd, TBM_SETTIC, 0, (LPARAM)i);
196 }
197 else
198 {
199 /* Horizontal trackbar: Balance */
200
201 /* Disable the balance trackbar by default */
202 EnableWindow(hwnd, FALSE);
203
204 /* set up range */
205 SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, BALANCE_STEPS));
206
207 /* set up page size */
208 SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)BALANCE_PAGE_SIZE);
209
210 /* set position */
211 SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)BALANCE_STEPS / 2);
212
213 /* Calculate and set ticks */
214 nSteps = (BALANCE_STEPS / (BALANCE_TICKS + 1));
215 if (BALANCE_STEPS % (BALANCE_TICKS + 1) != 0)
216 nSteps++;
217 for (i = nSteps; i < BALANCE_STEPS; i += nSteps)
218 SendMessage(hwnd, TBM_SETTIC, 0, (LPARAM)i);
219 }
220 }
221 else if (!wcsicmp(ClassName, L"static"))
222 {
223 /* Set font */
224 SendMessageW(hwnd, WM_SETFONT, (WPARAM)hFont, TRUE);
225 }
226 else if (!wcsicmp(ClassName, L"button"))
227 {
228 if (DialogItem->id == IDC_LINE_SWITCH)
229 {
230 if (MixerId == PLAY_MIXER)
231 {
232 /* Disable checkboxes by default, if we are in play mode */
233 EnableWindow(hwnd, FALSE);
234 }
235 }
236 else if (DialogItem->id == IDC_LINE_ADVANCED)
237 {
238 ShowWindow(hwnd, SW_HIDE);
239 }
240
241 /* Set font */
242 SendMessageW(hwnd, WM_SETFONT, (WPARAM)hFont, TRUE);
243 }
244
245 if (WindowName != NULL)
246 {
247 /* move offset past window name */
248 Offset += wcslen(WindowName) + 1;
249 }
250
251 /* check if there is additional data */
252 if (*Offset == 0)
253 {
254 /* no additional data */
255 Offset++;
256 }
257 else
258 {
259 /* FIXME: Determine whether this should be "Offset += 1 + *Offset" to explicitly skip the data count too. */
260 /* skip past additional data */
261 Offset += *Offset;
262 }
263
264 /* make sure next template is word-aligned */
265 Offset = (LPWORD)(((ULONG_PTR)Offset + 3) & ~3);
266
267 /* done */
268 return Offset;
269 }
270
271 VOID
272 LoadDialogControls(
273 IN PMIXER_WINDOW MixerWindow,
274 LPRECT DialogOffset,
275 WORD ItemCount,
276 PDLGITEMTEMPLATE DialogItem,
277 DWORD DialogIdMultiplier,
278 UINT xBaseUnit,
279 UINT yBaseUnit)
280 {
281 LPWORD Offset;
282 WORD Index;
283
284 /* sanity check */
285 assert(ItemCount);
286
287 if (MixerWindow->Window)
288 MixerWindow->Window = (HWND*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerWindow->Window, (MixerWindow->WindowCount + ItemCount) * sizeof(HWND));
289 else
290 MixerWindow->Window = (HWND*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ItemCount * sizeof(HWND));
291 if (!MixerWindow->Window)
292 {
293 /* no memory */
294 return;
295 }
296
297 /* enumerate now all controls */
298 for (Index = 0; Index < ItemCount; Index++)
299 {
300 /* add controls */
301 Offset = AddDialogControl(MixerWindow->hWnd,
302 &MixerWindow->Window[MixerWindow->WindowCount],
303 DialogOffset,
304 DialogItem,
305 DialogIdMultiplier,
306 MixerWindow->hFont,
307 xBaseUnit,
308 yBaseUnit,
309 MixerWindow->MixerId);
310
311 /* sanity check */
312 assert(Offset);
313
314 /* move dialog item to new offset */
315 DialogItem =(PDLGITEMTEMPLATE)Offset;
316
317 /* increment window count */
318 MixerWindow->WindowCount++;
319 }
320 }
321
322 VOID
323 LoadDialog(
324 IN HMODULE hModule,
325 IN PMIXER_WINDOW MixerWindow,
326 IN LPCWSTR DialogResId,
327 IN DWORD Index)
328 {
329 LPDLGTEMPLATE DlgTemplate;
330 PDLGITEMTEMPLATE DlgItem;
331 RECT dialogRect;
332 LPWORD Offset;
333 WORD FontSize;
334 WCHAR FontName[100];
335 WORD Length;
336 int width;
337
338 DWORD units = GetDialogBaseUnits();
339 UINT xBaseUnit = LOWORD(units);
340 UINT yBaseUnit = HIWORD(units);
341
342 /* first load the dialog resource */
343 DlgTemplate = (LPDLGTEMPLATE)LoadDialogResource(hModule, DialogResId, NULL);
344 if (!DlgTemplate)
345 {
346 /* failed to load resource */
347 return;
348 }
349
350 /* Now walk past the dialog header */
351 Offset = (LPWORD)(DlgTemplate + 1);
352
353 /* FIXME: support menu */
354 assert(*Offset == 0);
355 Offset++;
356
357 /* FIXME: support classes */
358 assert(*Offset == 0);
359 Offset++;
360
361 /* FIXME: support titles */
362 assert(*Offset == 0);
363 Offset++;
364
365 /* get font size */
366 FontSize = *Offset;
367 Offset++;
368
369 /* calculate font length */
370 Length = wcslen((LPWSTR)Offset) + 1;
371 assert(Length < (sizeof(FontName) / sizeof(WCHAR)));
372
373 /* copy font */
374 wcscpy(FontName, (LPWSTR)Offset);
375
376 if (DlgTemplate->style & DS_SETFONT)
377 {
378 HDC hDC;
379
380 hDC = GetDC(0);
381
382 if (!MixerWindow->hFont)
383 {
384 int pixels = MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
385 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);
386 }
387
388 if (MixerWindow->hFont)
389 {
390 SIZE charSize;
391 HFONT hOldFont;
392
393 hOldFont = SelectObject(hDC, MixerWindow->hFont);
394 charSize.cx = GdiGetCharDimensions(hDC, NULL, &charSize.cy);
395 if (charSize.cx)
396 {
397 xBaseUnit = charSize.cx;
398 yBaseUnit = charSize.cy;
399 }
400 SelectObject(hDC, hOldFont);
401
402 MixerWindow->baseUnit.cx = charSize.cx;
403 MixerWindow->baseUnit.cy = charSize.cy;
404 }
405 }
406
407 // assert(MixerWindow->hFont);
408
409 /* move offset after font name */
410 Offset += Length;
411
412 /* offset is now at first dialog item control */
413 DlgItem = (PDLGITEMTEMPLATE)Offset;
414
415 dialogRect.left = 0;
416 dialogRect.right = DlgTemplate->cx;
417 dialogRect.top = 0;
418 dialogRect.bottom = DlgTemplate->cy;
419
420 ConvertRect(&dialogRect, xBaseUnit, yBaseUnit);
421
422 width = dialogRect.right - dialogRect.left;
423
424 dialogRect.left += MixerWindow->rect.right;
425 dialogRect.right += MixerWindow->rect.right;
426 dialogRect.top += MixerWindow->rect.top;
427 dialogRect.bottom += MixerWindow->rect.top;
428
429 MixerWindow->rect.right += width;
430 if ((dialogRect.bottom - dialogRect.top) > (MixerWindow->rect.bottom - MixerWindow->rect.top))
431 MixerWindow->rect.bottom = MixerWindow->rect.top + dialogRect.bottom - dialogRect.top;
432
433 /* now add the controls */
434 LoadDialogControls(MixerWindow, &dialogRect, DlgTemplate->cdit, DlgItem, Index, xBaseUnit, yBaseUnit);
435 }
436
437 BOOL
438 CALLBACK
439 EnumConnectionsCallback(
440 PSND_MIXER Mixer,
441 DWORD LineID,
442 LPMIXERLINE Line,
443 PVOID Context)
444 {
445 WCHAR LineName[MIXER_LONG_NAME_CHARS];
446 DWORD Flags;
447 DWORD wID;
448 UINT ControlCount = 0, Index;
449 LPMIXERCONTROL Control = NULL;
450 HWND hDlgCtrl;
451 PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
452 PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
453
454 if (Line->cControls == 0)
455 return TRUE;
456
457 /* get line name */
458 if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
459 {
460 /* failed to get line name */
461 LineName[0] = L'\0';
462 }
463
464 pVolumeDetails = HeapAlloc(GetProcessHeap(),
465 0,
466 Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
467 if (pVolumeDetails == NULL)
468 goto done;
469
470 /* check if line is found in registry settings */
471 if (ReadLineConfig(PrefContext->DeviceName,
472 LineName,
473 Line->szName,
474 &Flags))
475 {
476 /* is it selected */
477 if (Flags != 0x4)
478 {
479 int dlgId;
480
481 if ((Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) ||
482 (Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES))
483 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_MASTER : IDD_NORMAL_MASTER;
484 else
485 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_LINE : IDD_NORMAL_LINE;
486
487 /* load dialog resource */
488 LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(dlgId), PrefContext->MixerWindow->DialogCount);
489
490 /* get id */
491 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_NAME;
492
493 /* set line name */
494 SetDlgItemTextW(PrefContext->MixerWindow->hWnd, wID, Line->szName);
495
496 /* query controls */
497 if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) != FALSE)
498 {
499 /* now go through all controls and update their states */
500 for (Index = 0; Index < Line->cControls; Index++)
501 {
502 if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
503 {
504 MIXERCONTROLDETAILS_BOOLEAN Details;
505
506 /* get volume control details */
507 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
508 {
509 /* update dialog control */
510 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SWITCH;
511
512 /* get dialog control */
513 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
514
515 if (hDlgCtrl != NULL)
516 {
517 /* Enable the 'Mute' checkbox, if we are in play mode */
518 if (Mixer->MixerId == PLAY_MIXER)
519 EnableWindow(hDlgCtrl, TRUE);
520
521 /* check state */
522 if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != Details.fValue)
523 {
524 /* update control state */
525 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)Details.fValue, 0);
526 }
527 }
528 }
529 }
530 else if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
531 {
532 /* get volume control details */
533 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
534 {
535 /* update dialog control */
536 DWORD volumePosition, volumeStep, maxVolume, i;
537 DWORD balancePosition, balanceStep;
538
539 volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
540
541 maxVolume = 0;
542 for (i = 0; i < Line->cChannels; i++)
543 {
544 if (pVolumeDetails[i].dwValue > maxVolume)
545 maxVolume = pVolumeDetails[i].dwValue;
546 }
547
548 volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
549
550 if (Line->cChannels == 1)
551 {
552 balancePosition = BALANCE_CENTER;
553 }
554 else if (Line->cChannels == 2)
555 {
556 if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
557 {
558 balancePosition = BALANCE_CENTER;
559 }
560 else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
561 {
562 balancePosition = BALANCE_RIGHT;
563 }
564 else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
565 {
566 balancePosition = BALANCE_LEFT;
567 }
568 else
569 {
570 balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
571
572 if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
573 {
574 balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
575 balancePosition = BALANCE_RIGHT - balancePosition;
576 }
577 else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
578 {
579 balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
580 balancePosition = BALANCE_LEFT + balancePosition;
581 }
582 }
583 }
584
585 /* Set the volume trackbar */
586 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_VERT;
587
588 /* get dialog control */
589 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
590
591 if (hDlgCtrl != NULL)
592 {
593 /* check state */
594 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
595
596 /* Enable the volume trackbar */
597 EnableWindow(hDlgCtrl, TRUE);
598
599 if (OldPosition != (VOLUME_MAX - volumePosition))
600 {
601 /* update control state */
602 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - volumePosition);
603 }
604 }
605
606 if (Line->cChannels == 2)
607 {
608 /* Set the balance trackbar */
609 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_HORZ;
610
611 /* get dialog control */
612 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
613
614 if (hDlgCtrl != NULL)
615 {
616 /* check state */
617 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
618
619 /* Enable the balance trackbar */
620 EnableWindow(hDlgCtrl, TRUE);
621
622 if (OldPosition != balancePosition)
623 {
624 /* update control state */
625 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, balancePosition);
626 }
627 }
628 }
629 }
630 }
631 else
632 {
633 if (PrefContext->MixerWindow->Mode == NORMAL_MODE)
634 PrefContext->MixerWindow->bHasExtendedControls = TRUE;
635 }
636 }
637
638 /* free controls */
639 HeapFree(GetProcessHeap(), 0, Control);
640 }
641
642 /* increment dialog count */
643 PrefContext->MixerWindow->DialogCount++;
644 }
645 }
646
647 done:
648 /* Free the volume details */
649 if (pVolumeDetails)
650 HeapFree(GetProcessHeap(), 0, pVolumeDetails);
651
652 return TRUE;
653 }
654
655 VOID
656 LoadDialogCtrls(
657 PPREFERENCES_CONTEXT PrefContext)
658 {
659 HWND hDlgCtrl;
660 RECT statusRect;
661
662 /* set dialog count to zero */
663 PrefContext->MixerWindow->DialogCount = 0;
664
665 SetRectEmpty(&PrefContext->MixerWindow->rect);
666
667 /* enumerate controls */
668 SndMixerEnumConnections(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, EnumConnectionsCallback, (PVOID)PrefContext);
669
670 if (PrefContext->MixerWindow->bHasExtendedControls)
671 {
672 EnableMenuItem(GetMenu(PrefContext->MixerWindow->hWnd), IDM_ADVANCED_CONTROLS, MF_BYCOMMAND | MF_ENABLED);
673 }
674
675 if (PrefContext->MixerWindow->hStatusBar)
676 {
677 GetWindowRect(PrefContext->MixerWindow->hStatusBar, &statusRect);
678 PrefContext->MixerWindow->rect.bottom += (statusRect.bottom - statusRect.top);
679 }
680
681 /* now move the window */
682 AdjustWindowRect(&PrefContext->MixerWindow->rect, WS_DLGFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, TRUE);
683 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);
684
685 /* Move the status bar */
686 if (PrefContext->MixerWindow->hStatusBar)
687 {
688 SetWindowPos(PrefContext->MixerWindow->hStatusBar,
689 HWND_TOP,
690 statusRect.left,
691 PrefContext->MixerWindow->rect.bottom - (statusRect.bottom - statusRect.top),
692 PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left,
693 statusRect.bottom - statusRect.top,
694 SWP_NOZORDER);
695 }
696
697 /* Hide the last line separator */
698 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, IDC_LINE_SEP * PrefContext->MixerWindow->DialogCount /*PrefContext->Count*/);
699 if (hDlgCtrl != NULL)
700 {
701 ShowWindow(hDlgCtrl, SW_HIDE);
702 }
703 }
704
705 VOID
706 UpdateDialogLineSwitchControl(
707 PPREFERENCES_CONTEXT PrefContext,
708 LPMIXERLINE Line,
709 LONG fValue)
710 {
711 DWORD Index;
712 DWORD wID;
713 HWND hDlgCtrl;
714 WCHAR LineName[MIXER_LONG_NAME_CHARS];
715
716 /* find the index of this line */
717 for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++)
718 {
719 /* get id */
720 wID = (Index + 1) * IDC_LINE_NAME;
721
722 if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
723 {
724 /* failed to retrieve id */
725 continue;
726 }
727
728 /* check if the line name matches */
729 if (!wcsicmp(LineName, Line->szName))
730 {
731 /* found matching line name */
732 wID = (Index + 1) * IDC_LINE_SWITCH;
733
734 /* get dialog control */
735 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
736
737 if (hDlgCtrl != NULL)
738 {
739 /* check state */
740 if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != fValue)
741 {
742 /* update control state */
743 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)fValue, 0);
744 }
745 }
746 break;
747 }
748 }
749 }
750
751 VOID
752 UpdateDialogLineSliderControl(
753 PPREFERENCES_CONTEXT PrefContext,
754 LPMIXERLINE Line,
755 DWORD dwDialogID,
756 DWORD Position)
757 {
758 DWORD Index;
759 DWORD wID;
760 HWND hDlgCtrl;
761 WCHAR LineName[MIXER_LONG_NAME_CHARS];
762
763 /* find the index of this line */
764 for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++)
765 {
766 /* get id */
767 wID = (Index + 1) * IDC_LINE_NAME;
768
769 if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
770 {
771 /* failed to retrieve id */
772 continue;
773 }
774
775 /* check if the line name matches */
776 if (!wcsicmp(LineName, Line->szName))
777 {
778 /* found matching line name */
779 wID = (Index + 1) * dwDialogID;
780
781 /* get dialog control */
782 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
783
784 if (hDlgCtrl != NULL)
785 {
786 /* check state */
787 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
788 if (OldPosition != Position)
789 {
790 /* update control state */
791 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, Position);
792 }
793 }
794 break;
795 }
796 }
797 }