ReactOS  0.4.14-dev-606-g14ebc0b
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 
413 // assert(MixerWindow->hFont);
414 
415  /* move offset after font name */
416  Offset += Length;
417 
418  /* offset is now at first dialog item control */
419  DlgItem = (PDLGITEMTEMPLATE)Offset;
420 
421  dialogRect.left = 0;
422  dialogRect.right = DlgTemplate->cx;
423  dialogRect.top = 0;
424  dialogRect.bottom = DlgTemplate->cy;
425 
426  ConvertRect(&dialogRect, xBaseUnit, yBaseUnit);
427 
428  width = dialogRect.right - dialogRect.left;
429 
430  dialogRect.left += MixerWindow->rect.right;
431  dialogRect.right += MixerWindow->rect.right;
432  dialogRect.top += MixerWindow->rect.top;
433  dialogRect.bottom += MixerWindow->rect.top;
434 
435  MixerWindow->rect.right += width;
436  if ((dialogRect.bottom - dialogRect.top) > (MixerWindow->rect.bottom - MixerWindow->rect.top))
437  MixerWindow->rect.bottom = MixerWindow->rect.top + dialogRect.bottom - dialogRect.top;
438 
439  /* now add the controls */
440  LoadDialogControls(MixerWindow, &dialogRect, DlgTemplate->cdit, DlgItem, Index, xBaseUnit, yBaseUnit);
441 }
442 
443 BOOL
444 CALLBACK
446  PSND_MIXER Mixer,
447  DWORD LineID,
449  PVOID Context)
450 {
451  WCHAR LineName[MIXER_LONG_NAME_CHARS];
452  DWORD Flags;
453  DWORD wID;
454  UINT ControlCount = 0, Index;
456  HWND hDlgCtrl;
457  PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
459 
460  if (Line->cControls == 0)
461  return TRUE;
462 
463  /* get line name */
464  if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
465  {
466  /* failed to get line name */
467  LineName[0] = L'\0';
468  }
469 
470  pVolumeDetails = HeapAlloc(GetProcessHeap(),
471  0,
472  Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
473  if (pVolumeDetails == NULL)
474  goto done;
475 
476  /* check if line is found in registry settings */
477  if (ReadLineConfig(PrefContext->DeviceName,
478  LineName,
479  Line->szName,
480  &Flags))
481  {
482  /* is it selected */
483  if (Flags != 0x4)
484  {
485  int dlgId;
486 
487  if ((Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) ||
488  (Line->dwComponentType == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES))
489  dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_MASTER : IDD_NORMAL_MASTER;
490  else
491  dlgId = (PrefContext->MixerWindow->Mode == SMALL_MODE) ? IDD_SMALL_LINE : IDD_NORMAL_LINE;
492 
493  /* load dialog resource */
494  LoadDialog(hAppInstance, PrefContext->MixerWindow, MAKEINTRESOURCE(dlgId), PrefContext->MixerWindow->DialogCount);
495 
496  /* get id */
497  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_NAME;
498 
499  /* set line name */
500  SetDlgItemTextW(PrefContext->MixerWindow->hWnd, wID, Line->szName);
501 
502  /* query controls */
503  if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) != FALSE)
504  {
505  /* now go through all controls and update their states */
506  for (Index = 0; Index < Line->cControls; Index++)
507  {
508  if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
509  {
511 
512  /* get volume control details */
513  if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
514  {
515  /* update dialog control */
516  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SWITCH;
517 
518  /* get dialog control */
519  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
520 
521  if (hDlgCtrl != NULL)
522  {
523  /* Enable the 'Mute' checkbox, if we are in play mode */
524  if (Mixer->MixerId == PLAY_MIXER)
525  EnableWindow(hDlgCtrl, TRUE);
526 
527  /* check state */
528  if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != Details.fValue)
529  {
530  /* update control state */
531  SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)Details.fValue, 0);
532  }
533  }
534  }
535  }
536  else if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
537  {
538  /* get volume control details */
539  if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
540  {
541  /* update dialog control */
542  DWORD volumePosition, volumeStep, maxVolume, i;
543  DWORD balancePosition, balanceStep;
544 
545  volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
546 
547  maxVolume = 0;
548  for (i = 0; i < Line->cChannels; i++)
549  {
550  if (pVolumeDetails[i].dwValue > maxVolume)
551  maxVolume = pVolumeDetails[i].dwValue;
552  }
553 
554  volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
555 
556  if (Line->cChannels == 1)
557  {
558  balancePosition = BALANCE_CENTER;
559  }
560  else if (Line->cChannels == 2)
561  {
562  if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
563  {
564  balancePosition = BALANCE_CENTER;
565  }
566  else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
567  {
568  balancePosition = BALANCE_RIGHT;
569  }
570  else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
571  {
572  balancePosition = BALANCE_LEFT;
573  }
574  else
575  {
576  balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
577 
578  if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
579  {
580  balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
581  balancePosition = BALANCE_RIGHT - balancePosition;
582  }
583  else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
584  {
585  balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
586  balancePosition = BALANCE_LEFT + balancePosition;
587  }
588  }
589  }
590 
591  /* Set the volume trackbar */
592  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_VERT;
593 
594  /* get dialog control */
595  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
596 
597  if (hDlgCtrl != NULL)
598  {
599  /* check state */
600  LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
601 
602  /* Enable the volume trackbar */
603  EnableWindow(hDlgCtrl, TRUE);
604 
605  if (OldPosition != (VOLUME_MAX - volumePosition))
606  {
607  /* update control state */
608  SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - volumePosition);
609  }
610  }
611 
612  if (Line->cChannels == 2)
613  {
614  /* Set the balance trackbar */
615  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_SLIDER_HORZ;
616 
617  /* get dialog control */
618  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
619 
620  if (hDlgCtrl != NULL)
621  {
622  /* check state */
623  LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
624 
625  /* Enable the balance trackbar */
626  EnableWindow(hDlgCtrl, TRUE);
627 
628  if (OldPosition != balancePosition)
629  {
630  /* update control state */
631  SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, balancePosition);
632  }
633  }
634  }
635  }
636  }
637  else
638  {
639  if (PrefContext->MixerWindow->Mode == NORMAL_MODE)
640  {
641  PrefContext->MixerWindow->bHasExtendedControls = TRUE;
642 
643  wID = (PrefContext->MixerWindow->DialogCount + 1) * IDC_LINE_ADVANCED;
644 
645  /* get dialog control */
646  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
647  if (hDlgCtrl != NULL)
648  {
649  ShowWindow(hDlgCtrl,
651  }
652  }
653  }
654  }
655 
656  /* free controls */
658  }
659 
660  /* increment dialog count */
661  PrefContext->MixerWindow->DialogCount++;
662  }
663  }
664 
665 done:
666  /* Free the volume details */
667  if (pVolumeDetails)
668  HeapFree(GetProcessHeap(), 0, pVolumeDetails);
669 
670  return TRUE;
671 }
672 
673 VOID
675  PPREFERENCES_CONTEXT PrefContext)
676 {
677  WCHAR szBuffer[64];
678  HWND hDlgCtrl;
679  RECT statusRect;
680  UINT i;
681  LONG dy;
682 
683  /* set dialog count to zero */
684  PrefContext->MixerWindow->DialogCount = 0;
685  PrefContext->MixerWindow->bHasExtendedControls = FALSE;
686  SetRectEmpty(&PrefContext->MixerWindow->rect);
687 
688  /* enumerate controls */
689  SndMixerEnumConnections(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, EnumConnectionsCallback, (PVOID)PrefContext);
690 
691  /* Update the 'Advanced Controls' menu item */
692  EnableMenuItem(GetMenu(PrefContext->MixerWindow->hWnd),
694  MF_BYCOMMAND | (PrefContext->MixerWindow->bHasExtendedControls ? MF_ENABLED : MF_GRAYED));
695 
696  /* Add some height for the status bar */
697  if (PrefContext->MixerWindow->hStatusBar)
698  {
699  GetWindowRect(PrefContext->MixerWindow->hStatusBar, &statusRect);
700  PrefContext->MixerWindow->rect.bottom += (statusRect.bottom - statusRect.top);
701  }
702 
703  /* Add height of the 'Advanced' button */
704  dy = MulDiv(ADVANCED_BUTTON_HEIGHT, PrefContext->MixerWindow->baseUnit.cy, 8);
705  if (PrefContext->MixerWindow->bShowExtendedControls && PrefContext->MixerWindow->bHasExtendedControls)
706  PrefContext->MixerWindow->rect.bottom += dy;
707 
708  /* now move the window */
710  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);
711 
712  /* Move the status bar */
713  if (PrefContext->MixerWindow->hStatusBar)
714  {
715  SetWindowPos(PrefContext->MixerWindow->hStatusBar,
716  HWND_TOP,
717  statusRect.left,
718  PrefContext->MixerWindow->rect.bottom - (statusRect.bottom - statusRect.top),
719  PrefContext->MixerWindow->rect.right - PrefContext->MixerWindow->rect.left,
720  statusRect.bottom - statusRect.top,
721  SWP_NOZORDER);
722  }
723 
724  if (PrefContext->MixerWindow->MixerId == RECORD_MIXER)
725  LoadStringW(hAppInstance, IDS_SELECT, szBuffer, ARRAYSIZE(szBuffer));
726 
727  for (i = 0; i < PrefContext->MixerWindow->DialogCount; i++)
728  {
729  if (PrefContext->MixerWindow->MixerId == RECORD_MIXER)
730  {
731  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, (i + 1) * IDC_LINE_SWITCH);
732 
733  /* Turn the autocheckbox into a checkbox */
735 
736  /* Change text from 'Mute' to 'Select' */
737  SetWindowTextW(hDlgCtrl, szBuffer);
738  }
739 
740  /* Resize the vertical line separator */
741  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, (i + 1) * IDC_LINE_SEP);
742  if (hDlgCtrl != NULL)
743  {
744  GetWindowRect(hDlgCtrl, &statusRect);
745  if (PrefContext->MixerWindow->bShowExtendedControls && PrefContext->MixerWindow->bHasExtendedControls)
746  statusRect.bottom += dy;
747 
748  SetWindowPos(hDlgCtrl,
749  HWND_TOP,
750  0,
751  0,
752  statusRect.right - statusRect.left,
753  statusRect.bottom - statusRect.top,
755  }
756  }
757 
758  /* Hide the last line separator */
759  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, IDC_LINE_SEP * PrefContext->MixerWindow->DialogCount);
760  if (hDlgCtrl != NULL)
761  {
762  ShowWindow(hDlgCtrl, SW_HIDE);
763  }
764 }
765 
766 VOID
768  PPREFERENCES_CONTEXT PrefContext,
770  LONG fValue)
771 {
772  DWORD Index;
773  DWORD wID;
774  HWND hDlgCtrl;
775  WCHAR LineName[MIXER_LONG_NAME_CHARS];
776 
777  /* find the index of this line */
778  for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++)
779  {
780  /* get id */
781  wID = (Index + 1) * IDC_LINE_NAME;
782 
783  if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
784  {
785  /* failed to retrieve id */
786  continue;
787  }
788 
789  /* check if the line name matches */
790  if (!wcsicmp(LineName, Line->szName))
791  {
792  /* found matching line name */
793  wID = (Index + 1) * IDC_LINE_SWITCH;
794 
795  /* get dialog control */
796  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
797 
798  if (hDlgCtrl != NULL)
799  {
800  /* check state */
801  if (SendMessageW(hDlgCtrl, BM_GETCHECK, 0, 0) != fValue)
802  {
803  /* update control state */
804  SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)fValue, 0);
805  }
806  }
807  break;
808  }
809  }
810 }
811 
812 VOID
814  PPREFERENCES_CONTEXT PrefContext,
816  DWORD dwDialogID,
817  DWORD Position)
818 {
819  DWORD Index;
820  DWORD wID;
821  HWND hDlgCtrl;
822  WCHAR LineName[MIXER_LONG_NAME_CHARS];
823 
824  /* find the index of this line */
825  for (Index = 0; Index < PrefContext->MixerWindow->DialogCount; Index++)
826  {
827  /* get id */
828  wID = (Index + 1) * IDC_LINE_NAME;
829 
830  if (GetDlgItemText(PrefContext->MixerWindow->hWnd, wID, LineName, MIXER_LONG_NAME_CHARS) == 0)
831  {
832  /* failed to retrieve id */
833  continue;
834  }
835 
836  /* check if the line name matches */
837  if (!wcsicmp(LineName, Line->szName))
838  {
839  /* found matching line name */
840  wID = (Index + 1) * dwDialogID;
841 
842  /* get dialog control */
843  hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
844 
845  if (hDlgCtrl != NULL)
846  {
847  /* check state */
848  LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
849  if (OldPosition != Position)
850  {
851  /* update control state */
853  }
854  }
855  break;
856  }
857  }
858 }
#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:38
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:197
#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:813
#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:674
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:56
#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:63
#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:767
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
LONG WINAPI GetDialogBaseUnits(VOID)
Definition: dialog.c:2146
BOOL CALLBACK EnumConnectionsCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
Definition: dialog.c:445
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:2826
#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:403
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:97
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:54
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
#define GWL_STYLE
Definition: winuser.h:846
TCHAR DeviceName[128]
Definition: sndvol32.h:114
static HWND hwnd[MAXHWNDS]
Definition: dialog.c:48
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:401
#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:39
uint32_t * LPDWORD
Definition: typedefs.h:57
HWND WINAPI GetDlgItem(HWND hDlg, int nIDDlgItem)
Definition: dialog.c:2183
#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:402
#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:105
#define IDC_LINE_SWITCH
Definition: resources.h:23