mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
add sndvol32 to the build system and reformat the code
svn path=/trunk/; revision=18102
This commit is contained in:
parent
469b041e51
commit
d286c03c70
7 changed files with 816 additions and 528 deletions
|
@ -55,6 +55,9 @@
|
||||||
<directory name="sm">
|
<directory name="sm">
|
||||||
<xi:include href="sm/sm.xml" />
|
<xi:include href="sm/sm.xml" />
|
||||||
</directory>
|
</directory>
|
||||||
|
<directory name="sndvol32">
|
||||||
|
<xi:include href="sndvol32/sndvol32.xml" />
|
||||||
|
</directory>
|
||||||
<directory name="taskmgr">
|
<directory name="taskmgr">
|
||||||
<xi:include href="taskmgr/taskmgr.xml" />
|
<xi:include href="taskmgr/taskmgr.xml" />
|
||||||
</directory>
|
</directory>
|
||||||
|
|
|
@ -13,7 +13,7 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "&Help Topics", IDC_HELP_TOPICS
|
MENUITEM "&Help Topics", IDC_HELP_TOPICS
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "&About ...", IDC_ABOUT
|
MENUITEM "&About Volume Control", IDC_ABOUT
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
129
reactos/subsys/system/sndvol32/misc.c
Normal file
129
reactos/subsys/system/sndvol32/misc.c
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* ReactOS Sound Volume Control
|
||||||
|
* Copyright (C) 2004-2005 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$
|
||||||
|
*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Sound Volume Control
|
||||||
|
* FILE: subsys/system/sndvol32/misc.c
|
||||||
|
* PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
|
||||||
|
*/
|
||||||
|
#include <sndvol32.h>
|
||||||
|
|
||||||
|
static INT
|
||||||
|
LengthOfStrResource(IN HINSTANCE hInst,
|
||||||
|
IN UINT uID)
|
||||||
|
{
|
||||||
|
HRSRC hrSrc;
|
||||||
|
HGLOBAL hRes;
|
||||||
|
LPWSTR lpName, lpStr;
|
||||||
|
|
||||||
|
if (hInst == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There are always blocks of 16 strings */
|
||||||
|
lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
|
||||||
|
|
||||||
|
/* Find the string table block */
|
||||||
|
if ((hrSrc = FindResourceW(hInst,
|
||||||
|
lpName,
|
||||||
|
(LPWSTR)RT_STRING)) &&
|
||||||
|
(hRes = LoadResource(hInst,
|
||||||
|
hrSrc)) &&
|
||||||
|
(lpStr = LockResource(hRes)))
|
||||||
|
{
|
||||||
|
UINT x;
|
||||||
|
|
||||||
|
/* Find the string we're looking for */
|
||||||
|
uID &= 0xF; /* position in the block, same as % 16 */
|
||||||
|
for (x = 0; x < uID; x++)
|
||||||
|
{
|
||||||
|
lpStr += (*lpStr) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Found the string */
|
||||||
|
return (int)(*lpStr);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT
|
||||||
|
AllocAndLoadString(OUT LPWSTR *lpTarget,
|
||||||
|
IN HINSTANCE hInst,
|
||||||
|
IN UINT uID)
|
||||||
|
{
|
||||||
|
INT ln;
|
||||||
|
|
||||||
|
ln = LengthOfStrResource(hInst,
|
||||||
|
uID);
|
||||||
|
if (ln++ > 0)
|
||||||
|
{
|
||||||
|
(*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
|
||||||
|
ln * sizeof(WCHAR));
|
||||||
|
if ((*lpTarget) != NULL)
|
||||||
|
{
|
||||||
|
INT Ret;
|
||||||
|
if (!(Ret = LoadStringW(hInst,
|
||||||
|
uID,
|
||||||
|
*lpTarget,
|
||||||
|
ln)))
|
||||||
|
{
|
||||||
|
LocalFree((HLOCAL)(*lpTarget));
|
||||||
|
}
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
LoadAndFormatString(IN HINSTANCE hInstance,
|
||||||
|
IN UINT uID,
|
||||||
|
OUT LPWSTR *lpTarget,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
DWORD Ret = 0;
|
||||||
|
LPWSTR lpFormat;
|
||||||
|
va_list lArgs;
|
||||||
|
|
||||||
|
if (AllocAndLoadString(&lpFormat,
|
||||||
|
hInstance,
|
||||||
|
uID) > 0)
|
||||||
|
{
|
||||||
|
va_start(lArgs, lpTarget);
|
||||||
|
/* let's use FormatMessage to format it because it has the ability to
|
||||||
|
allocate memory automatically */
|
||||||
|
Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
|
||||||
|
lpFormat,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(LPWSTR)lpTarget,
|
||||||
|
0,
|
||||||
|
&lArgs);
|
||||||
|
va_end(lArgs);
|
||||||
|
|
||||||
|
LocalFree((HLOCAL)lpFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* ReactOS Sound Volume Control
|
* ReactOS Sound Volume Control
|
||||||
* Copyright (C) 2004 Thomas Weidenmueller
|
* Copyright (C) 2004-2005 Thomas Weidenmueller
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -25,354 +25,423 @@
|
||||||
* FILE: subsys/system/sndvol32/mixer.c
|
* FILE: subsys/system/sndvol32/mixer.c
|
||||||
* PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
|
* PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
|
||||||
*/
|
*/
|
||||||
#include "sndvol32.h"
|
#include <sndvol32.h>
|
||||||
|
|
||||||
#define NO_MIXER_SELECTED (~0)
|
#define NO_MIXER_SELECTED (~0)
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
ClearMixerCache(PSND_MIXER Mixer)
|
ClearMixerCache(PSND_MIXER Mixer)
|
||||||
{
|
{
|
||||||
PSND_MIXER_DESTINATION Line, NextLine;
|
PSND_MIXER_DESTINATION Line, NextLine;
|
||||||
PSND_MIXER_CONNECTION Con, NextCon;
|
PSND_MIXER_CONNECTION Con, NextCon;
|
||||||
|
|
||||||
for(Line = Mixer->Lines; Line != NULL; Line = NextLine)
|
for (Line = Mixer->Lines; Line != NULL; Line = NextLine)
|
||||||
{
|
|
||||||
if(Line->Controls != NULL)
|
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, Line->Controls);
|
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;
|
||||||
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
|
PSND_MIXER
|
||||||
SndMixerCreate(HWND hWndNotification)
|
SndMixerCreate(HWND hWndNotification)
|
||||||
{
|
{
|
||||||
PSND_MIXER Mixer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SND_MIXER));
|
PSND_MIXER Mixer = HeapAlloc(GetProcessHeap(),
|
||||||
if(Mixer != NULL)
|
HEAP_ZERO_MEMORY,
|
||||||
{
|
sizeof(SND_MIXER));
|
||||||
Mixer->hWndNotification = hWndNotification;
|
if (Mixer != NULL)
|
||||||
Mixer->MixersCount = mixerGetNumDevs();
|
|
||||||
Mixer->MixerId = NO_MIXER_SELECTED;
|
|
||||||
|
|
||||||
if(Mixer->MixersCount > 0)
|
|
||||||
{
|
{
|
||||||
/* select the first mixer by default */
|
Mixer->hWndNotification = hWndNotification;
|
||||||
SndMixerSelect(Mixer, 0);
|
Mixer->MixersCount = mixerGetNumDevs();
|
||||||
}
|
Mixer->MixerId = NO_MIXER_SELECTED;
|
||||||
}
|
|
||||||
|
|
||||||
return Mixer;
|
if (Mixer->MixersCount > 0)
|
||||||
|
{
|
||||||
|
/* select the first mixer by default */
|
||||||
|
SndMixerSelect(Mixer, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Mixer;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
SndMixerDestroy(PSND_MIXER Mixer)
|
SndMixerDestroy(PSND_MIXER Mixer)
|
||||||
{
|
{
|
||||||
SndMixerClose(Mixer);
|
SndMixerClose(Mixer);
|
||||||
HeapFree(GetProcessHeap(), 0, Mixer);
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
Mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
SndMixerClose(PSND_MIXER Mixer)
|
SndMixerClose(PSND_MIXER Mixer)
|
||||||
{
|
{
|
||||||
if(Mixer->hmx != NULL)
|
if (Mixer->hmx != NULL)
|
||||||
{
|
{
|
||||||
mixerClose(Mixer->hmx);
|
mixerClose(Mixer->hmx);
|
||||||
Mixer->hmx = NULL;
|
Mixer->hmx = NULL;
|
||||||
Mixer->MixerId = NO_MIXER_SELECTED;
|
Mixer->MixerId = NO_MIXER_SELECTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
SndMixerQueryControls(PSND_MIXER Mixer, LPMIXERLINE LineInfo, LPMIXERCONTROL *Controls)
|
SndMixerQueryControls(PSND_MIXER Mixer,
|
||||||
|
LPMIXERLINE LineInfo,
|
||||||
|
LPMIXERCONTROL *Controls)
|
||||||
{
|
{
|
||||||
if(LineInfo->cControls > 0)
|
if (LineInfo->cControls > 0)
|
||||||
{
|
|
||||||
*Controls = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LineInfo->cControls * sizeof(MIXERCONTROL));
|
|
||||||
if(*Controls != NULL)
|
|
||||||
{
|
{
|
||||||
MIXERLINECONTROLS LineControls;
|
*Controls = HeapAlloc(GetProcessHeap(),
|
||||||
UINT j;
|
HEAP_ZERO_MEMORY,
|
||||||
|
LineInfo->cControls * sizeof(MIXERCONTROL));
|
||||||
LineControls.cbStruct = sizeof(LineControls);
|
if (*Controls != NULL)
|
||||||
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);
|
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++)
|
||||||
|
{
|
||||||
|
DPRINT("Line control: %ws", (*Controls)[j].szName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
*Controls);
|
||||||
|
*Controls = NULL;
|
||||||
|
DPRINT("Failed to get line controls!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Failed to allocate memory for %d line controls!\n", LineInfo->cControls);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, *Controls);
|
|
||||||
*Controls = NULL;
|
|
||||||
DBG("Failed to get line controls!\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG("Failed to allocate memory for %d line controls!\n", LineInfo->cControls);
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
SndMixerQueryConnections(PSND_MIXER Mixer, PSND_MIXER_DESTINATION Line)
|
SndMixerQueryConnections(PSND_MIXER Mixer,
|
||||||
|
PSND_MIXER_DESTINATION Line)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
MIXERLINE LineInfo;
|
MIXERLINE LineInfo;
|
||||||
BOOL Ret = TRUE;
|
BOOL Ret = TRUE;
|
||||||
|
|
||||||
LineInfo.cbStruct = sizeof(LineInfo);
|
LineInfo.cbStruct = sizeof(LineInfo);
|
||||||
LineInfo.dwDestination = Line->Info.dwDestination;
|
LineInfo.dwDestination = Line->Info.dwDestination;
|
||||||
for(i = Line->Info.cConnections; i > 0; i--)
|
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;
|
LineInfo.dwSource = i - 1;
|
||||||
PSND_MIXER_CONNECTION Con;
|
if (mixerGetLineInfo((HMIXEROBJ)Mixer->hmx,
|
||||||
|
&LineInfo,
|
||||||
|
MIXER_GETLINEINFOF_SOURCE) == MMSYSERR_NOERROR)
|
||||||
|
{
|
||||||
|
LPMIXERCONTROL Controls;
|
||||||
|
PSND_MIXER_CONNECTION Con;
|
||||||
|
|
||||||
if(!SndMixerQueryControls(Mixer, &LineInfo, &Controls))
|
if (!SndMixerQueryControls(Mixer,
|
||||||
{
|
&LineInfo,
|
||||||
DBG("Failed to query connection controls\n");
|
&Controls))
|
||||||
Ret = FALSE;
|
{
|
||||||
break;
|
DPRINT("Failed to query connection controls\n");
|
||||||
}
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Con = HeapAlloc(GetProcessHeap(), 0, sizeof(SND_MIXER_CONNECTION));
|
Con = HeapAlloc(GetProcessHeap(),
|
||||||
if(Con != NULL)
|
0,
|
||||||
{
|
sizeof(SND_MIXER_CONNECTION));
|
||||||
Con->Info = LineInfo;
|
if (Con != NULL)
|
||||||
Con->Controls = Controls;
|
{
|
||||||
Con->Next = Line->Connections;
|
Con->Info = LineInfo;
|
||||||
Line->Connections = Con;
|
Con->Controls = Controls;
|
||||||
}
|
Con->Next = Line->Connections;
|
||||||
else
|
Line->Connections = Con;
|
||||||
{
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, Controls);
|
else
|
||||||
}
|
{
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
Controls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Failed to get connection information!\n");
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG("Failed to get connection information!\n");
|
|
||||||
Ret = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
SndMixerQueryDestinations(PSND_MIXER Mixer)
|
SndMixerQueryDestinations(PSND_MIXER Mixer)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
BOOL Ret = TRUE;
|
BOOL Ret = TRUE;
|
||||||
|
|
||||||
for(i = Mixer->Caps.cDestinations; i > 0; i--)
|
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);
|
PSND_MIXER_DESTINATION Line;
|
||||||
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;
|
Line = HeapAlloc(GetProcessHeap(),
|
||||||
Mixer->Lines = Line;
|
HEAP_ZERO_MEMORY,
|
||||||
}
|
sizeof(SND_MIXER_DESTINATION));
|
||||||
else
|
if (Line != NULL)
|
||||||
{
|
{
|
||||||
DBG("Failed to get line information for id %d!\n", i);
|
Line->Info.cbStruct = sizeof(Line->Info);
|
||||||
HeapFree(GetProcessHeap(), 0, Line);
|
Line->Info.dwDestination = i - 1;
|
||||||
Ret = FALSE;
|
if (mixerGetLineInfo((HMIXEROBJ)Mixer->hmx,
|
||||||
break;
|
&Line->Info,
|
||||||
}
|
MIXER_GETLINEINFOF_DESTINATION) == MMSYSERR_NOERROR)
|
||||||
}
|
{
|
||||||
else
|
if (!SndMixerQueryConnections(Mixer, Line))
|
||||||
{
|
{
|
||||||
DBG("Allocation of SND_MIXER_DEST structure for id %d failed!\n", i);
|
DPRINT("Failed to query mixer connections!\n");
|
||||||
Ret = FALSE;
|
Ret = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
if (!SndMixerQueryControls(Mixer,
|
||||||
|
&Line->Info,
|
||||||
|
&Line->Controls))
|
||||||
|
{
|
||||||
|
DPRINT("Failed to query mixer controls!\n");
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return Ret;
|
Line->Next = Mixer->Lines;
|
||||||
|
Mixer->Lines = Line;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Failed to get line information for id %d!\n", i);
|
||||||
|
HeapFree(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
Line);
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Allocation of SND_MIXER_DEST structure for id %d failed!\n", i);
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
SndMixerSelect(PSND_MIXER Mixer, UINT MixerId)
|
SndMixerSelect(PSND_MIXER Mixer,
|
||||||
|
UINT MixerId)
|
||||||
{
|
{
|
||||||
if(MixerId >= Mixer->MixersCount)
|
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;
|
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
|
UINT
|
||||||
SndMixerGetSelection(PSND_MIXER Mixer)
|
SndMixerGetSelection(PSND_MIXER Mixer)
|
||||||
{
|
{
|
||||||
return Mixer->MixerId;
|
return Mixer->MixerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT
|
INT
|
||||||
SndMixerGetProductName(PSND_MIXER Mixer, LPTSTR lpBuffer, UINT uSize)
|
SndMixerGetProductName(PSND_MIXER Mixer,
|
||||||
|
LPTSTR lpBuffer,
|
||||||
|
UINT uSize)
|
||||||
{
|
{
|
||||||
if(Mixer->hmx)
|
if (Mixer->hmx)
|
||||||
{
|
|
||||||
int lnsz = lstrlen(Mixer->Caps.szPname);
|
|
||||||
if(lnsz + 1 > uSize)
|
|
||||||
{
|
{
|
||||||
return lnsz + 1;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(lpBuffer, Mixer->Caps.szPname, lnsz * sizeof(TCHAR));
|
|
||||||
lpBuffer[lnsz] = _T('\0');
|
|
||||||
return lnsz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context)
|
SndMixerEnumProducts(PSND_MIXER Mixer,
|
||||||
|
PFNSNDMIXENUMPRODUCTS EnumProc,
|
||||||
|
PVOID Context)
|
||||||
{
|
{
|
||||||
MIXERCAPS Caps;
|
MIXERCAPS Caps;
|
||||||
HMIXER hMixer;
|
HMIXER hMixer;
|
||||||
UINT i;
|
UINT i;
|
||||||
BOOL Ret = TRUE;
|
BOOL Ret = TRUE;
|
||||||
|
|
||||||
for(i = 0; i < Mixer->MixersCount; i++)
|
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 (mixerOpen(&hMixer,
|
||||||
{
|
i,
|
||||||
if(!EnumProc(Mixer, i, Caps.szPname, Context))
|
0,
|
||||||
|
0,
|
||||||
|
0) == MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
mixerClose(hMixer);
|
if (mixerGetDevCaps(i,
|
||||||
Ret = FALSE;
|
&Caps,
|
||||||
break;
|
sizeof(Caps)) == MMSYSERR_NOERROR)
|
||||||
|
{
|
||||||
|
if (!EnumProc(Mixer,
|
||||||
|
i,
|
||||||
|
Caps.szPname,
|
||||||
|
Context))
|
||||||
|
{
|
||||||
|
mixerClose(hMixer);
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Failed to get device capabilities for mixer id %d!\n", i);
|
||||||
|
}
|
||||||
|
mixerClose(hMixer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG("Failed to get device capabilities for mixer id %d!\n", i);
|
|
||||||
}
|
|
||||||
mixerClose(hMixer);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT
|
INT
|
||||||
SndMixerGetDestinationCount(PSND_MIXER Mixer)
|
SndMixerGetDestinationCount(PSND_MIXER Mixer)
|
||||||
{
|
{
|
||||||
return (Mixer->hmx ? Mixer->Caps.cDestinations : -1);
|
return (Mixer->hmx ? Mixer->Caps.cDestinations : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
SndMixerEnumLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context)
|
SndMixerEnumLines(PSND_MIXER Mixer,
|
||||||
|
PFNSNDMIXENUMLINES EnumProc,
|
||||||
|
PVOID Context)
|
||||||
{
|
{
|
||||||
if(Mixer->hmx)
|
if (Mixer->hmx)
|
||||||
{
|
|
||||||
PSND_MIXER_DESTINATION Line;
|
|
||||||
|
|
||||||
for(Line = Mixer->Lines; Line != NULL; Line = Line->Next)
|
|
||||||
{
|
{
|
||||||
if(!EnumProc(Mixer, &Line->Info, Context))
|
PSND_MIXER_DESTINATION Line;
|
||||||
{
|
|
||||||
return FALSE;
|
for (Line = Mixer->Lines; Line != NULL; Line = Line->Next)
|
||||||
}
|
{
|
||||||
|
if (!EnumProc(Mixer,
|
||||||
|
&Line->Info,
|
||||||
|
Context))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* ReactOS Sound Volume Control
|
* ReactOS Sound Volume Control
|
||||||
* Copyright (C) 2004 Thomas Weidenmueller
|
* Copyright (C) 2004-2005 Thomas Weidenmueller
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
* FILE: subsys/system/sndvol32/sndvol32.c
|
* FILE: subsys/system/sndvol32/sndvol32.c
|
||||||
* PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
|
* PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
|
||||||
*/
|
*/
|
||||||
#include "sndvol32.h"
|
#include <sndvol32.h>
|
||||||
|
|
||||||
HINSTANCE hAppInstance;
|
HINSTANCE hAppInstance;
|
||||||
ATOM MainWindowClass;
|
ATOM MainWindowClass;
|
||||||
|
@ -33,116 +33,137 @@ HWND hMainWnd;
|
||||||
HANDLE hAppHeap;
|
HANDLE hAppHeap;
|
||||||
|
|
||||||
#define GetDialogData(hwndDlg, type) \
|
#define GetDialogData(hwndDlg, type) \
|
||||||
( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)
|
( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)
|
||||||
#define GetWindowData(hwnd, type) \
|
#define GetWindowData(hwnd, type) \
|
||||||
( P##type )GetWindowLongPtr((hwnd), GWL_USERDATA)
|
( P##type )GetWindowLongPtr((hwnd), GWL_USERDATA)
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
typedef struct _PREFERENCES_CONTEXT
|
typedef struct _PREFERENCES_CONTEXT
|
||||||
{
|
{
|
||||||
PMIXER_WINDOW MixerWindow;
|
PMIXER_WINDOW MixerWindow;
|
||||||
PSND_MIXER Mixer;
|
PSND_MIXER Mixer;
|
||||||
HWND hwndDlg;
|
HWND hwndDlg;
|
||||||
} PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
|
} PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
|
||||||
|
|
||||||
typedef struct _PREFERENCES_FILL_DEVICES
|
typedef struct _PREFERENCES_FILL_DEVICES
|
||||||
{
|
{
|
||||||
PPREFERENCES_CONTEXT PrefContext;
|
PPREFERENCES_CONTEXT PrefContext;
|
||||||
HWND hComboBox;
|
HWND hComboBox;
|
||||||
UINT Selected;
|
UINT Selected;
|
||||||
} PREFERENCES_FILL_DEVICES, *PPREFERENCES_FILL_DEVICES;
|
} PREFERENCES_FILL_DEVICES, *PPREFERENCES_FILL_DEVICES;
|
||||||
|
|
||||||
static BOOL CALLBACK
|
static BOOL CALLBACK
|
||||||
FillDeviceComboBox(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context)
|
FillDeviceComboBox(PSND_MIXER Mixer,
|
||||||
|
UINT Id,
|
||||||
|
LPCTSTR ProductName,
|
||||||
|
PVOID Context)
|
||||||
{
|
{
|
||||||
LRESULT lres;
|
LRESULT lres;
|
||||||
PPREFERENCES_FILL_DEVICES FillContext = (PPREFERENCES_FILL_DEVICES)Context;
|
PPREFERENCES_FILL_DEVICES FillContext = (PPREFERENCES_FILL_DEVICES)Context;
|
||||||
|
|
||||||
lres = SendMessage(FillContext->hComboBox, CB_ADDSTRING, 0, (LPARAM)ProductName);
|
lres = SendMessage(FillContext->hComboBox,
|
||||||
if(lres != CB_ERR)
|
CB_ADDSTRING,
|
||||||
{
|
0,
|
||||||
/* save the index so we don't screw stuff when the combobox is sorted... */
|
(LPARAM)ProductName);
|
||||||
SendMessage(FillContext->hComboBox, CB_SETITEMDATA, (WPARAM)lres, Id);
|
if (lres != CB_ERR)
|
||||||
|
|
||||||
if(Id == FillContext->Selected)
|
|
||||||
{
|
{
|
||||||
SendMessage(FillContext->hComboBox, CB_SETCURSEL, (WPARAM)lres, 0);
|
/* save the index so we don't screw stuff when the combobox is sorted... */
|
||||||
}
|
SendMessage(FillContext->hComboBox,
|
||||||
}
|
CB_SETITEMDATA,
|
||||||
|
(WPARAM)lres,
|
||||||
|
Id);
|
||||||
|
|
||||||
return TRUE;
|
if (Id == FillContext->Selected)
|
||||||
|
{
|
||||||
|
SendMessage(FillContext->hComboBox,
|
||||||
|
CB_SETCURSEL,
|
||||||
|
(WPARAM)lres,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT_PTR CALLBACK
|
static INT_PTR CALLBACK
|
||||||
DlgPreferencesProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
DlgPreferencesProc(HWND hwndDlg,
|
||||||
|
UINT uMsg,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
PPREFERENCES_CONTEXT Context;
|
PPREFERENCES_CONTEXT Context;
|
||||||
|
|
||||||
switch(uMsg)
|
switch (uMsg)
|
||||||
{
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
{
|
||||||
switch(LOWORD(wParam))
|
case WM_COMMAND:
|
||||||
{
|
|
||||||
case IDOK:
|
|
||||||
case IDCANCEL:
|
|
||||||
{
|
{
|
||||||
EndDialog(hwndDlg, LOWORD(wParam));
|
switch (LOWORD(wParam))
|
||||||
break;
|
{
|
||||||
|
case IDOK:
|
||||||
|
case IDCANCEL:
|
||||||
|
{
|
||||||
|
EndDialog(hwndDlg,
|
||||||
|
LOWORD(wParam));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MM_MIXM_LINE_CHANGE:
|
||||||
|
{
|
||||||
|
DPRINT("MM_MIXM_LINE_CHANGE\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MM_MIXM_CONTROL_CHANGE:
|
||||||
|
{
|
||||||
|
DPRINT("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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case MM_MIXM_LINE_CHANGE:
|
return 0;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -155,253 +176,285 @@ DeleteMixerWindowControls(PMIXER_WINDOW MixerWindow)
|
||||||
BOOL
|
BOOL
|
||||||
RebuildMixerWindowControls(PMIXER_WINDOW MixerWindow)
|
RebuildMixerWindowControls(PMIXER_WINDOW MixerWindow)
|
||||||
{
|
{
|
||||||
DeleteMixerWindowControls(MixerWindow);
|
DeleteMixerWindowControls(MixerWindow);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
MainWindowProc(HWND hwnd,
|
||||||
|
UINT uMsg,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
PMIXER_WINDOW MixerWindow;
|
PMIXER_WINDOW MixerWindow;
|
||||||
LRESULT Result = 0;
|
LRESULT Result = 0;
|
||||||
|
|
||||||
switch(uMsg)
|
switch (uMsg)
|
||||||
{
|
|
||||||
case WM_COMMAND:
|
|
||||||
{
|
{
|
||||||
MixerWindow = GetWindowData(hwnd, MIXER_WINDOW);
|
case WM_COMMAND:
|
||||||
|
|
||||||
switch(LOWORD(wParam))
|
|
||||||
{
|
|
||||||
case IDC_PROPERTIES:
|
|
||||||
{
|
{
|
||||||
PREFERENCES_CONTEXT Preferences;
|
MixerWindow = GetWindowData(hwnd,
|
||||||
|
MIXER_WINDOW);
|
||||||
|
|
||||||
Preferences.MixerWindow = MixerWindow;
|
switch (LOWORD(wParam))
|
||||||
Preferences.Mixer = NULL;
|
{
|
||||||
|
case IDC_PROPERTIES:
|
||||||
|
{
|
||||||
|
PREFERENCES_CONTEXT Preferences;
|
||||||
|
|
||||||
if(DialogBoxParam(hAppInstance,
|
Preferences.MixerWindow = MixerWindow;
|
||||||
MAKEINTRESOURCE(IDD_PREFERENCES),
|
Preferences.Mixer = NULL;
|
||||||
hwnd,
|
|
||||||
DlgPreferencesProc,
|
if (DialogBoxParam(hAppInstance,
|
||||||
(LPARAM)&Preferences) == IDOK)
|
MAKEINTRESOURCE(IDD_PREFERENCES),
|
||||||
{
|
hwnd,
|
||||||
/* FIXME - update window */
|
DlgPreferencesProc,
|
||||||
}
|
(LPARAM)&Preferences) == IDOK)
|
||||||
break;
|
{
|
||||||
|
/* FIXME - update window */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IDC_EXIT:
|
||||||
|
{
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IDC_EXIT:
|
case MM_MIXM_LINE_CHANGE:
|
||||||
{
|
{
|
||||||
PostQuitMessage(0);
|
DPRINT("MM_MIXM_LINE_CHANGE\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MM_MIXM_LINE_CHANGE:
|
case MM_MIXM_CONTROL_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];
|
DPRINT("MM_MIXM_CONTROL_CHANGE\n");
|
||||||
|
break;
|
||||||
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
|
|
||||||
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
Result = -1;
|
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))
|
||||||
|
{
|
||||||
|
DPRINT("Rebuilding mixer window controls failed!\n");
|
||||||
|
SndMixerDestroy(MixerWindow->Mixer);
|
||||||
|
Result = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("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);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG("Failed to create status window!\n");
|
|
||||||
Result = -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_DESTROY:
|
return Result;
|
||||||
{
|
|
||||||
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
|
static BOOL
|
||||||
RegisterApplicationClasses(VOID)
|
RegisterApplicationClasses(VOID)
|
||||||
{
|
{
|
||||||
WNDCLASSEX wc;
|
WNDCLASSEX wc;
|
||||||
|
|
||||||
wc.cbSize = sizeof(WNDCLASSEX);
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
wc.lpfnWndProc = MainWindowProc;
|
wc.lpfnWndProc = MainWindowProc;
|
||||||
wc.cbClsExtra = 0;
|
wc.cbClsExtra = 0;
|
||||||
wc.cbWndExtra = sizeof(PMIXER_WINDOW);
|
wc.cbWndExtra = sizeof(PMIXER_WINDOW);
|
||||||
wc.hInstance = hAppInstance;
|
wc.hInstance = hAppInstance;
|
||||||
wc.hIcon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_MAINAPP));
|
wc.hIcon = LoadIcon(hAppInstance,
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
MAKEINTRESOURCE(IDI_MAINAPP));
|
||||||
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
|
wc.hCursor = LoadCursor(NULL,
|
||||||
wc.lpszMenuName = NULL;
|
IDC_ARROW);
|
||||||
wc.lpszClassName = SZ_APP_CLASS;
|
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
|
||||||
wc.hIconSm = NULL;
|
wc.lpszMenuName = NULL;
|
||||||
MainWindowClass = RegisterClassEx(&wc);
|
wc.lpszClassName = SZ_APP_CLASS;
|
||||||
|
wc.hIconSm = NULL;
|
||||||
|
MainWindowClass = RegisterClassEx(&wc);
|
||||||
|
|
||||||
return MainWindowClass != 0;
|
return MainWindowClass != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
UnregisterApplicationClasses(VOID)
|
UnregisterApplicationClasses(VOID)
|
||||||
{
|
{
|
||||||
UnregisterClass(SZ_APP_CLASS, hAppInstance);
|
UnregisterClass(SZ_APP_CLASS,
|
||||||
|
hAppInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HWND
|
static HWND
|
||||||
CreateApplicationWindow(VOID)
|
CreateApplicationWindow(VOID)
|
||||||
{
|
{
|
||||||
LPTSTR lpAppTitle;
|
LPTSTR lpAppTitle;
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
|
||||||
PMIXER_WINDOW MixerWindow = HeapAlloc(hAppHeap, 0, sizeof(MIXER_WINDOW));
|
PMIXER_WINDOW MixerWindow = HeapAlloc(hAppHeap,
|
||||||
if(MixerWindow == NULL)
|
0,
|
||||||
{
|
sizeof(MIXER_WINDOW));
|
||||||
return NULL;
|
if (MixerWindow == NULL)
|
||||||
}
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* load the application title */
|
/* load the application title */
|
||||||
if(RosAllocAndLoadString(&lpAppTitle,
|
if (AllocAndLoadString(&lpAppTitle,
|
||||||
hAppInstance,
|
hAppInstance,
|
||||||
IDS_SNDVOL32) == 0)
|
IDS_SNDVOL32) == 0)
|
||||||
{
|
{
|
||||||
lpAppTitle = NULL;
|
lpAppTitle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mixerGetNumDevs() > 0)
|
if (mixerGetNumDevs() > 0)
|
||||||
{
|
{
|
||||||
hWnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT,
|
hWnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT,
|
||||||
SZ_APP_CLASS,
|
SZ_APP_CLASS,
|
||||||
lpAppTitle,
|
lpAppTitle,
|
||||||
WS_DLGFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
|
WS_DLGFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
NULL,
|
NULL,
|
||||||
LoadMenu(hAppInstance, MAKEINTRESOURCE(IDM_MAINMENU)),
|
LoadMenu(hAppInstance,
|
||||||
hAppInstance,
|
MAKEINTRESOURCE(IDM_MAINMENU)),
|
||||||
MixerWindow);
|
hAppInstance,
|
||||||
}
|
MixerWindow);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
LPTSTR lpErrMessage;
|
{
|
||||||
|
LPTSTR lpErrMessage;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* no mixer devices are available!
|
* no mixer devices are available!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hWnd = NULL;
|
hWnd = NULL;
|
||||||
RosAllocAndLoadString(&lpErrMessage,
|
AllocAndLoadString(&lpErrMessage,
|
||||||
hAppInstance,
|
hAppInstance,
|
||||||
IDS_NOMIXERDEVICES);
|
IDS_NOMIXERDEVICES);
|
||||||
MessageBox(NULL, lpErrMessage, lpAppTitle, MB_ICONINFORMATION);
|
MessageBox(NULL,
|
||||||
LocalFree(lpErrMessage);
|
lpErrMessage,
|
||||||
}
|
lpAppTitle,
|
||||||
|
MB_ICONINFORMATION);
|
||||||
|
LocalFree(lpErrMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if(lpAppTitle != NULL)
|
if (lpAppTitle != NULL)
|
||||||
{
|
{
|
||||||
LocalFree(lpAppTitle);
|
LocalFree(lpAppTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hWnd == NULL)
|
if (hWnd == NULL)
|
||||||
{
|
{
|
||||||
HeapFree(hAppHeap, 0, MixerWindow);
|
HeapFree(hAppHeap,
|
||||||
}
|
0,
|
||||||
|
MixerWindow);
|
||||||
|
}
|
||||||
|
|
||||||
return hWnd;
|
return hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI
|
int WINAPI
|
||||||
WinMain(HINSTANCE hInstance,
|
WinMain(HINSTANCE hInstance,
|
||||||
HINSTANCE hPrevInstance,
|
HINSTANCE hPrevInstance,
|
||||||
LPSTR lpszCmdLine,
|
LPSTR lpszCmdLine,
|
||||||
int nCmdShow)
|
int nCmdShow)
|
||||||
{
|
{
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
|
|
||||||
hAppInstance = hInstance;
|
hAppInstance = hInstance;
|
||||||
hAppHeap = GetProcessHeap();
|
hAppHeap = GetProcessHeap();
|
||||||
|
|
||||||
InitCommonControls();
|
InitCommonControls();
|
||||||
|
|
||||||
if(!RegisterApplicationClasses())
|
if (!RegisterApplicationClasses())
|
||||||
{
|
{
|
||||||
DBG("Failed to register application classes (LastError: %d)!\n", GetLastError());
|
DPRINT("Failed to register application classes (LastError: %d)!\n", GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hMainWnd = CreateApplicationWindow();
|
hMainWnd = CreateApplicationWindow();
|
||||||
if(hMainWnd == NULL)
|
if (hMainWnd == NULL)
|
||||||
{
|
{
|
||||||
DBG("Failed to creat application window (LastError: %d)!\n", GetLastError());
|
DPRINT("Failed to creat application window (LastError: %d)!\n", GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(GetMessage(&Msg, NULL, 0, 0))
|
while (GetMessage(&Msg,
|
||||||
{
|
NULL,
|
||||||
TranslateMessage(&Msg);
|
0,
|
||||||
DispatchMessage(&Msg);
|
0))
|
||||||
}
|
{
|
||||||
|
TranslateMessage(&Msg);
|
||||||
|
DispatchMessage(&Msg);
|
||||||
|
}
|
||||||
|
|
||||||
DestroyWindow(hMainWnd);
|
DestroyWindow(hMainWnd);
|
||||||
|
|
||||||
UnregisterApplicationClasses();
|
UnregisterApplicationClasses();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,8 @@ extern HANDLE hAppHeap;
|
||||||
|
|
||||||
#define SZ_APP_CLASS TEXT("Volume Control")
|
#define SZ_APP_CLASS TEXT("Volume Control")
|
||||||
|
|
||||||
#define DBG DbgPrint("SNDVOL32: %s:%i: ", __FILE__, __LINE__); DbgPrint
|
ULONG DbgPrint(PCH , ...);
|
||||||
|
#define DPRINT DbgPrint("SNDVOL32: %s:%i: ", __FILE__, __LINE__); DbgPrint
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -74,4 +75,18 @@ BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOI
|
||||||
INT SndMixerGetDestinationCount(PSND_MIXER Mixer);
|
INT SndMixerGetDestinationCount(PSND_MIXER Mixer);
|
||||||
BOOL SndMixerEnumDestinationLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context);
|
BOOL SndMixerEnumDestinationLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MISC
|
||||||
|
*/
|
||||||
|
INT
|
||||||
|
AllocAndLoadString(OUT LPWSTR *lpTarget,
|
||||||
|
IN HINSTANCE hInst,
|
||||||
|
IN UINT uID);
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
LoadAndFormatString(IN HINSTANCE hInstance,
|
||||||
|
IN UINT uID,
|
||||||
|
OUT LPWSTR *lpTarget,
|
||||||
|
...);
|
||||||
|
|
||||||
#endif /* __SNDVOL32_H */
|
#endif /* __SNDVOL32_H */
|
||||||
|
|
19
reactos/subsys/system/sndvol32/sndvol32.xml
Normal file
19
reactos/subsys/system/sndvol32/sndvol32.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<module name="sndvol32" type="win32gui" installbase="system32" installname="sndvol32.exe">
|
||||||
|
<include base="ReactOS">include/wine</include>
|
||||||
|
<include base="sndvol32">.</include>
|
||||||
|
<define name="__USE_W32API" />
|
||||||
|
<define name="UNICODE" />
|
||||||
|
<define name="_UNICODE" />
|
||||||
|
<define name="_WIN32_WINNT">0x6501</define>
|
||||||
|
<library>ntdll</library>
|
||||||
|
<library>user32</library>
|
||||||
|
<library>gdi32</library>
|
||||||
|
<library>kernel32</library>
|
||||||
|
<library>comctl32</library>
|
||||||
|
<library>shell32</library>
|
||||||
|
<library>winmm</library>
|
||||||
|
<pch>sndvol32.h</pch>
|
||||||
|
<file>misc.c</file>
|
||||||
|
<file>mixer.c</file>
|
||||||
|
<file>sndvol32.c</file>
|
||||||
|
</module>
|
Loading…
Reference in a new issue