10 added files
reactos/subsys/system/sndvol32
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,6 @@
+*.o
+*.d
+*.exe
+*.coff
+*.sym
+*.map
\ No newline at end of file
reactos/subsys/system/sndvol32
diff -N En.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ En.rc 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,41 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+IDM_MAINMENU MENU DISCARDABLE
+BEGIN
+ POPUP "O&ptions"
+ BEGIN
+ MENUITEM "P&roperties", IDC_PROPERTIES
+ MENUITEM "&Advanced Controls", IDC_ADVANCED_CONTROLS
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", IDC_EXIT
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&Help Topics", IDC_HELP_TOPICS
+ MENUITEM SEPARATOR
+ MENUITEM "&About ...", IDC_ABOUT
+ END
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_SNDVOL32 "Volume Control"
+ IDS_NOMIXERDEVICES "There are no active mixer devices available! The application will now exit."
+END
+
+IDD_PREFERENCES DIALOGEX 0, 0, 224, 250
+STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Properties"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "&Mixer device:", -1, 7,8,48,9
+ COMBOBOX IDC_MIXERDEVICE, 55,8,162,80, CBS_DROPDOWNLIST | WS_TABSTOP
+ GROUPBOX "Adjust volume for:", -1, 7,25,211,77
+ PUSHBUTTON "&Playback", IDC_PLAYBACK, 13,43,47,8, BS_AUTORADIOBUTTON
+ PUSHBUTTON "&Recording", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
+ PUSHBUTTON "&Other:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
+ COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
+
+ PUSHBUTTON "OK", IDOK, 114,226,50,14
+ PUSHBUTTON "Cancel", IDCANCEL, 168,226,50,14
+END
reactos/subsys/system/sndvol32
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,23 @@
+# $Id: Makefile,v 1.1 2004/12/29 22:37:13 weiden Exp $
+
+PATH_TO_TOP = ../../..
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE = windows
+
+TARGET_NAME = sndvol32
+
+TARGET_INSTALLDIR = system32
+
+TARGET_CFLAGS = -D__USE_W32API -DUNICODE -D_UNICODE -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501
+
+TARGET_SDKLIBS = rosrtl.a user32.a kernel32.a ntdll.a
+
+TARGET_GCCLIBS = winmm msvcrt advapi32 kernel32 comctl32
+
+TARGET_OBJECTS = $(TARGET_NAME).o mixer.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
reactos/subsys/system/sndvol32
diff -N manifest.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ manifest.xml 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="ReactOS.Sound.Volume.Control"
+ type="win32"
+ />
+ <description>ReactOS Volume Control</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+ </dependency>
+</assembly>
+
+<!-- EOF -->
reactos/subsys/system/sndvol32
diff -N mixer.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mixer.c 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,378 @@
+/*
+ * ReactOS Sound Volume Control
+ * Copyright (C) 2004 Thomas Weidenmueller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * VMware is a registered trademark of VMware, Inc.
+ */
+/* $Id: mixer.c,v 1.1 2004/12/29 22:37:13 weiden Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Sound Volume Control
+ * FILE: subsys/system/sndvol32/mixer.c
+ * PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
+ */
+#include "sndvol32.h"
+
+#define NO_MIXER_SELECTED (~0)
+
+static VOID
+ClearMixerCache(PSND_MIXER Mixer)
+{
+ PSND_MIXER_DESTINATION Line, NextLine;
+ PSND_MIXER_CONNECTION Con, NextCon;
+
+ for(Line = Mixer->Lines; Line != NULL; Line = NextLine)
+ {
+ if(Line->Controls != NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, Line->Controls);
+ }
+
+ for(Con = Line->Connections; Con != NULL; Con = NextCon)
+ {
+ if(Con->Controls != NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, Con->Controls);
+ }
+
+ NextCon = Con->Next;
+ HeapFree(GetProcessHeap(), 0, Con);
+ }
+
+ NextLine = Line->Next;
+ HeapFree(GetProcessHeap(), 0, Line);
+ }
+ Mixer->Lines = NULL;
+}
+
+PSND_MIXER
+SndMixerCreate(HWND hWndNotification)
+{
+ PSND_MIXER Mixer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SND_MIXER));
+ if(Mixer != NULL)
+ {
+ Mixer->hWndNotification = hWndNotification;
+ Mixer->MixersCount = mixerGetNumDevs();
+ Mixer->MixerId = NO_MIXER_SELECTED;
+
+ if(Mixer->MixersCount > 0)
+ {
+ /* select the first mixer by default */
+ SndMixerSelect(Mixer, 0);
+ }
+ }
+
+ return Mixer;
+}
+
+VOID
+SndMixerDestroy(PSND_MIXER Mixer)
+{
+ SndMixerClose(Mixer);
+ HeapFree(GetProcessHeap(), 0, Mixer);
+}
+
+VOID
+SndMixerClose(PSND_MIXER Mixer)
+{
+ if(Mixer->hmx != NULL)
+ {
+ mixerClose(Mixer->hmx);
+ Mixer->hmx = NULL;
+ Mixer->MixerId = NO_MIXER_SELECTED;
+ }
+}
+
+static BOOL
+SndMixerQueryControls(PSND_MIXER Mixer, LPMIXERLINE LineInfo, LPMIXERCONTROL *Controls)
+{
+ if(LineInfo->cControls > 0)
+ {
+ *Controls = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LineInfo->cControls * sizeof(MIXERCONTROL));
+ if(*Controls != NULL)
+ {
+ MIXERLINECONTROLS LineControls;
+ UINT j;
+
+ LineControls.cbStruct = sizeof(LineControls);
+ LineControls.dwLineID = LineInfo->dwLineID;
+ LineControls.cControls = LineInfo->cControls;
+ LineControls.cbmxctrl = sizeof(MIXERCONTROL);
+ LineControls.pamxctrl = (PVOID)(*Controls);
+
+ for(j = 0; j < LineInfo->cControls; j++)
+ {
+ (*Controls)[j].cbStruct = sizeof(MIXERCONTROL);
+ }
+
+ if(mixerGetLineControls((HMIXEROBJ)Mixer->hmx, &LineControls, MIXER_GETLINECONTROLSF_ALL) == MMSYSERR_NOERROR)
+ {
+ for(j = 0; j < LineInfo->cControls; j++)
+ {
+ DBG("Line control: %ws", (*Controls)[j].szName);
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, *Controls);
+ *Controls = NULL;
+ DBG("Failed to get line controls!\n");
+ }
+ }
+ else
+ {
+ DBG("Failed to allocate memory for %d line controls!\n", LineInfo->cControls);
+ }
+
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+static BOOL
+SndMixerQueryConnections(PSND_MIXER Mixer, PSND_MIXER_DESTINATION Line)
+{
+ UINT i;
+ MIXERLINE LineInfo;
+ BOOL Ret = TRUE;
+
+ LineInfo.cbStruct = sizeof(LineInfo);
+ LineInfo.dwDestination = Line->Info.dwDestination;
+ for(i = Line->Info.cConnections; i > 0; i--)
+ {
+ LineInfo.dwSource = i - 1;
+ if(mixerGetLineInfo((HMIXEROBJ)Mixer->hmx, &LineInfo, MIXER_GETLINEINFOF_SOURCE) == MMSYSERR_NOERROR)
+ {
+ LPMIXERCONTROL Controls;
+ PSND_MIXER_CONNECTION Con;
+
+ if(!SndMixerQueryControls(Mixer, &LineInfo, &Controls))
+ {
+ DBG("Failed to query connection controls\n");
+ Ret = FALSE;
+ break;
+ }
+
+ Con = HeapAlloc(GetProcessHeap(), 0, sizeof(SND_MIXER_CONNECTION));
+ if(Con != NULL)
+ {
+ Con->Info = LineInfo;
+ Con->Controls = Controls;
+ Con->Next = Line->Connections;
+ Line->Connections = Con;
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, Controls);
+ }
+ }
+ else
+ {
+ DBG("Failed to get connection information!\n");
+ Ret = FALSE;
+ break;
+ }
+ }
+
+ return Ret;
+}
+
+static BOOL
+SndMixerQueryDestinations(PSND_MIXER Mixer)
+{
+ UINT i;
+ BOOL Ret = TRUE;
+
+ for(i = Mixer->Caps.cDestinations; i > 0; i--)
+ {
+ PSND_MIXER_DESTINATION Line;
+
+ Line = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SND_MIXER_DESTINATION));
+ if(Line != NULL)
+ {
+ Line->Info.cbStruct = sizeof(Line->Info);
+ Line->Info.dwDestination = i - 1;
+ if(mixerGetLineInfo((HMIXEROBJ)Mixer->hmx, &Line->Info, MIXER_GETLINEINFOF_DESTINATION) == MMSYSERR_NOERROR)
+ {
+ if(!SndMixerQueryConnections(Mixer, Line))
+ {
+ DBG("Failed to query mixer connections!\n");
+ Ret = FALSE;
+ break;
+ }
+ if(!SndMixerQueryControls(Mixer, &Line->Info, &Line->Controls))
+ {
+ DBG("Failed to query mixer controls!\n");
+ Ret = FALSE;
+ break;
+ }
+
+ Line->Next = Mixer->Lines;
+ Mixer->Lines = Line;
+ }
+ else
+ {
+ DBG("Failed to get line information for id %d!\n", i);
+ HeapFree(GetProcessHeap(), 0, Line);
+ Ret = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ DBG("Allocation of SND_MIXER_DEST structure for id %d failed!\n", i);
+ Ret = FALSE;
+ break;
+ }
+ }
+
+ return Ret;
+}
+
+BOOL
+SndMixerSelect(PSND_MIXER Mixer, UINT MixerId)
+{
+ if(MixerId >= Mixer->MixersCount)
+ {
+ return FALSE;
+ }
+
+ SndMixerClose(Mixer);
+
+ if(mixerOpen(&Mixer->hmx, MixerId, (DWORD_PTR)Mixer->hWndNotification, 0, CALLBACK_WINDOW | MIXER_OBJECTF_MIXER) == MMSYSERR_NOERROR ||
+ mixerOpen(&Mixer->hmx, MixerId, (DWORD_PTR)Mixer->hWndNotification, 0, CALLBACK_WINDOW) == MMSYSERR_NOERROR ||
+ mixerOpen(&Mixer->hmx, MixerId, 0, 0, 0) == MMSYSERR_NOERROR)
+ {
+ if(mixerGetDevCaps(MixerId, &Mixer->Caps, sizeof(Mixer->Caps)) == MMSYSERR_NOERROR)
+ {
+ BOOL Ret = FALSE;
+
+ Mixer->MixerId = MixerId;
+
+ ClearMixerCache(Mixer);
+
+ Ret = SndMixerQueryDestinations(Mixer);
+
+ if(!Ret)
+ {
+ ClearMixerCache(Mixer);
+ }
+
+ return Ret;
+ }
+ else
+ {
+ mixerClose(Mixer->hmx);
+ }
+ }
+
+ Mixer->hmx = NULL;
+ Mixer->MixerId = NO_MIXER_SELECTED;
+ return FALSE;
+}
+
+UINT
+SndMixerGetSelection(PSND_MIXER Mixer)
+{
+ return Mixer->MixerId;
+}
+
+INT
+SndMixerGetProductName(PSND_MIXER Mixer, LPTSTR lpBuffer, UINT uSize)
+{
+ if(Mixer->hmx)
+ {
+ int lnsz = lstrlen(Mixer->Caps.szPname);
+ if(lnsz + 1 > uSize)
+ {
+ return lnsz + 1;
+ }
+ else
+ {
+ memcpy(lpBuffer, Mixer->Caps.szPname, lnsz * sizeof(TCHAR));
+ lpBuffer[lnsz] = _T('\0');
+ return lnsz;
+ }
+ }
+
+ return -1;
+}
+
+BOOL
+SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context)
+{
+ MIXERCAPS Caps;
+ HMIXER hMixer;
+ UINT i;
+ BOOL Ret = TRUE;
+
+ for(i = 0; i < Mixer->MixersCount; i++)
+ {
+ if(mixerOpen(&hMixer, i, 0, 0, 0) == MMSYSERR_NOERROR)
+ {
+ if(mixerGetDevCaps(i, &Caps, sizeof(Caps)) == MMSYSERR_NOERROR)
+ {
+ if(!EnumProc(Mixer, i, Caps.szPname, Context))
+ {
+ mixerClose(hMixer);
+ Ret = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ DBG("Failed to get device capabilities for mixer id %d!\n", i);
+ }
+ mixerClose(hMixer);
+ }
+ }
+
+ return Ret;
+}
+
+INT
+SndMixerGetDestinationCount(PSND_MIXER Mixer)
+{
+ return (Mixer->hmx ? Mixer->Caps.cDestinations : -1);
+}
+
+BOOL
+SndMixerEnumLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context)
+{
+ if(Mixer->hmx)
+ {
+ PSND_MIXER_DESTINATION Line;
+
+ for(Line = Mixer->Lines; Line != NULL; Line = Line->Next)
+ {
+ if(!EnumProc(Mixer, &Line->Info, Context))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
reactos/subsys/system/sndvol32
diff -N resources.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ resources.h 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,24 @@
+#ifndef __SNDVOL_RESOURCES_H
+#define __SNDVOL_RESOURCES_H
+
+#define IDM_MAINMENU 101
+
+#define IDI_MAINAPP 101
+
+#define IDC_PROPERTIES 1001
+#define IDC_ADVANCED_CONTROLS 1002
+#define IDC_EXIT 1003
+#define IDC_HELP_TOPICS 1101
+#define IDC_ABOUT 1102
+
+#define IDD_PREFERENCES 101
+#define IDC_MIXERDEVICE 1001
+#define IDC_PLAYBACK 1002
+#define IDC_RECORDING 1003
+#define IDC_OTHER 1004
+#define IDC_LINE 1005
+
+#define IDS_SNDVOL32 100
+#define IDS_NOMIXERDEVICES 101
+
+#endif /* __SNDVOL_RESOURCES_H */
reactos/subsys/system/sndvol32
diff -N sndvol32.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sndvol32.c 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,407 @@
+/*
+ * ReactOS Sound Volume Control
+ * Copyright (C) 2004 Thomas Weidenmueller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * VMware is a registered trademark of VMware, Inc.
+ */
+/* $Id: sndvol32.c,v 1.1 2004/12/29 22:37:13 weiden Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Sound Volume Control
+ * FILE: subsys/system/sndvol32/sndvol32.c
+ * PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
+ */
+#include "sndvol32.h"
+
+HINSTANCE hAppInstance;
+ATOM MainWindowClass;
+HWND hMainWnd;
+HANDLE hAppHeap;
+
+#define GetDialogData(hwndDlg, type) \
+ ( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)
+#define GetWindowData(hwnd, type) \
+ ( P##type )GetWindowLongPtr((hwnd), GWL_USERDATA)
+
+/******************************************************************************/
+
+typedef struct _PREFERENCES_CONTEXT
+{
+ PMIXER_WINDOW MixerWindow;
+ PSND_MIXER Mixer;
+ HWND hwndDlg;
+} PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
+
+typedef struct _PREFERENCES_FILL_DEVICES
+{
+ PPREFERENCES_CONTEXT PrefContext;
+ HWND hComboBox;
+ UINT Selected;
+} PREFERENCES_FILL_DEVICES, *PPREFERENCES_FILL_DEVICES;
+
+static BOOL CALLBACK
+FillDeviceComboBox(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context)
+{
+ LRESULT lres;
+ PPREFERENCES_FILL_DEVICES FillContext = (PPREFERENCES_FILL_DEVICES)Context;
+
+ lres = SendMessage(FillContext->hComboBox, CB_ADDSTRING, 0, (LPARAM)ProductName);
+ if(lres != CB_ERR)
+ {
+ /* save the index so we don't screw stuff when the combobox is sorted... */
+ SendMessage(FillContext->hComboBox, CB_SETITEMDATA, (WPARAM)lres, Id);
+
+ if(Id == FillContext->Selected)
+ {
+ SendMessage(FillContext->hComboBox, CB_SETCURSEL, (WPARAM)lres, 0);
+ }
+ }
+
+ return TRUE;
+}
+
+static INT_PTR CALLBACK
+DlgPreferencesProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ PPREFERENCES_CONTEXT Context;
+
+ switch(uMsg)
+ {
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ case IDCANCEL:
+ {
+ EndDialog(hwndDlg, LOWORD(wParam));
+ break;
+ }
+ }
+ break;
+ }
+
+ case MM_MIXM_LINE_CHANGE:
+ {
+ DBG("MM_MIXM_LINE_CHANGE\n");
+ break;
+ }
+
+ case MM_MIXM_CONTROL_CHANGE:
+ {
+ DBG("MM_MIXM_CONTROL_CHANGE\n");
+ break;
+ }
+
+ case WM_INITDIALOG:
+ {
+ PREFERENCES_FILL_DEVICES FillDevContext;
+
+ SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
+ Context = (PPREFERENCES_CONTEXT)((LONG_PTR)lParam);
+ Context->hwndDlg = hwndDlg;
+ Context->Mixer = SndMixerCreate(hwndDlg);
+
+ FillDevContext.PrefContext = Context;
+ FillDevContext.hComboBox = GetDlgItem(hwndDlg, IDC_MIXERDEVICE);
+ FillDevContext.Selected = SndMixerGetSelection(Context->Mixer);
+ SndMixerEnumProducts(Context->Mixer,
+ FillDeviceComboBox,
+ &FillDevContext);
+ return TRUE;
+ }
+
+ case WM_DESTROY:
+ {
+ Context = GetDialogData(hwndDlg, PREFERENCES_CONTEXT);
+ if(Context->Mixer != NULL)
+ {
+ SndMixerDestroy(Context->Mixer);
+ }
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ EndDialog(hwndDlg, IDCANCEL);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+
+static VOID
+DeleteMixerWindowControls(PMIXER_WINDOW MixerWindow)
+{
+}
+
+BOOL
+RebuildMixerWindowControls(PMIXER_WINDOW MixerWindow)
+{
+ DeleteMixerWindowControls(MixerWindow);
+
+ return TRUE;
+}
+
+LRESULT CALLBACK
+MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ PMIXER_WINDOW MixerWindow;
+ LRESULT Result = 0;
+
+ switch(uMsg)
+ {
+ case WM_COMMAND:
+ {
+ MixerWindow = GetWindowData(hwnd, MIXER_WINDOW);
+
+ switch(LOWORD(wParam))
+ {
+ case IDC_PROPERTIES:
+ {
+ PREFERENCES_CONTEXT Preferences;
+
+ Preferences.MixerWindow = MixerWindow;
+ Preferences.Mixer = NULL;
+
+ if(DialogBoxParam(hAppInstance,
+ MAKEINTRESOURCE(IDD_PREFERENCES),
+ hwnd,
+ DlgPreferencesProc,
+ (LPARAM)&Preferences) == IDOK)
+ {
+ /* FIXME - update window */
+ }
+ break;
+ }
+
+ case IDC_EXIT:
+ {
+ PostQuitMessage(0);
+ break;
+ }
+ }
+ break;
+ }
+
+ case MM_MIXM_LINE_CHANGE:
+ {
+ DBG("MM_MIXM_LINE_CHANGE\n");
+ break;
+ }
+
+ case MM_MIXM_CONTROL_CHANGE:
+ {
+ DBG("MM_MIXM_CONTROL_CHANGE\n");
+ break;
+ }
+
+ case WM_CREATE:
+ {
+ MixerWindow = ((LPCREATESTRUCT)lParam)->lpCreateParams;
+ SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)MixerWindow);
+ MixerWindow->hWnd = hwnd;
+ MixerWindow->hStatusBar = CreateStatusWindow(WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
+ NULL, hwnd, 0);
+ if(MixerWindow->hStatusBar != NULL)
+ {
+ MixerWindow->Mixer = SndMixerCreate(MixerWindow->hWnd);
+ if(MixerWindow->Mixer != NULL)
+ {
+ TCHAR szProduct[MAXPNAMELEN];
+
+ if(SndMixerGetProductName(MixerWindow->Mixer, szProduct, sizeof(szProduct) / sizeof(szProduct[0])) > 0)
+ {
+ SendMessage(MixerWindow->hStatusBar, WM_SETTEXT, 0, (LPARAM)szProduct);
+ }
+
+ if(!RebuildMixerWindowControls(MixerWindow))
+ {
+ DBG("Rebuilding mixer window controls failed!\n");
+ SndMixerDestroy(MixerWindow->Mixer);
+ Result = -1;
+ }
+ }
+ else
+ {
+ Result = -1;
+ }
+ }
+ else
+ {
+ DBG("Failed to create status window!\n");
+ Result = -1;
+ }
+ break;
+ }
+
+ case WM_DESTROY:
+ {
+ MixerWindow = GetWindowData(hwnd, MIXER_WINDOW);
+ if(MixerWindow->Mixer != NULL)
+ {
+ SndMixerDestroy(MixerWindow->Mixer);
+ }
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ PostQuitMessage(0);
+ break;
+ }
+
+ default:
+ {
+ Result = DefWindowProc(hwnd, uMsg, wParam, lParam);
+ }
+ }
+
+ return Result;
+}
+
+static BOOL
+RegisterApplicationClasses(VOID)
+{
+ WNDCLASSEX wc;
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = MainWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = sizeof(PMIXER_WINDOW);
+ wc.hInstance = hAppInstance;
+ wc.hIcon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_MAINAPP));
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = SZ_APP_CLASS;
+ wc.hIconSm = NULL;
+ MainWindowClass = RegisterClassEx(&wc);
+
+ return MainWindowClass != 0;
+}
+
+static VOID
+UnregisterApplicationClasses(VOID)
+{
+ UnregisterClass(SZ_APP_CLASS, hAppInstance);
+}
+
+static HWND
+CreateApplicationWindow(VOID)
+{
+ LPTSTR lpAppTitle;
+ HWND hWnd;
+
+ PMIXER_WINDOW MixerWindow = HeapAlloc(hAppHeap, 0, sizeof(MIXER_WINDOW));
+ if(MixerWindow == NULL)
+ {
+ return NULL;
+ }
+
+ /* load the application title */
+ if(RosAllocAndLoadString(&lpAppTitle,
+ hAppInstance,
+ IDS_SNDVOL32) == 0)
+ {
+ lpAppTitle = NULL;
+ }
+
+ if(mixerGetNumDevs() > 0)
+ {
+ hWnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT,
+ SZ_APP_CLASS,
+ lpAppTitle,
+ WS_DLGFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL,
+ LoadMenu(hAppInstance, MAKEINTRESOURCE(IDM_MAINMENU)),
+ hAppInstance,
+ MixerWindow);
+ }
+ else
+ {
+ LPTSTR lpErrMessage;
+
+ /*
+ * no mixer devices are available!
+ */
+
+ hWnd = NULL;
+ RosAllocAndLoadString(&lpErrMessage,
+ hAppInstance,
+ IDS_NOMIXERDEVICES);
+ MessageBox(NULL, lpErrMessage, lpAppTitle, MB_ICONINFORMATION);
+ LocalFree(lpErrMessage);
+ }
+
+ if(lpAppTitle != NULL)
+ {
+ LocalFree(lpAppTitle);
+ }
+
+ if(hWnd == NULL)
+ {
+ HeapFree(hAppHeap, 0, MixerWindow);
+ }
+
+ return hWnd;
+}
+
+int WINAPI
+WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow)
+{
+ MSG Msg;
+
+ hAppInstance = hInstance;
+ hAppHeap = GetProcessHeap();
+
+ InitCommonControls();
+
+ if(!RegisterApplicationClasses())
+ {
+ DBG("Failed to register application classes (LastError: %d)!\n", GetLastError());
+ return 1;
+ }
+
+ hMainWnd = CreateApplicationWindow();
+ if(hMainWnd == NULL)
+ {
+ DBG("Failed to creat application window (LastError: %d)!\n", GetLastError());
+ return 1;
+ }
+
+ while(GetMessage(&Msg, NULL, 0, 0))
+ {
+ TranslateMessage(&Msg);
+ DispatchMessage(&Msg);
+ }
+
+ DestroyWindow(hMainWnd);
+
+ UnregisterApplicationClasses();
+
+ return 0;
+}
+
reactos/subsys/system/sndvol32
diff -N sndvol32.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sndvol32.h 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,78 @@
+#ifndef __SNDVOL32_H
+#define __SNDVOL32_H
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <tchar.h>
+#include <string.h>
+#include <rosrtl/resstr.h>
+#include "resources.h"
+
+typedef struct _MIXER_WINDOW
+{
+ HWND hWnd;
+ HWND hStatusBar;
+ struct _SND_MIXER *Mixer;
+ UINT SelectedLine;
+} MIXER_WINDOW, *PMIXER_WINDOW;
+
+LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+BOOL RebuildMixerWindowControls(PMIXER_WINDOW MixerWindow);
+
+extern HINSTANCE hAppInstance;
+extern ATOM MainWindowClass;
+extern HWND hMainWnd;
+extern HANDLE hAppHeap;
+
+#define SZ_APP_CLASS TEXT("Volume Control")
+
+#define DBG DbgPrint("SNDVOL32: %s:%i: ", __FILE__, __LINE__); DbgPrint
+
+
+/*
+ * MIXER
+ */
+
+typedef struct _SND_MIXER_CONNECTION
+{
+ struct _SND_MIXER_CONNECTION *Next;
+ MIXERLINE Info;
+ LPMIXERCONTROL Controls;
+} SND_MIXER_CONNECTION, *PSND_MIXER_CONNECTION;
+
+
+typedef struct _SND_MIXER_DESTINATION
+{
+ struct _SND_MIXER_DESTINATION *Next;
+ MIXERLINE Info;
+ LPMIXERCONTROL Controls;
+ PSND_MIXER_CONNECTION Connections;
+} SND_MIXER_DESTINATION, *PSND_MIXER_DESTINATION;
+
+typedef struct _SND_MIXER
+{
+ UINT MixersCount;
+ HWND hWndNotification;
+ UINT MixerId;
+ HMIXER hmx;
+ MIXERCAPS Caps;
+ PSND_MIXER_DESTINATION Lines;
+} SND_MIXER, *PSND_MIXER;
+
+typedef BOOL (CALLBACK *PFNSNDMIXENUMLINES)(PSND_MIXER Mixer, LPMIXERLINE Line, PVOID Context);
+typedef BOOL (CALLBACK *PFNSNDMIXENUMPRODUCTS)(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context);
+
+PSND_MIXER SndMixerCreate(HWND hWndNotification);
+VOID SndMixerDestroy(PSND_MIXER Mixer);
+VOID SndMixerClose(PSND_MIXER Mixer);
+BOOL SndMixerSelect(PSND_MIXER Mixer, UINT MixerId);
+UINT SndMixerGetSelection(PSND_MIXER Mixer);
+INT SndMixerGetProductName(PSND_MIXER Mixer, LPTSTR lpBuffer, UINT uSize);
+BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context);
+INT SndMixerGetDestinationCount(PSND_MIXER Mixer);
+BOOL SndMixerEnumDestinationLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context);
+
+#endif /* __SNDVOL32_H */
reactos/subsys/system/sndvol32
diff -N sndvol32.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sndvol32.rc 29 Dec 2004 22:37:13 -0000 1.1
@@ -0,0 +1,18 @@
+/* $Id: sndvol32.rc,v 1.1 2004/12/29 22:37:13 weiden Exp $ */
+
+#include <defines.h>
+#include "resources.h"
+
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Sound Volume Control\0"
+#define REACTOS_STR_INTERNAL_NAME "sndvol32\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "sndvol32.exe\0"
+#include <reactos/version.rc>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+1 24 DISCARDABLE "manifest.xml"
+
+IDI_MAINAPP ICON DISCARDABLE resources/sndvol32.ico
+
+#include "En.rc"
+
CVSspam 0.2.8