load some settings from the registry

svn path=/trunk/; revision=18123
This commit is contained in:
Thomas Bluemel 2005-09-27 13:42:20 +00:00
parent 2d5aef6968
commit 043d319095
4 changed files with 298 additions and 38 deletions

View file

@ -127,3 +127,121 @@ LoadAndFormatString(IN HINSTANCE hInstance,
return Ret;
}
/* NOTE: do NOT modify SNDVOL_REG_LINESTATE for binary compatibility with XP! */
typedef struct _SNDVOL_REG_LINESTATE
{
DWORD Flags;
WCHAR LineName[MIXER_LONG_NAME_CHARS];
} SNDVOL_REG_LINESTATE, *PSNDVOL_REG_LINESTATE;
static const TCHAR AppRegSettings[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Volume Control");
static const TCHAR AppOptionsKey[] = TEXT("Options");
static const TCHAR LineStatesValue[] = TEXT("LineStates");
static const TCHAR StyleValue[] = TEXT("Style");
HKEY hAppSettingsKey = NULL;
BOOL
InitAppConfig(VOID)
{
return RegCreateKeyEx(HKEY_CURRENT_USER,
AppRegSettings,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hAppSettingsKey,
NULL) == ERROR_SUCCESS;
}
VOID
CloseAppConfig(VOID)
{
if (hAppSettingsKey != NULL)
{
RegCloseKey(hAppSettingsKey);
hAppSettingsKey = NULL;
}
}
BOOL
ReadLineConfig(IN LPTSTR szDeviceName,
IN LPTSTR szLineName,
IN LPTSTR szControlName,
OUT DWORD *Flags)
{
HKEY hLineKey;
DWORD Type;
DWORD i, Size = 0;
PSNDVOL_REG_LINESTATE LineStates = NULL;
TCHAR szDevRegKey[MAX_PATH];
BOOL Ret = FALSE;
_stprintf(szDevRegKey,
TEXT("%s\\%s"),
szDeviceName,
szLineName);
if (RegCreateKeyEx(hAppSettingsKey,
szDevRegKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hLineKey,
NULL) == ERROR_SUCCESS)
{
if (RegQueryValueEx(hLineKey,
LineStatesValue,
NULL,
&Type,
NULL,
&Size) != ERROR_SUCCESS ||
Type != REG_BINARY ||
Size == 0 || (Size % sizeof(SNDVOL_REG_LINESTATE) != 0))
{
goto ExitClose;
}
LineStates = HeapAlloc(GetProcessHeap(),
0,
Size);
if (LineStates != NULL)
{
if (RegQueryValueEx(hLineKey,
LineStatesValue,
NULL,
&Type,
(LPBYTE)LineStates,
&Size) != ERROR_SUCCESS ||
Type != REG_BINARY ||
Size == 0 || (Size % sizeof(SNDVOL_REG_LINESTATE) != 0))
{
goto ExitClose;
}
/* try to find the control */
for (i = 0; i < Size / sizeof(SNDVOL_REG_LINESTATE); i++)
{
if (!_tcscmp(szControlName,
LineStates[i].LineName))
{
*Flags = LineStates[i].Flags;
Ret = TRUE;
break;
}
}
}
ExitClose:
HeapFree(GetProcessHeap(),
0,
LineStates);
RegCloseKey(hLineKey);
}
return Ret;
}

View file

@ -111,6 +111,7 @@ SndMixerClose(PSND_MIXER Mixer)
static BOOL
SndMixerQueryControls(PSND_MIXER Mixer,
PUINT DisplayControls,
LPMIXERLINE LineInfo,
LPMIXERCONTROL *Controls)
{
@ -138,7 +139,13 @@ SndMixerQueryControls(PSND_MIXER Mixer,
{
for (j = 0; j < LineControls.cControls; j++)
{
DPRINT("Line control: %ws\n", (*Controls)[j].szName);
if (SndMixerIsDisplayControl(Mixer,
&(*Controls)[j]))
{
(*DisplayControls)++;
}
DPRINT("Line control: %ws (0x%x, 0x%x)\n", (*Controls)[j].szName, (*Controls)[j].fdwControl, (*Controls)[j].dwControlType);
}
return TRUE;
@ -169,7 +176,7 @@ static BOOL
SndMixerQueryConnections(PSND_MIXER Mixer,
PSND_MIXER_DESTINATION Line)
{
UINT i;
UINT i, DispControls;
MIXERLINE LineInfo;
MMRESULT Result;
BOOL Ret = TRUE;
@ -188,8 +195,11 @@ SndMixerQueryConnections(PSND_MIXER Mixer,
PSND_MIXER_CONNECTION Con;
DPRINT("++ Source: %ws\n", LineInfo.szName);
DispControls = 0;
if (!SndMixerQueryControls(Mixer,
&DispControls,
&LineInfo,
&Controls))
{
@ -205,6 +215,7 @@ SndMixerQueryConnections(PSND_MIXER Mixer,
{
Con->Info = LineInfo;
Con->Controls = Controls;
Con->DisplayControls = DispControls;
Con->Next = Line->Connections;
Line->Connections = Con;
}
@ -247,15 +258,10 @@ SndMixerQueryDestinations(PSND_MIXER Mixer)
&Line->Info,
MIXER_GETLINEINFOF_DESTINATION) == MMSYSERR_NOERROR)
{
DPRINT("+ Destination: %ws (%d)\n", Line->Info.szName, Line->Info.dwComponentType);
if (!SndMixerQueryConnections(Mixer, Line))
{
DPRINT("Failed to query mixer connections!\n");
Ret = FALSE;
break;
}
DPRINT("+ Destination: %ws (0x%x, %d)\n", Line->Info.szName, Line->Info.dwLineID, Line->Info.dwComponentType);
if (!SndMixerQueryControls(Mixer,
&Line->DisplayControls,
&Line->Info,
&Line->Controls))
{
@ -264,6 +270,13 @@ SndMixerQueryDestinations(PSND_MIXER Mixer)
break;
}
if (!SndMixerQueryConnections(Mixer, Line))
{
DPRINT("Failed to query mixer connections!\n");
Ret = FALSE;
break;
}
Line->Next = Mixer->Lines;
Mixer->Lines = Line;
}
@ -374,6 +387,47 @@ SndMixerGetProductName(PSND_MIXER Mixer,
return -1;
}
INT
SndMixerGetLineName(PSND_MIXER Mixer,
DWORD LineID,
LPTSTR lpBuffer,
UINT uSize,
BOOL LongName)
{
if (Mixer->hmx)
{
int lnsz;
PSND_MIXER_DESTINATION Line;
LPMIXERLINE lpl = NULL;
for (Line = Mixer->Lines; Line != NULL; Line = Line->Next)
{
if (Line->Info.dwLineID == LineID)
{
lpl = &Line->Info;
break;
}
}
if (lpl != NULL)
{
lnsz = lstrlen(LongName ? lpl->szName : lpl->szShortName);
if(lnsz + 1 > uSize)
{
return lnsz + 1;
}
else
{
memcpy(lpBuffer, LongName ? lpl->szName : lpl->szShortName, lnsz * sizeof(TCHAR));
lpBuffer[lnsz] = _T('\0');
return lnsz;
}
}
}
return -1;
}
BOOL
SndMixerEnumProducts(PSND_MIXER Mixer,
PFNSNDMIXENUMPRODUCTS EnumProc,
@ -436,6 +490,7 @@ SndMixerEnumLines(PSND_MIXER Mixer,
{
if (!EnumProc(Mixer,
&Line->Info,
Line->DisplayControls,
Context))
{
return FALSE;
@ -463,6 +518,17 @@ SndMixerEnumConnections(PSND_MIXER Mixer,
if (Line->Info.dwLineID == LineID)
{
PSND_MIXER_CONNECTION Connection;
if (Line->DisplayControls != 0)
{
if (!EnumProc(Mixer,
LineID,
&Line->Info,
Context))
{
return FALSE;
}
}
for (Connection = Line->Connections; Connection != NULL; Connection = Connection->Next)
{
@ -483,3 +549,20 @@ SndMixerEnumConnections(PSND_MIXER Mixer,
return FALSE;
}
BOOL
SndMixerIsDisplayControl(PSND_MIXER Mixer,
LPMIXERCONTROL Control)
{
if (Mixer->hmx && !(Control->fdwControl & MIXERCONTROL_CONTROLF_DISABLED))
{
switch (Control->dwControlType & MIXERCONTROL_CT_CLASS_MASK)
{
case MIXERCONTROL_CT_CLASS_FADER:
case MIXERCONTROL_CT_CLASS_SWITCH:
return TRUE;
}
}
return FALSE;
}

View file

@ -51,6 +51,7 @@ typedef struct _PREFERENCES_CONTEXT
DWORD PlaybackID;
DWORD RecordingID;
UINT OtherLines;
TCHAR DeviceName[128];
DWORD tmp;
} PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
@ -98,6 +99,7 @@ FillDeviceComboBox(PSND_MIXER Mixer,
static BOOL CALLBACK
PrefDlgAddLine(PSND_MIXER Mixer,
LPMIXERLINE Line,
UINT DisplayControls,
PVOID Context)
{
PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
@ -113,6 +115,8 @@ PrefDlgAddLine(PSND_MIXER Mixer,
{
PrefContext->SelectedLine = Line->dwLineID;
}
DPRINT("!%ws cControls: %d\n", Line->szName, Line->cControls);
}
else
goto AddToOthersLines;
@ -128,6 +132,7 @@ PrefDlgAddLine(PSND_MIXER Mixer,
{
PrefContext->SelectedLine = Line->dwLineID;
}
DPRINT("!%ws cControls: %d\n", Line->szName, Line->cControls);
}
else
goto AddToOthersLines;
@ -196,10 +201,33 @@ PrefDlgAddConnection(PSND_MIXER Mixer,
(LPARAM)&lvi);
if (i != (UINT)-1)
{
/* FIXME - read config from registry */
TCHAR LineName[MIXER_LONG_NAME_CHARS];
DWORD Flags;
BOOL SelLine = FALSE;
if (SndMixerGetLineName(PrefContext->Mixer,
PrefContext->SelectedLine,
LineName,
MIXER_LONG_NAME_CHARS,
FALSE) == -1)
{
LineName[0] = TEXT('\0');
}
if (ReadLineConfig(PrefContext->DeviceName,
LineName,
Line->szName,
&Flags))
{
if (Flags != 0x4)
{
SelLine = TRUE;
}
}
ListView_SetCheckState(hwndControls,
i,
FALSE);
SelLine);
}
}
@ -214,18 +242,18 @@ UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context,
INT DeviceCbIndex;
/* select the mixer */
DeviceCbIndex = SendMessage(GetDlgItem(Context->hwndDlg,
IDC_MIXERDEVICE),
CB_GETCURSEL,
0,
0);
DeviceCbIndex = SendDlgItemMessage(Context->hwndDlg,
IDC_MIXERDEVICE,
CB_GETCURSEL,
0,
0);
if (DeviceCbIndex != CB_ERR)
{
MixerID = SendMessage(GetDlgItem(Context->hwndDlg,
IDC_MIXERDEVICE),
CB_GETITEMDATA,
DeviceCbIndex,
0);
MixerID = SendDlgItemMessage(Context->hwndDlg,
IDC_MIXERDEVICE,
CB_GETITEMDATA,
DeviceCbIndex,
0);
if (MixerID == CB_ERR)
{
MixerID = 0;
@ -244,6 +272,10 @@ UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context,
Context->RecordingID = (DWORD)-1;
Context->OtherLines = 0;
Context->SelectedLine = (DWORD)-1;
SndMixerGetProductName(Context->Mixer,
Context->DeviceName,
sizeof(Context->DeviceName) / sizeof(Context->DeviceName[0]));
if (SndMixerEnumLines(Context->Mixer,
PrefDlgAddLine,
@ -271,11 +303,11 @@ UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context,
if (Context->OtherLines != 0)
{
/* select the first item in the other lines combo box by default */
SendMessage(GetDlgItem(Context->hwndDlg,
IDC_LINE),
CB_SETCURSEL,
0,
0);
SendDlgItemMessage(Context->hwndDlg,
IDC_LINE,
CB_SETCURSEL,
0,
0);
}
EnableWindow(GetDlgItem(Context->hwndDlg,
IDC_LINE),
@ -349,18 +381,18 @@ DlgPreferencesProc(HWND hwndDlg,
DWORD LineID;
DWORD Index;
Index = SendMessage(GetDlgItem(hwndDlg,
IDC_LINE),
CB_GETCURSEL,
0,
0);
Index = SendDlgItemMessage(hwndDlg,
IDC_LINE,
CB_GETCURSEL,
0,
0);
if (Index != CB_ERR)
{
LineID = SendMessage(GetDlgItem(hwndDlg,
IDC_LINE),
CB_GETITEMDATA,
Index,
0);
LineID = SendDlgItemMessage(hwndDlg,
IDC_LINE,
CB_GETITEMDATA,
Index,
0);
if (LineID != CB_ERR)
{
UpdatePrefDlgControls(Context,
@ -769,6 +801,12 @@ WinMain(HINSTANCE hInstance,
hAppInstance = hInstance;
hAppHeap = GetProcessHeap();
if (!InitAppConfig())
{
DPRINT("Unable to open the Volume Control registry key!\n");
return 1;
}
/* load the application title */
if (AllocAndLoadString(&lpAppTitle,
hAppInstance,
@ -809,6 +847,8 @@ WinMain(HINSTANCE hInstance,
{
LocalFree(lpAppTitle);
}
CloseAppConfig();
return 0;
}

View file

@ -42,6 +42,7 @@ typedef struct _SND_MIXER_CONNECTION
struct _SND_MIXER_CONNECTION *Next;
MIXERLINE Info;
LPMIXERCONTROL Controls;
UINT DisplayControls;
} SND_MIXER_CONNECTION, *PSND_MIXER_CONNECTION;
@ -50,6 +51,7 @@ typedef struct _SND_MIXER_DESTINATION
struct _SND_MIXER_DESTINATION *Next;
MIXERLINE Info;
LPMIXERCONTROL Controls;
UINT DisplayControls;
PSND_MIXER_CONNECTION Connections;
} SND_MIXER_DESTINATION, *PSND_MIXER_DESTINATION;
@ -63,7 +65,7 @@ typedef struct _SND_MIXER
PSND_MIXER_DESTINATION Lines;
} SND_MIXER, *PSND_MIXER;
typedef BOOL (CALLBACK *PFNSNDMIXENUMLINES)(PSND_MIXER Mixer, LPMIXERLINE Line, PVOID Context);
typedef BOOL (CALLBACK *PFNSNDMIXENUMLINES)(PSND_MIXER Mixer, LPMIXERLINE Line, UINT DisplayControls, PVOID Context);
typedef BOOL (CALLBACK *PFNSNDMIXENUMCONNECTIONS)(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context);
typedef BOOL (CALLBACK *PFNSNDMIXENUMPRODUCTS)(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context);
@ -73,14 +75,25 @@ 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);
INT SndMixerGetLineName(PSND_MIXER Mixer, DWORD LineID, LPTSTR lpBuffer, UINT uSize, BOOL LongName);
BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context);
INT SndMixerGetDestinationCount(PSND_MIXER Mixer);
BOOL SndMixerEnumLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context);
BOOL SndMixerEnumConnections(PSND_MIXER Mixer, DWORD LineID, PFNSNDMIXENUMCONNECTIONS EnumProc, PVOID Context);
BOOL SndMixerIsDisplayControl(PSND_MIXER Mixer, LPMIXERCONTROL Control);
/*
* MISC
*/
extern HKEY hAppSettingsKey;
BOOL
InitAppConfig(VOID);
VOID
CloseAppConfig(VOID);
INT
AllocAndLoadString(OUT LPWSTR *lpTarget,
IN HINSTANCE hInst,
@ -92,4 +105,10 @@ LoadAndFormatString(IN HINSTANCE hInstance,
OUT LPWSTR *lpTarget,
...);
BOOL
ReadLineConfig(IN LPTSTR szDeviceName,
IN LPTSTR szLineName,
IN LPTSTR szControlName,
OUT DWORD *Flags);
#endif /* __SNDVOL32_H */