ReactOS  0.4.15-dev-318-g99b52df
dialog.c
Go to the documentation of this file.
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
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
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;
81  WCHAR WindowIdBuf[sizeof("#65535")];
82  HWND hwnd;
83  DWORD wID;
84  INT nSteps, i;
85 
86  /* initialize client rectangle */
87  rect.left = DialogItem->x;
88  rect.top = DialogItem->y;
89  rect.right = DialogItem->x + DialogItem->cx;
90  rect.bottom = DialogItem->y + DialogItem->cy;
91 
92  /* Convert Dialog units to pixes */
93  ConvertRect(&rect, xBaseUnit, yBaseUnit);
94 
95  rect.left += DialogOffset->left;
96  rect.right += DialogOffset->left;
97  rect.top += DialogOffset->top;
98  rect.bottom += DialogOffset->top;
99 
100  /* move offset after dialog item */
101  Offset = (LPWORD)(DialogItem + 1);
102 
103  if (*Offset == 0xFFFF)
104  {
105  /* class is encoded as type */
106  Offset++;
107 
108  /* get control type */
109  switch(*Offset)
110  {
111  case 0x80:
112  ClassName = L"button";
113  break ;
114  case 0x82:
115  ClassName = L"static";
116  break;
117  default:
118  /* FIXME */
119  assert(0);
120  ClassName = NULL;
121  }
122  Offset++;
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) + 1;
131  }
132 
133  if (*Offset == 0xFFFF)
134  {
135  /* Window name is encoded as ordinal */
136  Offset++;
137  wsprintf(WindowIdBuf, L"#%u", (DWORD)*Offset);
138  WindowName = WindowIdBuf;
139  Offset++;
140  }
141  else
142  {
143  /* window name is encoded as string */
144  WindowName = (LPWSTR)(Offset);
145 
146  /* move offset to the end of class string */
147  Offset += wcslen(WindowName) + 1;
148  }
149 
150  if (DialogItem->id == MAXWORD)
151  {
152  /* id is not important */
153  wID = DialogItem->id;
154  }
155  else
156  {
157  /* calculate id */
158  wID = DialogItem->id * (DialogIdMultiplier + 1);
159 
160  }
161 
162  /* now create the window */
163  hwnd = CreateWindowExW(DialogItem->dwExtendedStyle,
164  ClassName,
165  WindowName,
166  DialogItem->style,
167  rect.left,
168  rect.top,
169  rect.right - rect.left,
170  rect.bottom - rect.top,
171  hwndDialog,
172  UlongToPtr(wID),
173  hAppInstance,
174  NULL);
175 
176  /* sanity check */
177  assert(hwnd);
178 
179  /* store window */
180  *OutWnd = hwnd;
181 
182  /* check if this the track bar */
183  if (!wcsicmp(ClassName, L"msctls_trackbar32"))
184  {
185  if (DialogItem->style & TBS_VERT)
186  {
187  /* Vertical trackbar: Volume */
188 
189  /* Disable the volume trackbar by default */
191 
192  /* set up range */
194 
195  /* set up page size */
197 
198  /* set position */
200 
201  /* Calculate and set ticks */
202  nSteps = (VOLUME_MAX / (VOLUME_TICKS + 1));
203  if (VOLUME_MAX % (VOLUME_TICKS + 1) != 0)
204  nSteps++;
205  for (i = nSteps; i < VOLUME_MAX; i += nSteps)
207  }
208  else
209  {
210  /* Horizontal trackbar: Balance */
211 
212  /* Disable the balance trackbar by default */
214 
215  /* set up range */
217 
218  /* set up page size */
220 
221  /* set position */
223 
224  /* Calculate and set ticks */
225  nSteps = (BALANCE_STEPS / (BALANCE_TICKS + 1));
226  if (BALANCE_STEPS % (BALANCE_TICKS + 1) != 0)
227  nSteps++;
228  for (i = nSteps; i < BALANCE_STEPS; i += nSteps)
230  }
231  }
232  else if (!wcsicmp(ClassName, L"static"))
233  {
234  /* Set font */
236  }
237  else if (!wcsicmp(ClassName, L"button"))
238  {
239  if (DialogItem->id == IDC_LINE_SWITCH)
240  {
241  if (MixerId == PLAY_MIXER)
242  {
243  /* Disable checkboxes by default, if we are in play mode */
245  }
246  }
247  else if (DialogItem->id == IDC_LINE_ADVANCED)
248  {
250  }
251 
252  /* Set font */
254  }
255 
256 
257  /* check if there is additional data */
258  if (*Offset == 0)
259  {
260  /* no additional data */
261  Offset++;
262  }
263  else
264  {
265  /* FIXME: Determine whether this should be "Offset += 1 + *Offset" to explicitly skip the data count too. */
266  /* skip past additional data */
267  Offset += *Offset;
268  }
269 
270  /* make sure next template is word-aligned */
271  Offset = (LPWORD)(((ULONG_PTR)Offset + 3) & ~3);
272 
273  /* done */
274  return Offset;
275 }
276 
277 VOID
279  IN PMIXER_WINDOW MixerWindow,
280  LPRECT DialogOffset,
281  WORD ItemCount,
282  PDLGITEMTEMPLATE DialogItem,
283  DWORD DialogIdMultiplier,
284  UINT xBaseUnit,
285  UINT yBaseUnit)
286 {
287  LPWORD Offset;
288  WORD Index;
289 
290  /* sanity check */
291  assert(ItemCount);
292 
293  if (MixerWindow->Window)
294  MixerWindow->Window = (HWND*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerWindow->Window, (MixerWindow->WindowCount + ItemCount) * sizeof(HWND));
295  else
296  MixerWindow->Window = (HWND*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ItemCount * sizeof(HWND));
297  if (!MixerWindow->Window)
298  {
299  /* no memory */
300  return;
301  }
302 
303  /* enumerate now all controls */
304  for (Index = 0; Index < ItemCount; Index++)
305  {
306  /* add controls */
307  Offset = AddDialogControl(MixerWindow->hWnd,
308  &MixerWindow->Window[MixerWindow->WindowCount],
309  DialogOffset,
310  DialogItem,
311  DialogIdMultiplier,
312  MixerWindow->hFont,
313  xBaseUnit,
314  yBaseUnit,
315  MixerWindow->MixerId);
316 
317  /* sanity check */
318  assert(Offset);
319 
320  /* move dialog item to new offset */
321  DialogItem =(PDLGITEMTEMPLATE)Offset;
322 
323  /* increment window count */
324  MixerWindow->WindowCount++;
325  }
326 }
327 
328 VOID
331  IN PMIXER_WINDOW MixerWindow,
332  IN LPCWSTR DialogResId,
333  IN DWORD Index)
334 {
335  LPDLGTEMPLATE DlgTemplate;
336  PDLGITEMTEMPLATE DlgItem;
337  RECT dialogRect;
338  LPWORD Offset;
339  WORD FontSize;
340  WCHAR FontName[100];
341  WORD Length;
342  int width;
343 
345  UINT xBaseUnit = LOWORD(units);
346  UINT yBaseUnit = HIWORD(units);
347 
348  /* first load the dialog resource */
349  DlgTemplate = (LPDLGTEMPLATE)LoadDialogResource(hModule, DialogResId, NULL);
350  if (!DlgTemplate)
351  {
352  /* failed to load resource */
353  return;
354  }
355 
356  /* Now walk past the dialog header */
357  Offset = (LPWORD)(DlgTemplate + 1);
358 
359  /* FIXME: support menu */
360  assert(*Offset == 0);
361  Offset++;
362 
363  /* FIXME: support classes */
364  assert(*Offset == 0);
365  Offset++;
366 
367  /* FIXME: support titles */
368  assert(*Offset == 0);
369  Offset++;
370 
371  /* get font size */
372  FontSize = *Offset;
373  Offset++;
374 
375  /* calculate font length */
376  Length = wcslen((LPWSTR)Offset) + 1;
377  assert(Length < (sizeof(FontName) / sizeof(WCHAR)));
378 
379  /* copy font */
380  wcscpy(FontName, (LPWSTR)Offset);
381 
382  if (DlgTemplate->style & DS_SETFONT)
383  {
384  HDC hDC;
385 
386  hDC = GetDC(0);
387 
388  if (!MixerWindow->hFont)
389  {
390  int pixels = MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
392  }
393 
394  if (MixerWindow->hFont)
395  {
396  SIZE charSize;
397  HFONT hOldFont;
398 
399  hOldFont = SelectObject(hDC, MixerWindow->hFont);
400  charSize.cx = GdiGetCharDimensions(hDC, NULL, &charSize.cy);
401  if (charSize.cx)
402  {
403  xBaseUnit = charSize.cx;
404  yBaseUnit = charSize.cy;
405  }
406  SelectObject(hDC, hOldFont);
407 
408  MixerWindow->baseUnit.cx = charSize.cx;
409  MixerWindow->baseUnit.cy = charSize.cy;
410  }
411 
412  ReleaseDC(NULL, hDC);
413  }
414 
415 // assert(MixerWindow->hFont);
416 
417  /* move offset after font name */
418  Offset += Length;
419 
420  /* offset is now at first dialog item control */
421  DlgItem = (PDLGITEMTEMPLATE)Offset;
422 
423  dialogRect.left = 0;
424  dialogRect.right = DlgTemplate->cx;
425  dialogRect.top = 0;
426  dialogRect.bottom = DlgTemplate->cy;
427 
428  ConvertRect(&dialogRect, xBaseUnit, yBaseUnit);
429 
430  width = dialogRect.right - dialogRect.left;
431 
432  dialogRect.left += MixerWindow->rect.right;
433  dialogRect.right += MixerWindow->rect.right;
434  dialogRect.top += MixerWindow->rect.top;
435  dialogRect.bottom += MixerWindow->rect.top;
436 
437  MixerWindow->rect.right += width;
438  if ((dialogRect.bottom - dialogRect.top) > (MixerWindow->rect.bottom - MixerWindow->rect.top))
439  MixerWindow->rect.bottom = MixerWindow->rect.top + dialogRect.bottom - dialogRect.top;
440 
441  /* now add the controls */
442  LoadDialogControls(MixerWindow, &dialogRect, DlgTemplate->cdit, DlgItem, Index, xBaseUnit, yBaseUnit);
443 }
444 
445 BOOL
446 CALLBACK
448  PSND_MIXER Mixer,
449  DWORD LineID,
451  PVOID Context)
452 {
453  WCHAR LineName[MIXER_LONG_NAME_CHARS];
454  DWORD Flags;
455  DWORD wID;
456  UINT ControlCount = 0, Index;
458  HWND hDlgCtrl;
459  PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
461 
462  if (Line->cControls == 0)
463  return TRUE;
464 
465  /* get line name */
466  if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
467  {
468  /* failed to get line name */
469  LineName[0] = L'\0';
470  }
471 
472  pVolumeDetails = HeapAlloc(GetProcessHeap(),
473  0,
474  Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
475  if (pVolumeDetails == NULL)
476  goto done;
477 
478  /* check if line is found in registry settings */
479  if (ReadLineConfig(PrefContext->DeviceName,
480  LineName,
481  Line->szName,
482  &Flags))
483  {
484  /* is it selected */
485  if (Flags != 0x4)
486  {
487  int dlgId;
488 
489  if ((Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) ||
490  (Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES))
491  dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_MASTER : IDD_NORMAL_MASTER;
492  else
493  dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_LINE : IDD_NORMAL_LINE;
494 
495  /* load dialog resource */
496  LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(dlgId), PrefContext->MixerWindow->DialogCount);
497 
498  /* get id */
499  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_NAME;
500 
501  /* set line name */
502  SetDlgItemTextW(PrefContext->MixerWindow->hWnd, wID, Line->szName);
503 
504  /* query controls */
505  if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) != FALSE)
506  {
507  /* now go through all controls and update their states */
508  for (Index = 0; Index < Line->cControls; Index++)
509  {
510  if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
511  {
513 
514  /* get volume control details */
515  if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
516  {
517  /* update dialog control */
518  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SWITCH;
519 
520  /* get dialog control */
521  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
522 
523  if (hDlgCtrl != NULL)
524  {
525  /* Enable the 'Mute' checkbox, if we are in play mode */
526  if (Mixer->MixerId == PLAY_MIXER)
527  EnableWindow(hDlgCtrl, TRUE);
528 
529  /* check state */
530  if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != Details.fValue)
531  {
532  /* update control state */
533  SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)Details.fValue, 0);
534  }
535  }
536  }
537  }
538  else if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
539  {
540  /* get volume control details */
541  if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
542  {
543  /* update dialog control */
544  DWORD volumePosition, volumeStep, maxVolume, i;
545  DWORD balancePosition, balanceStep;
546 
547  volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
548 
549  maxVolume = 0;
550  for (i = 0; i < Line->cChannels; i++)
551  {
552  if (pVolumeDetails[i].dwValue > maxVolume)
553  maxVolume = pVolumeDetails[i].dwValue;
554  }
555 
556  volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
557 
558  if (Line->cChannels == 1)
559  {
560  balancePosition = BALANCE_CENTER;
561  }
562  else if (Line->cChannels == 2)
563  {
564  if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
565  {
566  balancePosition = BALANCE_CENTER;
567  }
568  else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
569  {
570  balancePosition = BALANCE_RIGHT;
571  }
572  else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
573  {
574  balancePosition = BALANCE_LEFT;
575  }
576  else
577  {
578  balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
579 
580  if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
581  {
582  balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
583  balancePosition = BALANCE_RIGHT - balancePosition;
584  }
585  else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
586  {
587  balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
588  balancePosition = BALANCE_LEFT + balancePosition;
589  }
590  }
591  }
592 
593  /* Set the volume trackbar */
594  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_VERT;
595 
596  /* get dialog control */
597  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
598 
599  if (hDlgCtrl != NULL)
600  {
601  /* check state */
602  LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
603 
604  /* Enable the volume trackbar */
605  EnableWindow(hDlgCtrl, TRUE);
606 
607  if (OldPosition != (VOLUME_MAX - volumePosition))
608  {
609  /* update control state */
610  SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - volumePosition);
611  }
612  }
613 
614  if (Line->cChannels == 2)
615  {
616  /* Set the balance trackbar */
617  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_HORZ;
618 
619  /* get dialog control */
620  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
621 
622  if (hDlgCtrl != NULL)
623  {
624  /* check state */
625  LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
626 
627  /* Enable the balance trackbar */
628  EnableWindow(hDlgCtrl, TRUE);
629 
630  if (OldPosition != balancePosition)
631  {
632  /* update control state */
633  SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, balancePosition);
634  }
635  }
636  }
637  }
638  }
639  else
640  {
641  if (PrefContext->MixerWindow->Mode == NORMAL_MODE)
642  {
643  PrefContext->MixerWindow->bHasExtendedControls = TRUE;
644 
645  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_ADVANCED;
646 
647  /* get dialog control */
648  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
649  if (hDlgCtrl != NULL)
650  {
651  ShowWindow(hDlgCtrl,
653  }
654  }
655  }
656  }
657 
658  /* free controls */
660  }
661 
662  /* increment dialog count */
663  PrefContext->MixerWindow->DialogCount++;
664  }
665  }
666 
667 done:
668  /* Free the volume details */
669  if (pVolumeDetails)
670  HeapFree(GetProcessHeap(), 0, pVolumeDetails);
671 
672  return TRUE;
673 }
674 
675 VOID
677  PPREFERENCES_CONTEXT PrefContext)
678 {
679  WCHAR szBuffer[64];
680  HWND hDlgCtrl;
681  RECT statusRect;
682  UINT i;
683  LONG dy;
684 
685  /* set dialog count to zero */
686  PrefContext->MixerWindow->DialogCount = 0;
687  PrefContext->MixerWindow->bHasExtendedControls = FALSE;
688  SetRectEmpty(&PrefContext->MixerWindow->rect);
689 
690  /* enumerate controls */
691  SndMixerEnumConnections(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, EnumConnectionsCallback, (PVOID)PrefContext);
692 
693  /* Update the 'Advanced Controls' menu item */
694  EnableMenuItem(GetMenu(PrefContext->MixerWindow->hWnd),
696  MF_BYCOMMAND | (PrefContext->MixerWindow->bHasExtendedControls ? MF_ENABLED : MF_GRAYED));
697 
698  /* Add some height for the status bar */
699  if (PrefContext->MixerWindow->hStatusBar)
700  {
701  GetWindowRect(PrefContext->MixerWindow->hStatusBar, &statusRect);
702  PrefContext->MixerWindow->rect.bottom += (statusRect.bottom - statusRect.top);
703  }
704 
705  /* Add height of the 'Advanced' button */
706  dy = MulDiv(ADVANCED_BUTTON_HEIGHT, PrefContext->MixerWindow->baseUnit.cy, 8);
707  if (PrefContext->MixerWindow->bShowExtendedControls && PrefContext->MixerWindow->bHasExtendedControls)
708  PrefContext->MixerWindow->rect.bottom += dy;
709 
710  /* now move the window */
712  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);
713 
714  /* Move the status bar */
715  if (PrefContext->MixerWindow->hStatusBar)
716  {
717  SetWindowPos(PrefContext->MixerWindow->hStatusBar,
718  HWND_TOP,
719  statusRect.left,
720  PrefContext->MixerWindow->rect.bottom - (statusRect.bottom - statusRect.top),
721  PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left,
722  statusRect.bottom - statusRect.top,
723  SWP_NOZORDER);
724  }
725 
726  if (PrefContext->MixerWindow->MixerId == RECORD_MIXER)
727  LoadStringW(hAppInstance, IDS_SELECT, szBuffer, ARRAYSIZE(szBuffer));
728 
729  for (i = 0; i < PrefContext->MixerWindow->DialogCount; i++)
730  {
731  if (PrefContext->MixerWindow->MixerId == RECORD_MIXER)
732  {
733  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, (i + 1) * IDC_LINE_SWITCH);
734 
735  /* Turn the autocheckbox into a checkbox */
737 
738  /* Change text from 'Mute' to 'Select' */
739  SetWindowTextW(hDlgCtrl, szBuffer);
740  }
741 
742  /* Resize the vertical line separator */
743  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, (i + 1) * IDC_LINE_SEP);
744  if (hDlgCtrl != NULL)
745  {
746  GetWindowRect(hDlgCtrl, &statusRect);
747  if (PrefContext->MixerWindow->bShowExtendedControls && PrefContext->MixerWindow->bHasExtendedControls)
748  statusRect.bottom += dy;
749 
750  SetWindowPos(hDlgCtrl,
751  HWND_TOP,
752  0,
753  0,
754  statusRect.right - statusRect.left,
755  statusRect.bottom - statusRect.top,
757  }
758  }
759 
760  /* Hide the last line separator */
761  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, IDC_LINE_SEP * PrefContext->MixerWindow->DialogCount);
762  if (hDlgCtrl != NULL)
763  {
764  ShowWindow(hDlgCtrl, SW_HIDE);
765  }
766 }
767 
768 VOID
770  PPREFERENCES_CONTEXT PrefContext,
772  LONG fValue)
773 {
774  DWORD Index;
775  DWORD wID;
776  HWND hDlgCtrl;
777  WCHAR LineName[MIXER_LONG_NAME_CHARS];
778 
779  /* find the index of this line */
780  for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++)
781  {
782  /* get id */
783  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) * IDC_LINE_SWITCH;
796 
797  /* get dialog control */
798  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
799 
800  if (hDlgCtrl != NULL)
801  {
802  /* check state */
803  if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != fValue)
804  {
805  /* update control state */
806  SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)fValue, 0);
807  }
808  }
809  break;
810  }
811  }
812 }
813 
814 VOID
816  PPREFERENCES_CONTEXT PrefContext,
818  DWORD dwDialogID,
819  DWORD Position)
820 {
821  DWORD Index;
822  DWORD wID;
823  HWND hDlgCtrl;
824  WCHAR LineName[MIXER_LONG_NAME_CHARS];
825 
826  /* find the index of this line */
827  for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++)
828  {
829  /* get id */
830  wID = (Index + 1) * IDC_LINE_NAME;
831 
832  if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
833  {
834  /* failed to retrieve id */
835  continue;
836  }
837 
838  /* check if the line name matches */
839  if (!wcsicmp(LineName, Line->szName))
840  {
841  /* found matching line name */
842  wID = (Index + 1) * dwDialogID;
843 
844  /* get dialog control */
845  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
846 
847  if (hDlgCtrl != NULL)
848  {
849  /* check state */
850  LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
851  if (OldPosition != Position)
852  {
853  /* update control state */
855  }
856  }
857  break;
858  }
859  }
860 }
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define IDC_LINE_SLIDER_VERT
Definition: resources.h:25
#define VOLUME_TICKS
Definition: sndvol32.h:20
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define IN
Definition: typedefs.h:39
GLint GLint GLsizei width
Definition: gl.h:1546
BOOL ReadLineConfig(IN LPTSTR szDeviceName, IN LPTSTR szLineName, IN LPTSTR szControlName, OUT DWORD *Flags)
Definition: misc.c:307
#define TRUE
Definition: types.h:120
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 IDD_NORMAL_LINE
Definition: resources.h:49
#define MF_BYCOMMAND
Definition: winuser.h:202
VOID LoadDialogControls(IN PMIXER_WINDOW MixerWindow, LPRECT DialogOffset, WORD ItemCount, PDLGITEMTEMPLATE DialogItem, DWORD DialogIdMultiplier, UINT xBaseUnit, UINT yBaseUnit)
Definition: dialog.c:278
#define DEFAULT_QUALITY
Definition: wingdi.h:435
INT SndMixerGetLineName(PSND_MIXER Mixer, DWORD LineID, LPTSTR lpBuffer, UINT uSize, BOOL LongName)
Definition: mixer.c:390
#define FF_DONTCARE
Definition: wingdi.h:447
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
HDC WINAPI GetDC(_In_opt_ HWND)
#define SW_HIDE
Definition: winuser.h:762
struct _PREFERENCES_CONTEXT * PPREFERENCES_CONTEXT
#define MAXWORD
GLint dy
Definition: linetemp.h:97
static COORD Position
Definition: mouse.c:34
#define IDD_SMALL_MASTER
Definition: resources.h:50
#define BALANCE_LEFT
Definition: sndvol32.h:22
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
#define TBM_SETRANGE
Definition: commctrl.h:2033
#define IDD_NORMAL_MASTER
Definition: resources.h:48
LONG top
Definition: windef.h:307
HANDLE HWND
Definition: compat.h:13
BOOL SndMixerEnumConnections(PSND_MIXER Mixer, DWORD LineID, PFNSNDMIXENUMCONNECTIONS EnumProc, PVOID Context)
Definition: mixer.c:552
LPVOID LoadDialogResource(IN HMODULE hModule, IN LPCWSTR ResourceName, OUT LPDWORD ResourceLength)
Definition: dialog.c:21
DWORD style
Definition: winuser.h:3034
#define WS_DLGFRAME
Definition: pedump.c:626
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define assert(x)
Definition: debug.h:53
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
VOID UpdateDialogLineSliderControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD dwDialogID, DWORD Position)
Definition: dialog.c:815
#define HWND_TOP
Definition: winuser.h:1193
#define TBM_SETPOS
Definition: commctrl.h:2032
#define VOLUME_MAX
Definition: sndvol32.h:19
VOID LoadDialogCtrls(PPREFERENCES_CONTEXT PrefContext)
Definition: dialog.c:676
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
UINT_PTR WPARAM
Definition: windef.h:207
LONG left
Definition: windef.h:306
#define SWP_NOZORDER
Definition: winuser.h:1232
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WS_CLIPCHILDREN
Definition: pedump.c:619
#define DEFAULT_CHARSET
Definition: wingdi.h:383
LONG right
Definition: windef.h:308
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int32_t INT
Definition: typedefs.h:57
#define RECORD_MIXER
Definition: sndvol32.h:30
#define SetWindowLongPtr
Definition: treelist.c:70
#define IDM_ADVANCED_CONTROLS
Definition: resources.h:10
& rect
Definition: startmenu.cpp:1413
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
HFONT hFont
Definition: main.c:53
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define BALANCE_CENTER
Definition: sndvol32.h:23
BOOL WINAPI AdjustWindowRect(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL)
BOOL SndMixerQueryControls(PSND_MIXER Mixer, PUINT DisplayControls, LPMIXERLINE LineInfo, LPMIXERCONTROL *Controls)
Definition: mixer.c:112
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
VOID UpdateDialogLineSwitchControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, LONG fValue)
Definition: dialog.c:769
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define BALANCE_RIGHT
Definition: sndvol32.h:24
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define IDC_LINE_SEP
Definition: resources.h:27
#define TBM_GETPOS
Definition: commctrl.h:2027
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:425
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
LONG WINAPI GetDialogBaseUnits(VOID)
Definition: dialog.c:2152
BOOL CALLBACK EnumConnectionsCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
Definition: dialog.c:447
struct _SND_MIXER * Mixer
Definition: sndvol32.h:45
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:67
#define IDC_LINE_NAME
Definition: resources.h:22
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define TBM_SETPAGESIZE
Definition: commctrl.h:2047
smooth NULL
Definition: ftsmooth.c:416
#define BS_AUTOCHECKBOX
Definition: pedump.c:654
#define BS_CHECKBOX
Definition: pedump.c:653
_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:426
LONG cx
Definition: windef.h:334
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI SetDlgItemTextW(HWND hDlg, int nIDDlgItem, LPCWSTR lpString)
Definition: dialog.c:2832
#define BM_GETCHECK
Definition: winuser.h:1900
struct DLGTEMPLATE * LPDLGTEMPLATE
BOOL bShowExtendedControls
Definition: sndvol32.h:54
#define UlongToPtr(u)
Definition: config.h:106
VOID LoadDialog(IN HMODULE hModule, IN PMIXER_WINDOW MixerWindow, IN LPCWSTR DialogResId, IN DWORD Index)
Definition: dialog.c:329
#define RT_DIALOG
Definition: pedump.c:367
#define BALANCE_PAGE_SIZE
Definition: sndvol32.h:27
UINT DialogCount
Definition: sndvol32.h:49
#define WS_CAPTION
Definition: pedump.c:624
#define BALANCE_TICKS
Definition: sndvol32.h:26
#define BM_SETCHECK
Definition: winuser.h:1903
#define IDC_LINE_ADVANCED
Definition: resources.h:26
#define GetDlgItemText
Definition: winuser.h:5760
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MF_ENABLED
Definition: winuser.h:128
#define ADVANCED_BUTTON_HEIGHT
Definition: sndvol32.h:32
INT SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails)
Definition: mixer.c:498
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned short WORD
Definition: ntddk_ex.h:93
#define OUT_DEFAULT_PRECIS
Definition: wingdi.h:414
unsigned long DWORD
Definition: ntddk_ex.h:95
WINDOW_MODE Mode
Definition: sndvol32.h:51
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TBS_VERT
Definition: commctrl.h:2012
Definition: ncftp.h:79
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
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)
#define DS_SETFONT
Definition: winuser.h:378
#define TBM_SETTIC
Definition: commctrl.h:2031
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
Definition: mmsystem.h:320
UINT MixerId
Definition: sndvol32.h:100
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define MIXER_LONG_NAME_CHARS
Definition: mmsystem.h:294
#define wcsicmp
Definition: string.h:1152
static const WCHAR Control[]
Definition: interface.c:27
#define BALANCE_STEPS
Definition: sndvol32.h:25
WORD cdit
Definition: winuser.h:3036
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
uint16_t * LPWORD
Definition: typedefs.h:55
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
#define GWL_STYLE
Definition: winuser.h:846
TCHAR DeviceName[128]
Definition: sndvol32.h:117
static HWND hwnd[MAXHWNDS]
Definition: dialog.c:44
static HDC hDC
Definition: 3dtext.c:33
#define SW_SHOWNORMAL
Definition: winuser.h:764
LONG WINAPI GdiGetCharDimensions(HDC, LPTEXTMETRICW, LONG *)
Definition: font.c:2145
#define MIXERCONTROL_CONTROLTYPE_MUTE
Definition: mmsystem.h:384
#define IDC_LINE_SLIDER_HORZ
Definition: resources.h:24
#define WS_MINIMIZEBOX
Definition: pedump.c:631
#define MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
Definition: mmsystem.h:319
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HeapReAlloc
Definition: compat.h:402
#define IDS_SELECT
Definition: resources.h:43
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
#define VOLUME_MIN
Definition: sndvol32.h:18
#define IDD_SMALL_LINE
Definition: resources.h:51
unsigned int UINT
Definition: ndis.h:50
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
#define PLAY_MIXER
Definition: sndvol32.h:29
short cy
Definition: winuser.h:3040
#define WM_SETFONT
Definition: winuser.h:1632
#define FW_NORMAL
Definition: wingdi.h:372
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define SendMessage
Definition: winuser.h:5818
#define OUT
Definition: typedefs.h:40
uint32_t * LPDWORD
Definition: typedefs.h:58
HWND WINAPI GetDlgItem(HWND hDlg, int nIDDlgItem)
Definition: dialog.c:2189
#define HIWORD(l)
Definition: typedefs.h:246
VOID ConvertRect(LPRECT lpRect, UINT xBaseUnit, UINT yBaseUnit)
Definition: dialog.c:12
LONG bottom
Definition: windef.h:309
#define LOGPIXELSY
Definition: wingdi.h:718
#define SWP_NOMOVE
Definition: winuser.h:1229
#define VOLUME_PAGE_SIZE
Definition: sndvol32.h:21
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)
BOOL bHasExtendedControls
Definition: sndvol32.h:53
#define GetWindowLongPtr
Definition: treelist.c:73
#define MF_GRAYED
Definition: winuser.h:129
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LONG_PTR LRESULT
Definition: windef.h:209
#define wsprintf
Definition: winuser.h:5840
GLfloat units
Definition: glext.h:11727
short cx
Definition: winuser.h:3039
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_SYSMENU
Definition: pedump.c:629
HMENU WINAPI GetMenu(_In_ HWND)
LONG cy
Definition: windef.h:335
#define LOWORD(l)
Definition: pedump.c:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:403
#define MulDiv(x, y, z)
Definition: gdifloat.h:86
HINSTANCE hAppInstance
Definition: mmc.c:23
HMODULE hModule
Definition: animate.c:44
PMIXER_WINDOW MixerWindow
Definition: sndvol32.h:108
#define IDC_LINE_SWITCH
Definition: resources.h:23