2 * ReactOS Sound Volume Control
3 * Copyright (C) 2004-2005 Thomas Weidenmueller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS Sound Volume Control
23 * FILE: subsys/system/sndvol32/sndvol32.c
24 * PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
28 HINSTANCE hAppInstance
;
33 PREFERENCES_CONTEXT Preferences
;
35 #define GetDialogData(hwndDlg, type) \
36 ( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)
37 #define GetWindowData(hwnd, type) \
38 ( P##type )GetWindowLongPtr((hwnd), GWL_USERDATA)
40 /******************************************************************************/
44 typedef struct _PREFERENCES_FILL_DEVICES
46 PPREFERENCES_CONTEXT PrefContext
;
49 } PREFERENCES_FILL_DEVICES
, *PPREFERENCES_FILL_DEVICES
;
52 FillDeviceComboBox(PSND_MIXER Mixer
,
58 PPREFERENCES_FILL_DEVICES FillContext
= (PPREFERENCES_FILL_DEVICES
)Context
;
60 UNREFERENCED_PARAMETER(Mixer
);
62 lres
= SendMessage(FillContext
->hComboBox
,
68 /* save the index so we don't screw stuff when the combobox is sorted... */
69 SendMessage(FillContext
->hComboBox
,
74 if (Id
== FillContext
->Selected
)
76 SendMessage(FillContext
->hComboBox
,
87 PrefDlgAddLine(PSND_MIXER Mixer
,
92 PPREFERENCES_CONTEXT PrefContext
= (PPREFERENCES_CONTEXT
)Context
;
94 UNREFERENCED_PARAMETER(Mixer
);
95 UNREFERENCED_PARAMETER(DisplayControls
);
97 switch (Line
->dwComponentType
)
99 case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
:
100 if (PrefContext
->PlaybackID
== (DWORD
)-1)
102 PrefContext
->PlaybackID
= Line
->dwLineID
;
104 if (PrefContext
->SelectedLine
== (DWORD
)-1)
106 PrefContext
->SelectedLine
= Line
->dwLineID
;
110 goto AddToOthersLines
;
114 case MIXERLINE_COMPONENTTYPE_DST_WAVEIN
:
115 if (PrefContext
->RecordingID
== (DWORD
)-1)
117 PrefContext
->RecordingID
= Line
->dwLineID
;
119 if (PrefContext
->SelectedLine
== (DWORD
)-1)
121 PrefContext
->SelectedLine
= Line
->dwLineID
;
125 goto AddToOthersLines
;
134 if (PrefContext
->SelectedLine
== (DWORD
)-1)
136 PrefContext
->SelectedLine
= Line
->dwLineID
;
140 hwndCbOthers
= GetDlgItem(PrefContext
->hwndDlg
,
143 lres
= SendMessage(hwndCbOthers
,
146 (LPARAM
)Line
->szName
);
149 SendMessage(hwndCbOthers
,
154 PrefContext
->OtherLines
++;
164 PrefDlgAddConnection(PSND_MIXER Mixer
,
169 PPREFERENCES_CONTEXT PrefContext
= (PPREFERENCES_CONTEXT
)Context
;
174 UNREFERENCED_PARAMETER(Mixer
);
175 UNREFERENCED_PARAMETER(LineID
);
177 if (Line
->cControls
!= 0)
179 hwndControls
= GetDlgItem(PrefContext
->hwndDlg
,
182 lvi
.mask
= LVIF_TEXT
| LVIF_PARAM
;
183 lvi
.iItem
= PrefContext
->tmp
++;
185 lvi
.pszText
= Line
->szName
;
186 lvi
.lParam
= (LPARAM
)Line
->dwSource
;
188 i
= SendMessage(hwndControls
,
194 TCHAR LineName
[MIXER_LONG_NAME_CHARS
];
196 BOOL SelLine
= FALSE
;
198 if (SndMixerGetLineName(PrefContext
->Mixer
,
199 PrefContext
->SelectedLine
,
201 MIXER_LONG_NAME_CHARS
,
204 LineName
[0] = TEXT('\0');
207 if (ReadLineConfig(PrefContext
->DeviceName
,
218 ListView_SetCheckState(hwndControls
,
228 UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context
,
231 INT OldID
, MixerID
= 0;
234 /* select the mixer */
235 DeviceCbIndex
= SendDlgItemMessage(Context
->hwndDlg
,
240 if (DeviceCbIndex
!= CB_ERR
)
242 MixerID
= SendDlgItemMessage(Context
->hwndDlg
,
247 if (MixerID
== CB_ERR
)
253 OldID
= Context
->Selected
;
254 if (MixerID
!= OldID
&&
255 SndMixerSelect(Context
->Mixer
,
258 Context
->Selected
= SndMixerGetSelection(Context
->Mixer
);
260 /* update the controls */
261 Context
->PlaybackID
= (DWORD
)-1;
262 Context
->RecordingID
= (DWORD
)-1;
263 Context
->OtherLines
= 0;
264 Context
->SelectedLine
= (DWORD
)-1;
266 SndMixerGetProductName(Context
->Mixer
,
268 sizeof(Context
->DeviceName
) / sizeof(Context
->DeviceName
[0]));
270 if (SndMixerEnumLines(Context
->Mixer
,
276 /* enable/disable controls and make default selection */
277 EnableWindow(GetDlgItem(Context
->hwndDlg
,
279 Context
->PlaybackID
!= (DWORD
)-1);
280 CheckDlgButton(Context
->hwndDlg
,
282 (Context
->PlaybackID
!= (DWORD
)-1 && SelBox
++ == 0) ?
283 BST_CHECKED
: BST_UNCHECKED
);
285 EnableWindow(GetDlgItem(Context
->hwndDlg
,
287 Context
->RecordingID
!= (DWORD
)-1);
288 CheckDlgButton(Context
->hwndDlg
,
290 (Context
->RecordingID
!= (DWORD
)-1 && SelBox
++ == 0) ?
291 BST_CHECKED
: BST_UNCHECKED
);
293 if (Context
->OtherLines
!= 0)
295 /* select the first item in the other lines combo box by default */
296 SendDlgItemMessage(Context
->hwndDlg
,
302 EnableWindow(GetDlgItem(Context
->hwndDlg
,
305 EnableWindow(GetDlgItem(Context
->hwndDlg
,
307 Context
->OtherLines
!= 0);
308 CheckDlgButton(Context
->hwndDlg
,
310 (Context
->OtherLines
!= 0 && SelBox
++ == 0) ?
311 BST_CHECKED
: BST_UNCHECKED
);
313 /* disable the OK button if the device doesn't have any lines */
314 EnableWindow(GetDlgItem(Context
->hwndDlg
,
316 Context
->PlaybackID
!= (DWORD
)-1 ||
317 Context
->RecordingID
!= (DWORD
)-1 ||
318 Context
->OtherLines
!= 0);
320 LineID
= Context
->SelectedLine
;
324 /* update the line sources list */
325 if ((MixerID
!= OldID
&& Context
->SelectedLine
!= (DWORD
)-1) ||
326 (Context
->SelectedLine
!= LineID
&& LineID
!= (DWORD
)-1))
328 Context
->SelectedLine
= LineID
;
330 (void)ListView_DeleteAllItems(GetDlgItem(Context
->hwndDlg
,
334 SndMixerEnumConnections(Context
->Mixer
,
336 PrefDlgAddConnection
,
343 WriteLineSettings(PREFERENCES_CONTEXT Context
, HWND hwndDlg
)
347 WCHAR LineName
[MIXER_LONG_NAME_CHARS
];
348 WCHAR DestinationName
[MIXER_LONG_NAME_CHARS
];
352 hwndControls
= GetDlgItem(hwndDlg
, IDC_CONTROLS
);
354 /* get list item count */
355 Count
= ListView_GetItemCount(hwndControls
);
360 if (SndMixerGetLineName(Preferences
.MixerWindow
->Mixer
, Preferences
.SelectedLine
, DestinationName
, MIXER_LONG_NAME_CHARS
, TRUE
) == -1)
362 /* failed to get destination line name */
366 /* allocate line states array */
367 for(Index
= 0; Index
< Count
; Index
++)
373 ListView_GetItemText(hwndControls
, Index
, 0, LineName
, MIXER_LONG_NAME_CHARS
);
375 /* make sure it is null terminated */
376 LineName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
378 /* get check state */
379 Flags
= (ListView_GetCheckState(hwndControls
, Index
) == 0 ? 0x4 : 0);
381 /* write configuration */
382 WriteLineConfig(Preferences
.DeviceName
, DestinationName
, LineName
, Flags
);
388 static INT_PTR CALLBACK
389 DlgPreferencesProc(HWND hwndDlg
,
394 PPREFERENCES_CONTEXT Context
;
400 Context
= GetDialogData(hwndDlg
,
401 PREFERENCES_CONTEXT
);
402 switch (LOWORD(wParam
))
404 case IDC_MIXERDEVICE
:
406 if (HIWORD(wParam
) == CBN_SELCHANGE
)
408 UpdatePrefDlgControls(Context
,
416 if (HIWORD(wParam
) == CBN_SELCHANGE
)
421 Index
= SendDlgItemMessage(hwndDlg
,
428 LineID
= SendDlgItemMessage(hwndDlg
,
433 if (LineID
!= CB_ERR
)
435 UpdatePrefDlgControls(Context
,
445 UpdatePrefDlgControls(Context
,
446 Context
->PlaybackID
);
447 EnableWindow(GetDlgItem(hwndDlg
,
455 UpdatePrefDlgControls(Context
,
456 Context
->RecordingID
);
457 EnableWindow(GetDlgItem(hwndDlg
,
468 EnableWindow(GetDlgItem(hwndDlg
,
472 LineCbIndex
= SendDlgItemMessage(hwndDlg
,
477 if (LineCbIndex
!= CB_ERR
)
479 LineID
= SendDlgItemMessage(hwndDlg
,
484 if (LineID
!= CB_ERR
)
486 UpdatePrefDlgControls(Context
,
495 /* write line settings */
496 WriteLineSettings(Preferences
, hwndDlg
);
512 PREFERENCES_FILL_DEVICES FillDevContext
;
517 SetWindowLongPtr(hwndDlg
,
520 Context
= (PPREFERENCES_CONTEXT
)((LONG_PTR
)lParam
);
521 Context
->hwndDlg
= hwndDlg
;
522 Context
->Mixer
= SndMixerCreate(hwndDlg
);
523 Context
->Selected
= (UINT
)-1;
525 FillDevContext
.PrefContext
= Context
;
526 FillDevContext
.hComboBox
= GetDlgItem(hwndDlg
,
528 FillDevContext
.Selected
= SndMixerGetSelection(Context
->Mixer
);
529 SndMixerEnumProducts(Context
->Mixer
,
533 /* initialize the list view control */
534 hwndControls
= GetDlgItem(hwndDlg
,
536 (void)ListView_SetExtendedListViewStyle(hwndControls
,
539 GetClientRect(hwndControls
,
541 lvc
.mask
= LVCF_TEXT
| LVCF_WIDTH
;
542 lvc
.pszText
= TEXT("");
543 lvc
.cx
= rcClient
.right
;
544 SendMessage(hwndControls
,
549 /* update all controls */
550 UpdatePrefDlgControls(Context
,
557 Context
= GetDialogData(hwndDlg
,
558 PREFERENCES_CONTEXT
);
559 if (Context
->Mixer
!= NULL
)
561 SndMixerDestroy(Context
->Mixer
);
578 /******************************************************************************/
581 DeleteMixerWindowControls(PMIXER_WINDOW MixerWindow
)
585 for(Index
= 0; Index
< MixerWindow
->WindowCount
; Index
++)
587 /* destroys the window */
588 DestroyWindow(MixerWindow
->Window
[Index
]);
592 HeapFree(GetProcessHeap(), 0, MixerWindow
->Window
);
595 MixerWindow
->Window
= NULL
;
596 MixerWindow
->WindowCount
= 0;
600 RebuildMixerWindowControls(PPREFERENCES_CONTEXT PrefContext
)
602 /* delete existing mixer controls */
603 DeleteMixerWindowControls(PrefContext
->MixerWindow
);
605 /* load new mixer controls */
606 LoadDialogCtrls(PrefContext
);
614 SetVolumeCallback(PSND_MIXER Mixer
, DWORD LineID
, LPMIXERLINE Line
, PVOID Ctx
)
616 UINT ControlCount
= 0, Index
;
617 LPMIXERCONTROL Control
= NULL
;
618 MIXERCONTROLDETAILS_UNSIGNED uDetails
;
619 MIXERCONTROLDETAILS_BOOLEAN bDetails
;
620 PSET_VOLUME_CONTEXT Context
= (PSET_VOLUME_CONTEXT
)Ctx
;
622 /* check if the line name is equal */
623 if (wcsicmp(Line
->szName
, Context
->LineName
))
630 if (SndMixerQueryControls(Mixer
, &ControlCount
, Line
, &Control
) == FALSE
)
632 /* failed to query for controls */
636 /* now go through all controls and compare control ids */
637 for(Index
= 0; Index
< ControlCount
; Index
++)
639 if (Context
->bVertical
)
641 if ((Control
[Index
].dwControlType
& MIXERCONTROL_CT_CLASS_MASK
) == MIXERCONTROL_CT_CLASS_FADER
)
643 /* FIXME: give me granularity */
644 DWORD Step
= 0x10000 / 5;
647 uDetails
.dwValue
= 0x10000 - Step
* Context
->SliderPos
;
650 SndMixerSetVolumeControlDetails(Preferences
.MixerWindow
->Mixer
, Control
[Index
].dwControlID
, sizeof(MIXERCONTROLDETAILS_UNSIGNED
), (LPVOID
)&uDetails
);
656 else if (Context
->bSwitch
)
658 if ((Control
[Index
].dwControlType
& MIXERCONTROL_CT_CLASS_MASK
) == MIXERCONTROL_CT_CLASS_SWITCH
)
661 bDetails
.fValue
= Context
->SliderPos
;
664 SndMixerSetVolumeControlDetails(Preferences
.MixerWindow
->Mixer
, Control
[Index
].dwControlID
, sizeof(MIXERCONTROLDETAILS_BOOLEAN
), (LPVOID
)&bDetails
);
672 /* FIXME: implement left - right channel switch support */
678 HeapFree(GetProcessHeap(), 0, Control
);
688 MixerControlChangeCallback(PSND_MIXER Mixer
, DWORD LineID
, LPMIXERLINE Line
, PVOID Context
)
690 UINT ControlCount
= 0, Index
;
691 LPMIXERCONTROL Control
= NULL
;
693 /* check if the line has controls */
694 if (Line
->cControls
== 0)
701 if (SndMixerQueryControls(Mixer
, &ControlCount
, Line
, &Control
) == FALSE
)
703 /* failed to query for controls */
707 /* now go through all controls and compare control ids */
708 for(Index
= 0; Index
< ControlCount
; Index
++)
710 if (Control
[Index
].dwControlID
== PtrToUlong(Context
))
712 if ((Control
[Index
].dwControlType
& MIXERCONTROL_CT_CLASS_MASK
) == MIXERCONTROL_CT_CLASS_SWITCH
)
714 MIXERCONTROLDETAILS_BOOLEAN Details
;
716 /* get volume control details */
717 if (SndMixerGetVolumeControlDetails(Preferences
.MixerWindow
->Mixer
, Control
[Index
].dwControlID
, sizeof(MIXERCONTROLDETAILS_BOOLEAN
), (LPVOID
)&Details
) != -1)
719 /* update dialog control */
720 UpdateDialogLineSwitchControl(&Preferences
, Line
, Details
.fValue
);
723 else if ((Control
[Index
].dwControlType
& MIXERCONTROL_CT_CLASS_MASK
) == MIXERCONTROL_CT_CLASS_FADER
)
725 MIXERCONTROLDETAILS_UNSIGNED Details
;
727 /* get volume control details */
728 if (SndMixerGetVolumeControlDetails(Preferences
.MixerWindow
->Mixer
, Control
[Index
].dwControlID
, sizeof(MIXERCONTROLDETAILS_UNSIGNED
), (LPVOID
)&Details
) != -1)
730 /* update dialog control */
732 DWORD Step
= 0x10000 / 5;
734 /* FIXME: give me granularity */
735 Position
= 5 - (Details
.dwValue
/ Step
);
737 /* update volume control slider */
738 UpdateDialogLineSliderControl(&Preferences
, Line
, Control
[Index
].dwControlID
, IDC_LINE_SLIDER_VERT
, Position
);
746 HeapFree(GetProcessHeap(), 0, Control
);
754 static LRESULT CALLBACK
755 MainWindowProc(HWND hwnd
,
760 PMIXER_WINDOW MixerWindow
;
761 DWORD CtrlID
, LineOffset
;
763 SET_VOLUME_CONTEXT Context
;
769 MixerWindow
= GetWindowData(hwnd
,
772 switch (LOWORD(wParam
))
776 PREFERENCES_CONTEXT Preferences
;
778 Preferences
.MixerWindow
= MixerWindow
;
779 Preferences
.Mixer
= NULL
;
781 if (DialogBoxParam(hAppInstance
,
782 MAKEINTRESOURCE(IDD_PREFERENCES
),
785 (LPARAM
)&Preferences
) == IDOK
)
788 TCHAR szProduct
[MAXPNAMELEN
];
790 /* get mixer product name */
791 if (SndMixerGetProductName(MixerWindow
->Mixer
,
793 sizeof(szProduct
) / sizeof(szProduct
[0])) == -1)
795 /* failed to get name */
796 szProduct
[0] = L
'\0';
801 wcscpy(Preferences
.DeviceName
, szProduct
);
804 /* destroy old status bar */
805 DestroyWindow(MixerWindow
->hStatusBar
);
807 /* rebuild dialog controls */
808 if (RebuildMixerWindowControls(&Preferences
))
810 DPRINT("Rebuilding mixer window controls failed!\n");
813 /* create status window */
814 MixerWindow
->hStatusBar
= CreateStatusWindow(WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
,
820 if (MixerWindow
->hStatusBar
)
822 SendMessage(MixerWindow
->hStatusBar
,
839 HICON hAppIcon
= (HICON
)GetClassLongPtrW(hwnd
,
851 CtrlID
= LOWORD(wParam
);
853 /* check if the message is from the line switch */
854 if (HIWORD(wParam
) == BN_CLICKED
&& (CtrlID
% IDC_LINE_SWITCH
== 0))
856 /* compute line offset */
857 LineOffset
= CtrlID
/ IDC_LINE_SWITCH
;
859 /* compute window id of line name static control */
860 CtrlID
= LineOffset
* IDC_LINE_NAME
;
863 if (GetDlgItemTextW(hwnd
, CtrlID
, Context
.LineName
, MIXER_LONG_NAME_CHARS
) != 0)
866 Context
.SliderPos
= SendMessage((HWND
)lParam
, BM_GETCHECK
, 0, 0);
867 Context
.bVertical
= FALSE
;
868 Context
.bSwitch
= TRUE
;
871 SndMixerEnumConnections(Preferences
.MixerWindow
->Mixer
, Preferences
.SelectedLine
, SetVolumeCallback
, (LPVOID
)&Context
);
880 case MM_MIXM_LINE_CHANGE
:
882 DPRINT("MM_MIXM_LINE_CHANGE\n");
886 case MM_MIXM_CONTROL_CHANGE
:
888 DPRINT("MM_MIXM_CONTROL_CHANGE\n");
890 /* get mixer window */
891 MixerWindow
= GetWindowData(hwnd
,
896 assert(MixerWindow
->Mixer
->hmx
== (HMIXER
)wParam
);
898 SndMixerEnumConnections(MixerWindow
->Mixer
, Preferences
.SelectedLine
, MixerControlChangeCallback
, (PVOID
)lParam
);
904 if (LOWORD(wParam
) == TB_THUMBTRACK
)
906 /* get dialog item ctrl */
907 CtrlID
= GetDlgCtrlID((HWND
)lParam
);
910 LineOffset
= CtrlID
/ IDC_LINE_SLIDER_VERT
;
912 /* compute window id of line name static control */
913 CtrlID
= LineOffset
* IDC_LINE_NAME
;
916 if (GetDlgItemTextW(hwnd
, CtrlID
, Context
.LineName
, MIXER_LONG_NAME_CHARS
) != 0)
919 Context
.SliderPos
= HIWORD(wParam
);
920 Context
.bVertical
= TRUE
;
921 Context
.bSwitch
= FALSE
;
924 SndMixerEnumConnections(Preferences
.MixerWindow
->Mixer
, Preferences
.SelectedLine
, SetVolumeCallback
, (LPVOID
)&Context
);
934 MixerWindow
= ((LPCREATESTRUCT
)lParam
)->lpCreateParams
;
935 SetWindowLongPtr(hwnd
,
937 (LONG_PTR
)MixerWindow
);
938 MixerWindow
->hWnd
= hwnd
;
939 MixerWindow
->Mixer
= SndMixerCreate(MixerWindow
->hWnd
);
940 if (MixerWindow
->Mixer
!= NULL
)
942 TCHAR szProduct
[MAXPNAMELEN
];
944 /* get mixer product name */
945 if (SndMixerGetProductName(MixerWindow
->Mixer
,
947 sizeof(szProduct
) / sizeof(szProduct
[0])) == -1)
949 /* failed to get name */
950 szProduct
[0] = L
'\0';
954 /* initialize perferences */
955 ZeroMemory(&Preferences
, sizeof(Preferences
));
958 Preferences
.Mixer
= MixerWindow
->Mixer
;
960 /* store mixer window */
961 Preferences
.MixerWindow
= MixerWindow
;
963 /* first destination line id */
964 Preferences
.SelectedLine
= 0xFFFF0000;
967 wcscpy(Preferences
.DeviceName
, szProduct
);
969 if (!RebuildMixerWindowControls(&Preferences
))
971 DPRINT("Rebuilding mixer window controls failed!\n");
972 SndMixerDestroy(MixerWindow
->Mixer
);
973 MixerWindow
->Mixer
= NULL
;
977 /* create status window */
978 MixerWindow
->hStatusBar
= CreateStatusWindow(WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
,
982 if (MixerWindow
->hStatusBar
)
984 SendMessage(MixerWindow
->hStatusBar
,
995 MixerWindow
= GetWindowData(hwnd
,
997 if (MixerWindow
->Mixer
!= NULL
)
999 SndMixerDestroy(MixerWindow
->Mixer
);
1012 Result
= DefWindowProc(hwnd
,
1024 RegisterApplicationClasses(VOID
)
1028 wc
.cbSize
= sizeof(WNDCLASSEX
);
1029 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1030 wc
.lpfnWndProc
= MainWindowProc
;
1032 wc
.cbWndExtra
= sizeof(PMIXER_WINDOW
);
1033 wc
.hInstance
= hAppInstance
;
1034 wc
.hIcon
= LoadIcon(hAppInstance
,
1035 MAKEINTRESOURCE(IDI_MAINAPP
));
1036 wc
.hCursor
= LoadCursor(NULL
,
1038 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1039 wc
.lpszMenuName
= NULL
;
1040 wc
.lpszClassName
= SZ_APP_CLASS
;
1042 MainWindowClass
= RegisterClassEx(&wc
);
1044 return MainWindowClass
!= 0;
1048 UnregisterApplicationClasses(VOID
)
1050 UnregisterClass(SZ_APP_CLASS
,
1055 CreateApplicationWindow(VOID
)
1059 PMIXER_WINDOW MixerWindow
= HeapAlloc(hAppHeap
,
1061 sizeof(MIXER_WINDOW
));
1062 if (MixerWindow
== NULL
)
1067 if (mixerGetNumDevs() > 0)
1069 hWnd
= CreateWindowEx(WS_EX_WINDOWEDGE
| WS_EX_CONTROLPARENT
,
1072 WS_DLGFRAME
| WS_CAPTION
| WS_MINIMIZEBOX
| WS_SYSMENU
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
| WS_VISIBLE
,
1075 LoadMenu(hAppInstance
,
1076 MAKEINTRESOURCE(IDM_MAINMENU
)),
1082 LPTSTR lpErrMessage
;
1085 * no mixer devices are available!
1089 if (AllocAndLoadString(&lpErrMessage
,
1091 IDS_NOMIXERDEVICES
))
1096 MB_ICONINFORMATION
);
1097 LocalFree(lpErrMessage
);
1112 _tWinMain(HINSTANCE hInstance
,
1113 HINSTANCE hPrevInstance
,
1119 INITCOMMONCONTROLSEX Controls
;
1121 UNREFERENCED_PARAMETER(hPrevInstance
);
1122 UNREFERENCED_PARAMETER(lpszCmdLine
);
1123 UNREFERENCED_PARAMETER(nCmdShow
);
1125 hAppInstance
= hInstance
;
1126 hAppHeap
= GetProcessHeap();
1128 if (InitAppConfig())
1130 /* load the application title */
1131 if (!AllocAndLoadString(&lpAppTitle
,
1138 Controls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
1139 Controls
.dwICC
= ICC_BAR_CLASSES
| ICC_STANDARD_CLASSES
;
1141 InitCommonControlsEx(&Controls
);
1143 if (RegisterApplicationClasses())
1145 hMainWnd
= CreateApplicationWindow();
1146 if (hMainWnd
!= NULL
)
1149 while ((bRet
=GetMessage(&Msg
,
1156 TranslateMessage(&Msg
);
1157 DispatchMessage(&Msg
);
1161 DestroyWindow(hMainWnd
);
1166 DPRINT("Failed to create application window (LastError: %d)!\n", GetLastError());
1169 UnregisterApplicationClasses();
1173 DPRINT("Failed to register application classes (LastError: %d)!\n", GetLastError());
1176 if (lpAppTitle
!= NULL
)
1178 LocalFree(lpAppTitle
);
1185 DPRINT("Unable to open the Volume Control registry key!\n");