ReactOS 0.4.17-dev-116-ga4b6fe9
dialog.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Sound Volume Control
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Dialog control routines
5 * COPYRIGHT: Copyright 2011 Johannes Anderwald <johannes.anderwald@reactos.org>
6 * Copyright 2018-2019 Eric Kohl <eric.kohl@reactos.org>
7 * Copyright 2026 Vitaly Orekhov <vkvo2000@vivaldi.net>
8 */
9
10#include "sndvol32.h"
11
12
13VOID
14ConvertRect(LPRECT lpRect, UINT xBaseUnit, UINT yBaseUnit)
15{
16 lpRect->left = MulDiv(lpRect->left, xBaseUnit, 4);
17 lpRect->right = MulDiv(lpRect->right, xBaseUnit, 4);
18 lpRect->top = MulDiv(lpRect->top, yBaseUnit, 8);
19 lpRect->bottom = MulDiv(lpRect->bottom, yBaseUnit, 8);
20}
21
25 IN LPCWSTR ResourceName,
26 OUT LPDWORD ResourceLength)
27{
28 HRSRC hSrc;
29 HGLOBAL hRes;
31
32 /* find resource */
33 hSrc = FindResourceW(hModule, ResourceName, (LPCWSTR)RT_DIALOG);
34
35 if (!hSrc)
36 {
37 /* failed to find resource */
38 return NULL;
39 }
40
41 /* now load the resource */
42 hRes = LoadResource(hAppInstance, hSrc);
43 if (!hRes)
44 {
45 /* failed to load resource */
46 return NULL;
47 }
48
49 /* now lock the resource */
50 Result = LockResource(hRes);
51
52 if (!Result)
53 {
54 /* failed to lock resource */
55 return NULL;
56 }
57
58 if (ResourceLength)
59 {
60 /* store output length */
61 *ResourceLength = SizeofResource(hAppInstance, hSrc);
62 }
63
64 /* done */
65 return Result;
66}
67
70 IN HWND hwndDialog,
71 OUT HWND *OutWnd,
72 IN LPRECT DialogOffset,
73 IN PDLGITEMTEMPLATE DialogItem,
74 IN DWORD DialogIdMultiplier,
75 IN HFONT hFont,
76 IN UINT xBaseUnit,
77 IN UINT yBaseUnit,
78 IN UINT MixerId)
79{
80 RECT rect;
82 LPWSTR ClassName, WindowName;
83 WCHAR WindowIdBuf[sizeof("#65535")];
84 HWND hwnd;
85 DWORD wID;
86 INT nSteps, i;
87
88 /* initialize client rectangle */
89 rect.left = DialogItem->x;
90 rect.top = DialogItem->y;
91 rect.right = DialogItem->x + DialogItem->cx;
92 rect.bottom = DialogItem->y + DialogItem->cy;
93
94 /* Convert Dialog units to pixes */
95 ConvertRect(&rect, xBaseUnit, yBaseUnit);
96
97 rect.left += DialogOffset->left;
98 rect.right += DialogOffset->left;
99 rect.top += DialogOffset->top;
100 rect.bottom += DialogOffset->top;
101
102 /* move offset after dialog item */
103 Offset = (LPWORD)(DialogItem + 1);
104
105 if (*Offset == 0xFFFF)
106 {
107 /* class is encoded as type */
108 Offset++;
109
110 /* get control type */
111 switch(*Offset)
112 {
113 case 0x80:
114 ClassName = L"button";
115 break ;
116 case 0x82:
117 ClassName = L"static";
118 break;
119 default:
120 /* FIXME */
121 assert(0);
122 ClassName = NULL;
123 }
124 Offset++;
125 }
126 else
127 {
128 /* class name is encoded as string */
129 ClassName = (LPWSTR)(Offset);
130
131 /* move offset to the end of class string */
132 Offset += wcslen(ClassName) + 1;
133 }
134
135 if (*Offset == 0xFFFF)
136 {
137 /* Window name is encoded as ordinal */
138 Offset++;
139 wsprintf(WindowIdBuf, L"#%u", (DWORD)*Offset);
140 WindowName = WindowIdBuf;
141 Offset++;
142 }
143 else
144 {
145 /* window name is encoded as string */
146 WindowName = (LPWSTR)(Offset);
147
148 /* move offset to the end of class string */
149 Offset += wcslen(WindowName) + 1;
150 }
151
152 if (DialogItem->id == MAXWORD)
153 {
154 /* id is not important */
155 wID = DialogItem->id;
156 }
157 else
158 {
159 /* calculate id */
160 wID = DialogItem->id * (DialogIdMultiplier + 1);
161
162 }
163
164 /* now create the window */
165 hwnd = CreateWindowExW(DialogItem->dwExtendedStyle,
166 ClassName,
167 WindowName,
168 DialogItem->style,
169 rect.left,
170 rect.top,
173 hwndDialog,
174 UlongToPtr(wID),
176 NULL);
177
178 /* sanity check */
179 assert(hwnd);
180
181 /* store window */
182 *OutWnd = hwnd;
183
184 /* check if this the track bar */
185 if (!_wcsicmp(ClassName, L"msctls_trackbar32"))
186 {
187 if (DialogItem->style & TBS_VERT)
188 {
189 /* Vertical trackbar: Volume */
190
191 /* Disable the volume trackbar by default */
193
194 /* set up range */
196
197 /* set up page size */
199
200 /* set position */
202
203 /* Calculate and set ticks */
204 nSteps = (VOLUME_MAX / (VOLUME_TICKS + 1));
205 if (VOLUME_MAX % (VOLUME_TICKS + 1) != 0)
206 nSteps++;
207 for (i = nSteps; i < VOLUME_MAX; i += nSteps)
209 }
210 else
211 {
212 /* Horizontal trackbar: Balance */
213
214 /* Disable the balance trackbar by default */
216
217 /* set up range */
219
220 /* set up page size */
222
223 /* set position */
225
226 /* Calculate and set ticks */
227 nSteps = (BALANCE_STEPS / (BALANCE_TICKS + 1));
228 if (BALANCE_STEPS % (BALANCE_TICKS + 1) != 0)
229 nSteps++;
230 for (i = nSteps; i < BALANCE_STEPS; i += nSteps)
232 }
233 }
234 else if (!_wcsicmp(ClassName, L"static"))
235 {
236 /* Set font */
238 }
239 else if (!_wcsicmp(ClassName, L"button"))
240 {
241 if (DialogItem->id == IDC_LINE_SWITCH)
242 {
243 if (MixerId == PLAY_MIXER)
244 {
245 /* Disable checkboxes by default, if we are in play mode */
247 }
248 }
249 else if (DialogItem->id == IDC_LINE_ADVANCED)
250 {
252 }
253
254 /* Set font */
256 }
257
258
259 /* check if there is additional data */
260 if (*Offset == 0)
261 {
262 /* no additional data */
263 Offset++;
264 }
265 else
266 {
267 /* FIXME: Determine whether this should be "Offset += 1 + *Offset" to explicitly skip the data count too. */
268 /* skip past additional data */
269 Offset += *Offset;
270 }
271
272 /* make sure next template is word-aligned */
273 Offset = (LPWORD)(((ULONG_PTR)Offset + 3) & ~3);
274
275 /* done */
276 return Offset;
277}
278
279VOID
281 IN PMIXER_WINDOW MixerWindow,
282 LPRECT DialogOffset,
283 WORD ItemCount,
284 PDLGITEMTEMPLATE DialogItem,
285 DWORD DialogIdMultiplier,
286 UINT xBaseUnit,
287 UINT yBaseUnit)
288{
290 WORD Index;
291
292 /* sanity check */
293 assert(ItemCount);
294
295 if (MixerWindow->Window)
296 MixerWindow->Window = (HWND*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerWindow->Window, (MixerWindow->WindowCount + ItemCount) * sizeof(HWND));
297 else
298 MixerWindow->Window = (HWND*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ItemCount * sizeof(HWND));
299 if (!MixerWindow->Window)
300 {
301 /* no memory */
302 return;
303 }
304
305 /* enumerate now all controls */
306 for (Index = 0; Index < ItemCount; Index++)
307 {
308 /* add controls */
309 Offset = AddDialogControl(MixerWindow->hWnd,
310 &MixerWindow->Window[MixerWindow->WindowCount],
311 DialogOffset,
312 DialogItem,
313 DialogIdMultiplier,
314 MixerWindow->hFont,
315 xBaseUnit,
316 yBaseUnit,
317 MixerWindow->MixerId);
318
319 /* sanity check */
320 assert(Offset);
321
322 /* move dialog item to new offset */
323 DialogItem =(PDLGITEMTEMPLATE)Offset;
324
325 /* increment window count */
326 MixerWindow->WindowCount++;
327 }
328}
329
330VOID
333 IN PMIXER_WINDOW MixerWindow,
334 IN LPCWSTR DialogResId,
335 IN DWORD Index)
336{
337 LPDLGTEMPLATE DlgTemplate;
338 PDLGITEMTEMPLATE DlgItem;
339 RECT dialogRect;
341 WORD FontSize;
342 WCHAR FontName[100];
344 int width;
345
347 UINT xBaseUnit = LOWORD(units);
348 UINT yBaseUnit = HIWORD(units);
349
350 /* first load the dialog resource */
351 DlgTemplate = (LPDLGTEMPLATE)LoadDialogResource(hModule, DialogResId, NULL);
352 if (!DlgTemplate)
353 {
354 /* failed to load resource */
355 return;
356 }
357
358 /* Now walk past the dialog header */
359 Offset = (LPWORD)(DlgTemplate + 1);
360
361 /* FIXME: support menu */
362 assert(*Offset == 0);
363 Offset++;
364
365 /* FIXME: support classes */
366 assert(*Offset == 0);
367 Offset++;
368
369 /* FIXME: support titles */
370 assert(*Offset == 0);
371 Offset++;
372
373 /* get font size */
374 FontSize = *Offset;
375 Offset++;
376
377 /* calculate font length */
378 Length = wcslen((LPWSTR)Offset) + 1;
379 assert(Length < (sizeof(FontName) / sizeof(WCHAR)));
380
381 /* copy font */
382 wcscpy(FontName, (LPWSTR)Offset);
383
384 if (DlgTemplate->style & DS_SETFONT)
385 {
386 HDC hDC;
387
388 hDC = GetDC(0);
389
390 if (!MixerWindow->hFont)
391 {
392 int pixels = MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
394 }
395
396 if (MixerWindow->hFont)
397 {
398 SIZE charSize;
399 HFONT hOldFont;
400
401 hOldFont = SelectObject(hDC, MixerWindow->hFont);
402 charSize.cx = GdiGetCharDimensions(hDC, NULL, &charSize.cy);
403 if (charSize.cx)
404 {
405 xBaseUnit = charSize.cx;
406 yBaseUnit = charSize.cy;
407 }
408 SelectObject(hDC, hOldFont);
409
410 MixerWindow->baseUnit.cx = charSize.cx;
411 MixerWindow->baseUnit.cy = charSize.cy;
412 }
413
415 }
416
417// assert(MixerWindow->hFont);
418
419 /* move offset after font name */
420 Offset += Length;
421
422 /* offset is now at first dialog item control */
423 DlgItem = (PDLGITEMTEMPLATE)Offset;
424
425 dialogRect.left = 0;
426 dialogRect.right = DlgTemplate->cx;
427 dialogRect.top = 0;
428 dialogRect.bottom = DlgTemplate->cy;
429
430 ConvertRect(&dialogRect, xBaseUnit, yBaseUnit);
431
432 width = dialogRect.right - dialogRect.left;
433
434 dialogRect.left += MixerWindow->rect.right;
435 dialogRect.right += MixerWindow->rect.right;
436 dialogRect.top += MixerWindow->rect.top;
437 dialogRect.bottom += MixerWindow->rect.top;
438
439 MixerWindow->rect.right += width;
440 if ((dialogRect.bottom - dialogRect.top) > (MixerWindow->rect.bottom - MixerWindow->rect.top))
441 MixerWindow->rect.bottom = MixerWindow->rect.top + dialogRect.bottom - dialogRect.top;
442
443 /* now add the controls */
444 LoadDialogControls(MixerWindow, &dialogRect, DlgTemplate->cdit, DlgItem, Index, xBaseUnit, yBaseUnit);
445}
446
447BOOL
450 PSND_MIXER Mixer,
451 DWORD LineID,
454{
456 DWORD Flags;
457 DWORD wID;
458 UINT ControlCount = 0, Index;
460 HWND hDlgCtrl;
461 PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
463
464 if (Line->cControls == 0)
465 return TRUE;
466
467 /* get line name */
468 if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
469 {
470 /* failed to get line name */
471 LineName[0] = L'\0';
472 }
473
474 pVolumeDetails = HeapAlloc(GetProcessHeap(),
475 0,
476 Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
477 if (pVolumeDetails == NULL)
478 goto done;
479
480 /* check if line is found in registry settings */
481 if (ReadLineConfig(PrefContext->DeviceName,
482 LineName,
483 Line->szName,
484 &Flags))
485 {
486 /* is it selected */
487 if (Flags != 0x4)
488 {
489 int dlgId;
490
491 if ((Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) ||
492 (Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES))
493 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_MASTER : IDD_NORMAL_MASTER;
494 else
495 dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_LINE : IDD_NORMAL_LINE;
496
497 /* load dialog resource */
498 LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(dlgId), PrefContext->MixerWindow->DialogCount);
499
500 /* get id */
501 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_NAME;
502
503 /* set line name */
504 SetDlgItemTextW(PrefContext->MixerWindow->hWnd, wID, Line->szName);
505
506 /* query controls */
507 if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) != FALSE)
508 {
509 /* now go through all controls and update their states */
510 for (Index = 0; Index < Line->cControls; Index++)
511 {
512 if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
513 {
515
516 /* get volume control details */
517 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
518 {
519 /* update dialog control */
520 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SWITCH;
521
522 /* get dialog control */
523 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
524
525 if (hDlgCtrl != NULL)
526 {
527 /* Enable the 'Mute' checkbox, if we are in play mode */
528 if (Mixer->MixerId == PLAY_MIXER)
529 EnableWindow(hDlgCtrl, TRUE);
530
531 /* check state */
532 if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != Details.fValue)
533 {
534 /* update control state */
535 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)Details.fValue, 0);
536 }
537 }
538 }
539 }
540 else if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
541 {
542 /* get volume control details */
543 if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
544 {
545 /* update dialog control */
546 DWORD volumePosition, volumeStep, maxVolume, i;
547 DWORD balancePosition, balanceStep;
548
549 volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
550
551 maxVolume = 0;
552 for (i = 0; i < Line->cChannels; i++)
553 {
554 if (pVolumeDetails[i].dwValue > maxVolume)
555 maxVolume = pVolumeDetails[i].dwValue;
556 }
557
558 volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
559
560 if (Line->cChannels == 1)
561 {
562 balancePosition = BALANCE_CENTER;
563 }
564 else if (Line->cChannels == 2)
565 {
566 if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
567 {
568 balancePosition = BALANCE_CENTER;
569 }
570 else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
571 {
572 balancePosition = BALANCE_RIGHT;
573 }
574 else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
575 {
576 balancePosition = BALANCE_LEFT;
577 }
578 else
579 {
580 balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
581
582 if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
583 {
584 balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
585 balancePosition = BALANCE_RIGHT - balancePosition;
586 }
587 else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
588 {
589 balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
590 balancePosition = BALANCE_LEFT + balancePosition;
591 }
592 }
593 }
594
595 /* Set the volume trackbar */
596 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_VERT;
597
598 /* get dialog control */
599 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
600
601 if (hDlgCtrl != NULL)
602 {
603 /* check state */
604 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
605
606 /* Enable the volume trackbar */
607 EnableWindow(hDlgCtrl, TRUE);
608
609 if (OldPosition != (VOLUME_MAX - volumePosition))
610 {
611 /* update control state */
612 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - volumePosition);
613 }
614 }
615
616 if (Line->cChannels == 2)
617 {
618 /* Set the balance trackbar */
619 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_HORZ;
620
621 /* get dialog control */
622 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
623
624 if (hDlgCtrl != NULL)
625 {
626 /* check state */
627 LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
628
629 /* Enable the balance trackbar */
630 EnableWindow(hDlgCtrl, TRUE);
631
632 if (OldPosition != balancePosition)
633 {
634 /* update control state */
635 SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, balancePosition);
636 }
637 }
638 }
639 }
640 }
641 else
642 {
643 if (PrefContext->MixerWindow->Mode == NORMAL_MODE)
644 {
645 PrefContext->MixerWindow->bHasExtendedControls = TRUE;
646
647 wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_ADVANCED;
648
649 /* get dialog control */
650 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
651 if (hDlgCtrl != NULL)
652 {
653 ShowWindow(hDlgCtrl,
655 }
656 }
657 }
658 }
659
660 /* free controls */
662 }
663
664 /* increment dialog count */
665 PrefContext->MixerWindow->DialogCount++;
666 }
667 }
668
669done:
670 /* Free the volume details */
671 if (pVolumeDetails)
672 HeapFree(GetProcessHeap(), 0, pVolumeDetails);
673
674 return TRUE;
675}
676
677VOID
679 PPREFERENCES_CONTEXT PrefContext)
680{
681 WCHAR szBuffer[64];
682 HWND hDlgCtrl;
683 RECT statusRect;
684 UINT i;
685 LONG dy;
686
687 /* set dialog count to zero */
688 PrefContext->MixerWindow->DialogCount = 0;
689 PrefContext->MixerWindow->bHasExtendedControls = FALSE;
690 SetRectEmpty(&PrefContext->MixerWindow->rect);
691
692 /* enumerate controls */
693 SndMixerEnumConnections(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, EnumConnectionsCallback, (PVOID)PrefContext);
694
695 /* Update the 'Advanced Controls' menu item */
696 EnableMenuItem(GetMenu(PrefContext->MixerWindow->hWnd),
699
700 /* Add some height for the status bar */
701 if (PrefContext->MixerWindow->hStatusBar)
702 {
703 GetWindowRect(PrefContext->MixerWindow->hStatusBar, &statusRect);
704 PrefContext->MixerWindow->rect.bottom += (statusRect.bottom - statusRect.top);
705 }
706
707 /* Add height of the 'Advanced' button */
709 if (PrefContext->MixerWindow->bShowExtendedControls && PrefContext->MixerWindow->bHasExtendedControls)
710 PrefContext->MixerWindow->rect.bottom += dy;
711
712 /* now move the window */
714 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);
715
716 /* Move the status bar */
717 if (PrefContext->MixerWindow->hStatusBar)
718 {
719 SetWindowPos(PrefContext->MixerWindow->hStatusBar,
720 HWND_TOP,
721 statusRect.left,
722 PrefContext->MixerWindow->rect.bottom - (statusRect.bottom - statusRect.top),
723 PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left,
724 statusRect.bottom - statusRect.top,
726 }
727
728 if (PrefContext->MixerWindow->MixerId == RECORD_MIXER)
729 LoadStringW(hAppInstance, IDS_SELECT, szBuffer, ARRAYSIZE(szBuffer));
730
731 for (i = 0; i < PrefContext->MixerWindow->DialogCount; i++)
732 {
733 if (PrefContext->MixerWindow->MixerId == RECORD_MIXER)
734 {
735 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, (i + 1) * IDC_LINE_SWITCH);
736
737 /* Turn the autocheckbox into a checkbox */
739
740 /* Change text from 'Mute' to 'Select' */
741 SetWindowTextW(hDlgCtrl, szBuffer);
742 }
743
744 /* Resize the vertical line separator */
745 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, (i + 1) * IDC_LINE_SEP);
746 if (hDlgCtrl != NULL)
747 {
748 GetWindowRect(hDlgCtrl, &statusRect);
749 if (PrefContext->MixerWindow->bShowExtendedControls && PrefContext->MixerWindow->bHasExtendedControls)
750 statusRect.bottom += dy;
751
752 SetWindowPos(hDlgCtrl,
753 HWND_TOP,
754 0,
755 0,
756 statusRect.right - statusRect.left,
757 statusRect.bottom - statusRect.top,
759 }
760 }
761
762 /* Hide the last line separator */
763 hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, IDC_LINE_SEP * PrefContext->MixerWindow->DialogCount);
764 if (hDlgCtrl != NULL)
765 {
766 ShowWindow(hDlgCtrl, SW_HIDE);
767 }
768}
769
770HWND
772 PPREFERENCES_CONTEXT PrefContext,
774 DWORD dwDialogID)
775{
776 DWORD Index;
777
778 /* find the index of this line */
779 for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++)
780 {
781 /* get id */
783 DWORD wID = (Index + 1) * IDC_LINE_NAME;
784
785 if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
786 {
787 /* failed to retrieve id */
788 continue;
789 }
790
791 /* check if the line name matches */
792 if (!_wcsicmp(LineName, Line->szName))
793 {
794 /* found matching line name */
795 wID = (Index + 1) * dwDialogID;
796
797 return GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
798 }
799 }
800
801 return NULL;
802}
803
804VOID
806 PPREFERENCES_CONTEXT PrefContext,
808 LONG fValue)
809{
810 HWND hDlgCtrl = GetLineDialogControl(PrefContext, Line, IDC_LINE_SWITCH);
811
812 if (hDlgCtrl != NULL && SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != fValue)
813 SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)fValue, 0);
814}
815
816DWORD
818 PPREFERENCES_CONTEXT PrefContext,
820 DWORD dwDialogID)
821{
822 HWND hDlgCtrl = GetLineDialogControl(PrefContext, Line, dwDialogID);
823
824 return hDlgCtrl != NULL
825 ? SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0)
826 : 0;
827}
828
829VOID
831 PPREFERENCES_CONTEXT PrefContext,
833 DWORD dwDialogID,
835{
836 HWND hDlgCtrl = GetLineDialogControl(PrefContext, Line, dwDialogID);
837 BOOL isPositionChanged = GetDialogLineSliderCurrentPosition(PrefContext, Line, dwDialogID) != Position;
838
839 if (hDlgCtrl != NULL && isPositionChanged)
841}
static HDC hDC
Definition: 3dtext.c:33
HINSTANCE hAppInstance
Definition: mmc.c:23
HFONT hFont
Definition: main.c:53
VOID UpdateDialogLineSliderControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD dwDialogID, DWORD Position)
Definition: dialog.c:830
VOID LoadDialog(IN HMODULE hModule, IN PMIXER_WINDOW MixerWindow, IN LPCWSTR DialogResId, IN DWORD Index)
Definition: dialog.c:331
VOID UpdateDialogLineSwitchControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, LONG fValue)
Definition: dialog.c:805
VOID LoadDialogCtrls(PPREFERENCES_CONTEXT PrefContext)
Definition: dialog.c:678
DWORD GetDialogLineSliderCurrentPosition(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD dwDialogID)
Definition: dialog.c:817
VOID ConvertRect(LPRECT lpRect, UINT xBaseUnit, UINT yBaseUnit)
Definition: dialog.c:14
VOID LoadDialogControls(IN PMIXER_WINDOW MixerWindow, LPRECT DialogOffset, WORD ItemCount, PDLGITEMTEMPLATE DialogItem, DWORD DialogIdMultiplier, UINT xBaseUnit, UINT yBaseUnit)
Definition: dialog.c:280
LPWORD AddDialogControl(IN HWND hwndDialog, OUT HWND *OutWnd, IN LPRECT DialogOffset, IN PDLGITEMTEMPLATE DialogItem, IN DWORD DialogIdMultiplier, IN HFONT hFont, IN UINT xBaseUnit, IN UINT yBaseUnit, IN UINT MixerId)
Definition: dialog.c:69
HWND GetLineDialogControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD dwDialogID)
Definition: dialog.c:771
BOOL CALLBACK EnumConnectionsCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
Definition: dialog.c:449
LPVOID LoadDialogResource(IN HMODULE hModule, IN LPCWSTR ResourceName, OUT LPDWORD ResourceLength)
Definition: dialog.c:23
BOOL ReadLineConfig(IN LPTSTR szDeviceName, IN LPTSTR szLineName, IN LPTSTR szControlName, OUT DWORD *Flags)
Definition: misc.c:307
BOOL SndMixerQueryControls(PSND_MIXER Mixer, PUINT DisplayControls, LPMIXERLINE LineInfo, LPMIXERCONTROL *Controls)
Definition: mixer.c:112
INT SndMixerGetLineName(PSND_MIXER Mixer, DWORD LineID, LPTSTR lpBuffer, UINT uSize, BOOL LongName)
Definition: mixer.c:390
INT SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails)
Definition: mixer.c:498
BOOL SndMixerEnumConnections(PSND_MIXER Mixer, DWORD LineID, PFNSNDMIXENUMCONNECTIONS EnumProc, PVOID Context)
Definition: mixer.c:552
#define IDD_SMALL_MASTER
Definition: resources.h:50
#define IDD_NORMAL_LINE
Definition: resources.h:49
#define IDC_LINE_SLIDER_VERT
Definition: resources.h:25
#define IDS_SELECT
Definition: resources.h:43
#define IDM_ADVANCED_CONTROLS
Definition: resources.h:10
#define IDC_LINE_ADVANCED
Definition: resources.h:26
#define IDC_LINE_NAME
Definition: resources.h:22
#define IDD_SMALL_LINE
Definition: resources.h:51
#define IDD_NORMAL_MASTER
Definition: resources.h:48
#define IDC_LINE_SWITCH
Definition: resources.h:23
#define IDC_LINE_SLIDER_HORZ
Definition: resources.h:24
#define IDC_LINE_SEP
Definition: resources.h:27
RECT rect
Definition: combotst.c:67
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HMODULE hModule
Definition: animate.c:44
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
HANDLE HWND
Definition: compat.h:19
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define L(x)
Definition: resources.c:13
#define UlongToPtr(u)
Definition: config.h:106
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLfloat units
Definition: glext.h:11727
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLint dy
Definition: linetemp.h:97
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
Definition: mmsystem.h:319
#define MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
Definition: mmsystem.h:320
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
#define MIXER_LONG_NAME_CHARS
Definition: mmsystem.h:294
#define MIXERCONTROL_CONTROLTYPE_MUTE
Definition: mmsystem.h:384
static HDC
Definition: imagelist.c:88
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
unsigned int UINT
Definition: ndis.h:50
#define MAXWORD
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CAPTION
Definition: pedump.c:624
#define WS_SYSMENU
Definition: pedump.c:629
short WCHAR
Definition: pedump.c:58
#define WS_VISIBLE
Definition: pedump.c:620
#define RT_DIALOG
Definition: pedump.c:367
#define BS_AUTOCHECKBOX
Definition: pedump.c:654
long LONG
Definition: pedump.c:60
#define BS_CHECKBOX
Definition: pedump.c:653
#define WS_DLGFRAME
Definition: pedump.c:626
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WS_CLIPCHILDREN
Definition: pedump.c:619
#define WS_MINIMIZEBOX
Definition: pedump.c:631
#define TBM_SETPAGESIZE
Definition: commctrl.h:2056
#define TBM_SETTIC
Definition: commctrl.h:2040
#define TBM_GETPOS
Definition: commctrl.h:2036
#define TBS_VERT
Definition: commctrl.h:2021
#define TBM_SETRANGE
Definition: commctrl.h:2042
#define TBM_SETPOS
Definition: commctrl.h:2041
wcscpy
#define LoadStringW
Definition: utils.h:64
#define VOLUME_MAX
Definition: sndvol32.h:19
#define BALANCE_RIGHT
Definition: sndvol32.h:24
#define VOLUME_PAGE_SIZE
Definition: sndvol32.h:21
#define VOLUME_TICKS
Definition: sndvol32.h:20
#define PLAY_MIXER
Definition: sndvol32.h:29
#define VOLUME_MIN
Definition: sndvol32.h:18
#define BALANCE_PAGE_SIZE
Definition: sndvol32.h:27
#define RECORD_MIXER
Definition: sndvol32.h:30
#define BALANCE_STEPS
Definition: sndvol32.h:25
#define BALANCE_CENTER
Definition: sndvol32.h:23
#define ADVANCED_BUTTON_HEIGHT
Definition: sndvol32.h:32
#define BALANCE_LEFT
Definition: sndvol32.h:22
struct _PREFERENCES_CONTEXT * PPREFERENCES_CONTEXT
@ SMALL_MODE
Definition: sndvol32.h:39
@ NORMAL_MODE
Definition: sndvol32.h:38
#define BALANCE_TICKS
Definition: sndvol32.h:26
_In_ PVOID Context
Definition: storport.h:2269
WORD cdit
Definition: winuser.h:3169
short cy
Definition: winuser.h:3173
DWORD style
Definition: winuser.h:3167
short cx
Definition: winuser.h:3172
Definition: ncftp.h:79
BOOL bShowExtendedControls
Definition: sndvol32.h:56
WINDOW_MODE Mode
Definition: sndvol32.h:53
struct _SND_MIXER * Mixer
Definition: sndvol32.h:47
UINT MixerId
Definition: sndvol32.h:54
UINT DialogCount
Definition: sndvol32.h:51
HWND hStatusBar
Definition: sndvol32.h:46
BOOL bHasExtendedControls
Definition: sndvol32.h:55
SIZE baseUnit
Definition: sndvol32.h:59
TCHAR DeviceName[128]
Definition: sndvol32.h:119
PMIXER_WINDOW MixerWindow
Definition: sndvol32.h:110
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
UINT MixerId
Definition: sndvol32.h:102
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
static COORD Position
Definition: mouse.c:34
#define GetWindowLongPtr
Definition: treelist.c:73
#define SetWindowLongPtr
Definition: treelist.c:70
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
uint16_t * LPWORD
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
#define OUT
Definition: typedefs.h:40
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
LONG WINAPI GdiGetCharDimensions(HDC, LPTEXTMETRICW, LONG *)
Definition: font.c:2314
#define DEFAULT_QUALITY
Definition: wingdi.h:436
#define FF_DONTCARE
Definition: wingdi.h:448
#define LOGPIXELSY
Definition: wingdi.h:719
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define DEFAULT_CHARSET
Definition: wingdi.h:384
#define OUT_DEFAULT_PRECIS
Definition: wingdi.h:415
HFONT WINAPI CreateFontW(_In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_opt_ LPCWSTR)
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
#define FW_NORMAL
Definition: wingdi.h:373
#define SW_SHOWNORMAL
Definition: winuser.h:781
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define SW_HIDE
Definition: winuser.h:779
#define MF_BYCOMMAND
Definition: winuser.h:202
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI AdjustWindowRect(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL)
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define GetDlgItemText
Definition: winuser.h:5951
#define SWP_NOMOVE
Definition: winuser.h:1255
BOOL WINAPI SetDlgItemTextW(_In_ HWND, _In_ int, _In_ LPCWSTR)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define BM_SETCHECK
Definition: winuser.h:1950
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
#define HWND_TOP
Definition: winuser.h:1218
#define MF_ENABLED
Definition: winuser.h:128
#define WM_SETFONT
Definition: winuser.h:1678
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
struct DLGTEMPLATE * LPDLGTEMPLATE
#define DS_SETFONT
Definition: winuser.h:378
#define SendMessage
Definition: winuser.h:6009
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
HDC WINAPI GetDC(_In_opt_ HWND)
#define wsprintf
Definition: winuser.h:6031
LONG WINAPI GetDialogBaseUnits(void)
Definition: dialog.c:2144
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define SWP_NOZORDER
Definition: winuser.h:1258
#define GWL_STYLE
Definition: winuser.h:863
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HMENU WINAPI GetMenu(_In_ HWND)
#define BM_GETCHECK
Definition: winuser.h:1947
#define MF_GRAYED
Definition: winuser.h:129
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170