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
12 ConvertRect(LPRECT lpRect
, UINT xBaseUnit
, UINT yBaseUnit
)
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);
23 IN LPCWSTR ResourceName
,
24 OUT LPDWORD ResourceLength
)
31 hSrc
= FindResourceW(hModule
, ResourceName
, (LPCWSTR
)RT_DIALOG
);
35 /* failed to find resource */
39 /* now load the resource */
40 hRes
= LoadResource(hAppInstance
, hSrc
);
43 /* failed to load resource */
47 /* now lock the resource */
48 Result
= LockResource(hRes
);
52 /* failed to lock resource */
58 /* store output length */
59 *ResourceLength
= SizeofResource(hAppInstance
, hSrc
);
70 IN LPRECT DialogOffset
,
71 IN PDLGITEMTEMPLATE DialogItem
,
72 IN DWORD DialogIdMultiplier
,
79 LPWSTR ClassName
, WindowName
= NULL
;
83 /* initialize client rectangle */
84 rect
.left
= DialogItem
->x
;
85 rect
.top
= DialogItem
->y
;
86 rect
.right
= DialogItem
->x
+ DialogItem
->cx
;
87 rect
.bottom
= DialogItem
->y
+ DialogItem
->cy
;
89 /* Convert Dialog units to pixes */
90 ConvertRect(&rect
, xBaseUnit
, yBaseUnit
);
92 rect
.left
+= DialogOffset
->left
;
93 rect
.right
+= DialogOffset
->left
;
94 rect
.top
+= DialogOffset
->top
;
95 rect
.bottom
+= DialogOffset
->top
;
97 /* move offset after dialog item */
98 Offset
= (LPWORD
)(DialogItem
+ 1);
100 if (*Offset
== 0xFFFF)
102 /* class is encoded as type */
105 /* get control type */
109 ClassName
= L
"button";
110 WindowName
= (LPWSTR
)(Offset
+ 1);
113 ClassName
= L
"static";
114 WindowName
= (LPWSTR
)(Offset
+ 1);
124 /* class name is encoded as string */
125 ClassName
= (LPWSTR
)Offset
;
127 /* move offset to the end of class string */
128 Offset
+= wcslen(ClassName
);
130 /* get window name */
131 WindowName
= (LPWSTR
)(Offset
+ 1);
134 /* move offset past class type/string */
137 if (DialogItem
->id
== MAXWORD
)
139 /* id is not important */
140 wID
= DialogItem
->id
;
145 wID
= DialogItem
->id
* (DialogIdMultiplier
+ 1);
148 /* now create the window */
149 hwnd
= CreateWindowExW(DialogItem
->dwExtendedStyle
,
155 rect
.right
- rect
.left
,
156 rect
.bottom
- rect
.top
,
168 /* check if this the track bar */
169 if (!wcsicmp(ClassName
, L
"msctls_trackbar32"))
172 SendMessage(hwnd
, TBM_SETRANGE
, (WPARAM
) TRUE
, (LPARAM
) MAKELONG(0, 5));
174 /* set up page size */
175 SendMessage(hwnd
, TBM_SETPAGESIZE
, 0, (LPARAM
) 1);
177 /* set available range */
178 //SendMessage(hwnd, TBM_SETSEL, (WPARAM) FALSE, (LPARAM) MAKELONG(0, 5));
181 SendMessage(hwnd
, TBM_SETPOS
, (WPARAM
) TRUE
, (LPARAM
) 0);
184 else if (!wcsicmp(ClassName
, L
"static") || !wcsicmp(ClassName
, L
"button"))
187 SendMessageW(hwnd
, WM_SETFONT
, (WPARAM
)hFont
, TRUE
);
190 //ShowWindow(hwnd, SW_SHOWNORMAL);
192 if (WindowName
!= NULL
)
194 /* move offset past window name */
195 Offset
+= wcslen(WindowName
) + 1;
198 /* check if there is additional data */
201 /* no additional data */
206 /* FIXME: Determine whether this should be "Offset += 1 + *Offset" to explicitly skip the data count too. */
207 /* skip past additional data */
211 /* make sure next template is word-aligned */
212 Offset
= (LPWORD
)(((ULONG_PTR
)Offset
+ 3) & ~3);
220 IN PMIXER_WINDOW MixerWindow
,
223 PDLGITEMTEMPLATE DialogItem
,
224 DWORD DialogIdMultiplier
,
234 if (MixerWindow
->Window
)
235 MixerWindow
->Window
= (HWND
*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, MixerWindow
->Window
, (MixerWindow
->WindowCount
+ ItemCount
) * sizeof(HWND
));
237 MixerWindow
->Window
= (HWND
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ItemCount
* sizeof(HWND
));
238 if (!MixerWindow
->Window
)
244 /* enumerate now all controls */
245 for (Index
= 0; Index
< ItemCount
; Index
++)
248 Offset
= AddDialogControl(MixerWindow
->hWnd
, &MixerWindow
->Window
[MixerWindow
->WindowCount
], DialogOffset
, DialogItem
, DialogIdMultiplier
, MixerWindow
->hFont
, xBaseUnit
, yBaseUnit
);
253 /* move dialog item to new offset */
254 DialogItem
=(PDLGITEMTEMPLATE
)Offset
;
256 /* increment window count */
257 MixerWindow
->WindowCount
++;
264 IN PMIXER_WINDOW MixerWindow
,
265 IN LPCWSTR DialogResId
,
268 LPDLGTEMPLATE DlgTemplate
;
269 PDLGITEMTEMPLATE DlgItem
;
277 DWORD units
= GetDialogBaseUnits();
278 UINT xBaseUnit
= LOWORD(units
);
279 UINT yBaseUnit
= HIWORD(units
);
281 /* first load the dialog resource */
282 DlgTemplate
= (LPDLGTEMPLATE
)LoadDialogResource(hModule
, DialogResId
, NULL
);
285 /* failed to load resource */
289 /* Now walk past the dialog header */
290 Offset
= (LPWORD
)(DlgTemplate
+ 1);
292 /* FIXME: support menu */
293 assert(*Offset
== 0);
296 /* FIXME: support classes */
297 assert(*Offset
== 0);
300 /* FIXME: support titles */
301 assert(*Offset
== 0);
308 /* calculate font length */
309 Length
= wcslen((LPWSTR
)Offset
) + 1;
310 assert(Length
< (sizeof(FontName
) / sizeof(WCHAR
)));
313 wcscpy(FontName
, (LPWSTR
)Offset
);
315 if (DlgTemplate
->style
& DS_SETFONT
)
321 if (!MixerWindow
->hFont
)
323 int pixels
= MulDiv(FontSize
, GetDeviceCaps(hDC
, LOGPIXELSY
), 72);
324 MixerWindow
->hFont
= CreateFontW(-pixels
, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
, FF_DONTCARE
, FontName
);
327 if (MixerWindow
->hFont
)
332 hOldFont
= SelectObject(hDC
, MixerWindow
->hFont
);
333 charSize
.cx
= GdiGetCharDimensions(hDC
, NULL
, &charSize
.cy
);
336 xBaseUnit
= charSize
.cx
;
337 yBaseUnit
= charSize
.cy
;
339 SelectObject(hDC
, hOldFont
);
343 // assert(MixerWindow->hFont);
345 /* move offset after font name */
348 /* offset is now at first dialog item control */
349 DlgItem
= (PDLGITEMTEMPLATE
)Offset
;
352 dialogRect
.right
= DlgTemplate
->cx
;
354 dialogRect
.bottom
= DlgTemplate
->cy
;
356 ConvertRect(&dialogRect
, xBaseUnit
, yBaseUnit
);
358 width
= dialogRect
.right
- dialogRect
.left
;
360 dialogRect
.left
+= MixerWindow
->rect
.right
;
361 dialogRect
.right
+= MixerWindow
->rect
.right
;
362 dialogRect
.top
+= MixerWindow
->rect
.top
;
363 dialogRect
.bottom
+= MixerWindow
->rect
.top
;
365 MixerWindow
->rect
.right
+= width
;
366 if ((dialogRect
.bottom
- dialogRect
.top
) > (MixerWindow
->rect
.bottom
- MixerWindow
->rect
.top
))
367 MixerWindow
->rect
.bottom
= MixerWindow
->rect
.top
+ dialogRect
.bottom
- dialogRect
.top
;
369 /* now add the controls */
370 LoadDialogControls(MixerWindow
, &dialogRect
, DlgTemplate
->cdit
, DlgItem
, Index
, xBaseUnit
, yBaseUnit
);
375 EnumConnectionsCallback(
381 WCHAR LineName
[MIXER_LONG_NAME_CHARS
];
384 UINT ControlCount
= 0, Index
;
385 LPMIXERCONTROL Control
= NULL
;
387 PPREFERENCES_CONTEXT PrefContext
= (PPREFERENCES_CONTEXT
)Context
;
389 if (Line
->cControls
!= 0)
392 if (SndMixerGetLineName(PrefContext
->MixerWindow
->Mixer
, PrefContext
->SelectedLine
, LineName
, MIXER_LONG_NAME_CHARS
, TRUE
) == -1)
394 /* failed to get line name */
398 /* check if line is found in registry settings */
399 if (ReadLineConfig(PrefContext
->DeviceName
,
407 int dlgId
= (PrefContext
->MixerWindow
->Mode
== SMALL_MODE
) ? IDD_SMALL_MASTER
: IDD_NORMAL_MASTER
;
409 /* load dialog resource */
410 LoadDialog(hAppInstance
, PrefContext
->MixerWindow
, MAKEINTRESOURCE(dlgId
), PrefContext
->Count
);
413 wID
= (PrefContext
->Count
+ 1) * IDC_LINE_NAME
;
416 SetDlgItemTextW(PrefContext
->MixerWindow
->hWnd
, wID
, Line
->szName
);
419 if (SndMixerQueryControls(Mixer
, &ControlCount
, Line
, &Control
) != FALSE
)
421 /* now go through all controls and update their states */
422 for(Index
= 0; Index
< ControlCount
; Index
++)
424 if ((Control
[Index
].dwControlType
& MIXERCONTROL_CT_CLASS_MASK
) == MIXERCONTROL_CT_CLASS_SWITCH
)
426 MIXERCONTROLDETAILS_BOOLEAN Details
;
428 /* get volume control details */
429 if (SndMixerGetVolumeControlDetails(Mixer
, Control
[Index
].dwControlID
, sizeof(MIXERCONTROLDETAILS_BOOLEAN
), (LPVOID
)&Details
) != -1)
431 /* update dialog control */
432 wID
= (PrefContext
->Count
+ 1) * IDC_LINE_SWITCH
;
434 /* get dialog control */
435 hDlgCtrl
= GetDlgItem(PrefContext
->MixerWindow
->hWnd
, wID
);
437 if (hDlgCtrl
!= NULL
)
440 if (SendMessageW(hDlgCtrl
, BM_GETCHECK
, 0, 0) != Details
.fValue
)
442 /* update control state */
443 SendMessageW(hDlgCtrl
, BM_SETCHECK
, (WPARAM
)Details
.fValue
, 0);
448 else if ((Control
[Index
].dwControlType
& MIXERCONTROL_CT_CLASS_MASK
) == MIXERCONTROL_CT_CLASS_FADER
)
450 MIXERCONTROLDETAILS_UNSIGNED Details
;
452 /* get volume control details */
453 if (SndMixerGetVolumeControlDetails(Mixer
, Control
[Index
].dwControlID
, sizeof(MIXERCONTROLDETAILS_UNSIGNED
), (LPVOID
)&Details
) != -1)
455 /* update dialog control */
457 DWORD Step
= 0x10000 / 5;
459 /* FIXME: give me granularity */
460 Position
= 5 - (Details
.dwValue
/ Step
);
462 /* FIXME support left - right slider */
463 wID
= (PrefContext
->Count
+ 1) * IDC_LINE_SLIDER_VERT
;
465 /* get dialog control */
466 hDlgCtrl
= GetDlgItem(PrefContext
->MixerWindow
->hWnd
, wID
);
468 if (hDlgCtrl
!= NULL
)
471 LRESULT OldPosition
= SendMessageW(hDlgCtrl
, TBM_GETPOS
, 0, 0);
472 if (OldPosition
!= Position
)
474 /* update control state */
475 SendMessageW(hDlgCtrl
, TBM_SETPOS
, (WPARAM
)TRUE
, Position
+ Index
);
483 HeapFree(GetProcessHeap(), 0, Control
);
486 /* increment dialog count */
487 PrefContext
->Count
++;
496 PPREFERENCES_CONTEXT PrefContext
)
501 /* set dialog count to zero */
502 PrefContext
->Count
= 0;
504 SetRectEmpty(&PrefContext
->MixerWindow
->rect
);
506 /* enumerate controls */
507 SndMixerEnumConnections(PrefContext
->MixerWindow
->Mixer
, PrefContext
->SelectedLine
, EnumConnectionsCallback
, (PVOID
)PrefContext
);
509 if (PrefContext
->MixerWindow
->hStatusBar
)
511 GetWindowRect(PrefContext
->MixerWindow
->hStatusBar
, &statusRect
);
512 PrefContext
->MixerWindow
->rect
.bottom
+= (statusRect
.bottom
- statusRect
.top
);
515 /* now move the window */
516 AdjustWindowRect(&PrefContext
->MixerWindow
->rect
, WS_DLGFRAME
| WS_CAPTION
| WS_MINIMIZEBOX
| WS_SYSMENU
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
| WS_VISIBLE
, TRUE
);
517 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
);
519 /* get last line separator */
520 hDlgCtrl
= GetDlgItem(PrefContext
->MixerWindow
->hWnd
, IDC_LINE_SEP
* PrefContext
->Count
);
522 if (hDlgCtrl
!= NULL
)
524 /* hide last separator */
525 ShowWindow(hDlgCtrl
, SW_HIDE
);
530 UpdateDialogLineSwitchControl(
531 PPREFERENCES_CONTEXT PrefContext
,
538 WCHAR LineName
[MIXER_LONG_NAME_CHARS
];
540 /* find the index of this line */
541 for(Index
= 0; Index
< PrefContext
->Count
; Index
++)
544 wID
= (Index
+ 1) * IDC_LINE_NAME
;
546 if (GetDlgItemText(PrefContext
->MixerWindow
->hWnd
, wID
, LineName
, MIXER_LONG_NAME_CHARS
) == 0)
548 /* failed to retrieve id */
552 /* check if the line name matches */
553 if (!wcsicmp(LineName
, Line
->szName
))
555 /* found matching line name */
556 wID
= (Index
+ 1) * IDC_LINE_SWITCH
;
558 /* get dialog control */
559 hDlgCtrl
= GetDlgItem(PrefContext
->MixerWindow
->hWnd
, wID
);
561 if (hDlgCtrl
!= NULL
)
564 if (SendMessageW(hDlgCtrl
, BM_GETCHECK
, 0, 0) != fValue
)
566 /* update control state */
567 SendMessageW(hDlgCtrl
, BM_SETCHECK
, (WPARAM
)fValue
, 0);
576 UpdateDialogLineSliderControl(
577 PPREFERENCES_CONTEXT PrefContext
,
586 WCHAR LineName
[MIXER_LONG_NAME_CHARS
];
588 /* find the index of this line */
589 for(Index
= 0; Index
< PrefContext
->Count
; Index
++)
592 wID
= (Index
+ 1) * IDC_LINE_NAME
;
594 if (GetDlgItemText(PrefContext
->MixerWindow
->hWnd
, wID
, LineName
, MIXER_LONG_NAME_CHARS
) == 0)
596 /* failed to retrieve id */
600 /* check if the line name matches */
601 if (!wcsicmp(LineName
, Line
->szName
))
603 /* found matching line name */
604 wID
= (Index
+ 1) * dwDialogID
;
606 /* get dialog control */
607 hDlgCtrl
= GetDlgItem(PrefContext
->MixerWindow
->hWnd
, wID
);
609 if (hDlgCtrl
!= NULL
)
612 LRESULT OldPosition
= SendMessageW(hDlgCtrl
, TBM_GETPOS
, 0, 0);
613 if (OldPosition
!= Position
)
615 /* update control state */
616 SendMessageW(hDlgCtrl
, TBM_SETPOS
, (WPARAM
)TRUE
, Position
+ Index
);