partly implemented the mixer selection dialog

svn path=/trunk/; revision=18115
This commit is contained in:
Thomas Bluemel 2005-09-27 01:02:15 +00:00
parent 2360c29d24
commit 7c58d9be05
9 changed files with 393 additions and 34 deletions

View file

@ -35,6 +35,8 @@ BEGIN
PUSHBUTTON "&Záznam", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
PUSHBUTTON "&Jiné:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
PUSHBUTTON "OK", IDOK, 114,226,50,14
PUSHBUTTON "Zrušit", IDCANCEL, 168,226,50,14

View file

@ -35,6 +35,8 @@ BEGIN
PUSHBUTTON "&Aufnahme", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
PUSHBUTTON "A&ndere:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
PUSHBUTTON "OK", IDOK, 114,226,50,14
PUSHBUTTON "Abbrechen", IDCANCEL, 168,226,50,14

View file

@ -35,6 +35,8 @@ BEGIN
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
LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
PUSHBUTTON "OK", IDOK, 114,226,50,14
PUSHBUTTON "Cancel", IDCANCEL, 168,226,50,14

View file

@ -35,6 +35,8 @@ BEGIN
PUSHBUTTON "&Enregistrement", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
PUSHBUTTON "&Autre :", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
PUSHBUTTON "OK", IDOK, 114,226,50,14
PUSHBUTTON "Annuler", IDCANCEL, 168,226,50,14

View file

@ -117,11 +117,12 @@ SndMixerQueryControls(PSND_MIXER Mixer,
if (LineInfo->cControls > 0)
{
*Controls = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
0,
LineInfo->cControls * sizeof(MIXERCONTROL));
if (*Controls != NULL)
{
MIXERLINECONTROLS LineControls;
MMRESULT Result;
UINT j;
LineControls.cbStruct = sizeof(LineControls);
@ -130,18 +131,14 @@ SndMixerQueryControls(PSND_MIXER Mixer,
LineControls.cbmxctrl = sizeof(MIXERCONTROL);
LineControls.pamxctrl = (PVOID)(*Controls);
for (j = 0; j < LineInfo->cControls; j++)
Result = mixerGetLineControls((HMIXEROBJ)Mixer->hmx,
&LineControls,
MIXER_GETLINECONTROLSF_ALL);
if (Result == MMSYSERR_NOERROR)
{
(*Controls)[j].cbStruct = sizeof(MIXERCONTROL);
}
if (mixerGetLineControls((HMIXEROBJ)Mixer->hmx,
&LineControls,
MIXER_GETLINECONTROLSF_ALL) == MMSYSERR_NOERROR)
{
for (j = 0; j < LineInfo->cControls; j++)
for (j = 0; j < LineControls.cControls; j++)
{
DPRINT("Line control: %ws", (*Controls)[j].szName);
DPRINT("Line control: %ws\n", (*Controls)[j].szName);
}
return TRUE;
@ -152,12 +149,12 @@ SndMixerQueryControls(PSND_MIXER Mixer,
0,
*Controls);
*Controls = NULL;
DPRINT("Failed to get line controls!\n");
DPRINT("Failed to get line (ID: 0x%x) controls: %d\n", LineInfo->dwLineID, Result);
}
}
else
{
DPRINT("Failed to allocate memory for %d line controls!\n", LineInfo->cControls);
DPRINT("Failed to allocate memory for %d line (ID: 0x%x) controls!\n", LineInfo->dwLineID, LineInfo->cControls);
}
return FALSE;
@ -174,19 +171,23 @@ SndMixerQueryConnections(PSND_MIXER Mixer,
{
UINT i;
MIXERLINE LineInfo;
MMRESULT Result;
BOOL Ret = TRUE;
LineInfo.cbStruct = sizeof(LineInfo);
LineInfo.dwDestination = Line->Info.dwDestination;
for (i = Line->Info.cConnections; i > 0; i--)
{
LineInfo.dwDestination = Line->Info.dwDestination;
LineInfo.dwSource = i - 1;
if (mixerGetLineInfo((HMIXEROBJ)Mixer->hmx,
&LineInfo,
MIXER_GETLINEINFOF_SOURCE) == MMSYSERR_NOERROR)
Result = mixerGetLineInfo((HMIXEROBJ)Mixer->hmx,
&LineInfo,
MIXER_GETLINEINFOF_SOURCE);
if (Result == MMSYSERR_NOERROR)
{
LPMIXERCONTROL Controls;
PSND_MIXER_CONNECTION Con;
DPRINT("++ Source: %ws\n", LineInfo.szName);
if (!SndMixerQueryControls(Mixer,
&LineInfo,
@ -216,7 +217,7 @@ SndMixerQueryConnections(PSND_MIXER Mixer,
}
else
{
DPRINT("Failed to get connection information!\n");
DPRINT("Failed to get connection information: %d\n", Result);
Ret = FALSE;
break;
}
@ -246,6 +247,8 @@ 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");
@ -445,3 +448,38 @@ SndMixerEnumLines(PSND_MIXER Mixer,
return FALSE;
}
BOOL
SndMixerEnumConnections(PSND_MIXER Mixer,
DWORD LineID,
PFNSNDMIXENUMCONNECTIONS EnumProc,
PVOID Context)
{
if (Mixer->hmx)
{
PSND_MIXER_DESTINATION Line;
for (Line = Mixer->Lines; Line != NULL; Line = Line->Next)
{
if (Line->Info.dwLineID == LineID)
{
PSND_MIXER_CONNECTION Connection;
for (Connection = Line->Connections; Connection != NULL; Connection = Connection->Next)
{
if (!EnumProc(Mixer,
LineID,
&Connection->Info,
Context))
{
return FALSE;
}
}
return TRUE;
}
}
}
return FALSE;
}

View file

@ -17,6 +17,8 @@
#define IDC_RECORDING 1003
#define IDC_OTHER 1004
#define IDC_LINE 1005
#define IDC_LABELCONTROLS 1006
#define IDC_CONTROLS 1007
#define IDS_SNDVOL32 100
#define IDS_NOMIXERDEVICES 101

View file

@ -31,6 +31,7 @@ HINSTANCE hAppInstance;
ATOM MainWindowClass;
HWND hMainWnd;
HANDLE hAppHeap;
LPTSTR lpAppTitle;
#define GetDialogData(hwndDlg, type) \
( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)
@ -44,6 +45,12 @@ typedef struct _PREFERENCES_CONTEXT
PMIXER_WINDOW MixerWindow;
PSND_MIXER Mixer;
HWND hwndDlg;
UINT Selected;
DWORD SelectedLine;
DWORD PlaybackID;
DWORD RecordingID;
UINT OtherLines;
} PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
typedef struct _PREFERENCES_FILL_DEVICES
@ -86,6 +93,209 @@ FillDeviceComboBox(PSND_MIXER Mixer,
return TRUE;
}
static BOOL CALLBACK
PrefDlgAddLine(PSND_MIXER Mixer,
LPMIXERLINE Line,
PVOID Context)
{
PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
switch (Line->dwComponentType)
{
case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
if (PrefContext->PlaybackID == (DWORD)-1)
{
PrefContext->PlaybackID = Line->dwLineID;
if (PrefContext->SelectedLine == (DWORD)-1)
{
PrefContext->SelectedLine = Line->dwLineID;
}
}
else
goto AddToOthersLines;
break;
case MIXERLINE_COMPONENTTYPE_DST_WAVEIN:
if (PrefContext->RecordingID == (DWORD)-1)
{
PrefContext->RecordingID = Line->dwLineID;
if (PrefContext->SelectedLine == (DWORD)-1)
{
PrefContext->SelectedLine = Line->dwLineID;
}
}
else
goto AddToOthersLines;
break;
default:
{
LRESULT lres;
HWND hwndCbOthers;
if (PrefContext->SelectedLine == (DWORD)-1)
{
PrefContext->SelectedLine = Line->dwLineID;
}
AddToOthersLines:
hwndCbOthers = GetDlgItem(PrefContext->hwndDlg,
IDC_LINE);
lres = SendMessage(hwndCbOthers,
CB_ADDSTRING,
0,
(LPARAM)Line->szName);
if (lres != CB_ERR)
{
SendMessage(hwndCbOthers,
CB_SETITEMDATA,
(WPARAM)lres,
Line->dwLineID);
PrefContext->OtherLines++;
}
break;
}
}
return TRUE;
}
static BOOL CALLBACK
PrefDlgAddConnection(PSND_MIXER Mixer,
DWORD LineID,
LPMIXERLINE Line,
PVOID Context)
{
PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
LVITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.pszText = Line->szName;
lvi.lParam = (LPARAM)Line->dwSource;
SendMessage(GetDlgItem(PrefContext->hwndDlg,
IDC_CONTROLS),
LVM_INSERTITEM,
0,
(LPARAM)&lvi);
return TRUE;
}
static VOID
UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context,
DWORD LineID)
{
UINT OldID, MixerID = 0;
INT DeviceCbIndex;
/* select the mixer */
DeviceCbIndex = SendMessage(GetDlgItem(Context->hwndDlg,
IDC_MIXERDEVICE),
CB_GETCURSEL,
0,
0);
if (DeviceCbIndex != CB_ERR)
{
MixerID = SendMessage(GetDlgItem(Context->hwndDlg,
IDC_MIXERDEVICE),
CB_GETITEMDATA,
DeviceCbIndex,
0);
if (MixerID == CB_ERR)
{
MixerID = 0;
}
}
OldID = Context->Selected;
if (MixerID != OldID &&
SndMixerSelect(Context->Mixer,
MixerID))
{
Context->Selected = SndMixerGetSelection(Context->Mixer);
/* update the controls */
Context->PlaybackID = (DWORD)-1;
Context->RecordingID = (DWORD)-1;
Context->OtherLines = 0;
Context->SelectedLine = (DWORD)-1;
if (SndMixerEnumLines(Context->Mixer,
PrefDlgAddLine,
Context))
{
UINT SelBox = 0;
/* enable/disable controls and make default selection */
EnableWindow(GetDlgItem(Context->hwndDlg,
IDC_PLAYBACK),
Context->PlaybackID != (DWORD)-1);
CheckDlgButton(Context->hwndDlg,
IDC_PLAYBACK,
(Context->PlaybackID != (DWORD)-1 && SelBox++ == 0) ?
BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(Context->hwndDlg,
IDC_RECORDING),
Context->RecordingID != (DWORD)-1);
CheckDlgButton(Context->hwndDlg,
IDC_RECORDING,
(Context->RecordingID != (DWORD)-1 && SelBox++ == 0) ?
BST_CHECKED : BST_UNCHECKED);
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);
}
EnableWindow(GetDlgItem(Context->hwndDlg,
IDC_LINE),
Context->OtherLines != 0);
CheckDlgButton(Context->hwndDlg,
IDC_LINE,
(Context->OtherLines != 0 && SelBox++ == 0) ?
BST_CHECKED : BST_UNCHECKED);
/* disable the OK button if the device doesn't have any lines */
EnableWindow(GetDlgItem(Context->hwndDlg,
IDOK),
Context->PlaybackID != (DWORD)-1 ||
Context->RecordingID != (DWORD)-1 ||
Context->OtherLines != 0);
LineID = Context->SelectedLine;
}
}
/* update the line sources list */
if ((MixerID != OldID && Context->SelectedLine != (DWORD)-1) ||
(Context->SelectedLine != LineID && LineID != (DWORD)-1))
{
Context->SelectedLine = LineID;
ListView_DeleteAllItems(GetDlgItem(Context->hwndDlg,
IDC_CONTROLS));
SndMixerEnumConnections(Context->Mixer,
LineID,
PrefDlgAddConnection,
Context);
}
}
static INT_PTR CALLBACK
DlgPreferencesProc(HWND hwndDlg,
UINT uMsg,
@ -98,8 +308,70 @@ DlgPreferencesProc(HWND hwndDlg,
{
case WM_COMMAND:
{
Context = GetDialogData(hwndDlg,
PREFERENCES_CONTEXT);
switch (LOWORD(wParam))
{
case IDC_MIXERDEVICE:
{
if (HIWORD(wParam) == CBN_SELCHANGE)
{
UpdatePrefDlgControls(Context,
(DWORD)-1);
}
break;
}
case IDC_LINE:
{
if (HIWORD(wParam) == CBN_SELCHANGE)
{
UpdatePrefDlgControls(Context,
(DWORD)-1);
}
break;
}
case IDC_PLAYBACK:
{
UpdatePrefDlgControls(Context,
Context->PlaybackID);
break;
}
case IDC_RECORDING:
{
UpdatePrefDlgControls(Context,
Context->RecordingID);
break;
}
case IDC_OTHER:
{
INT LineCbIndex;
DWORD LineID;
LineCbIndex = SendMessage(GetDlgItem(Context->hwndDlg,
IDC_MIXERDEVICE),
CB_GETCURSEL,
0,
0);
if (LineCbIndex != CB_ERR)
{
LineID = SendMessage(GetDlgItem(Context->hwndDlg,
IDC_MIXERDEVICE),
CB_GETITEMDATA,
LineCbIndex,
0);
if (LineID != CB_ERR)
{
UpdatePrefDlgControls(Context,
LineID);
}
}
break;
}
case IDOK:
case IDCANCEL:
{
@ -126,6 +398,9 @@ DlgPreferencesProc(HWND hwndDlg,
case WM_INITDIALOG:
{
PREFERENCES_FILL_DEVICES FillDevContext;
LVCOLUMN lvc;
RECT rcClient;
HWND hwndControls;
SetWindowLongPtr(hwndDlg,
DWLP_USER,
@ -133,6 +408,7 @@ DlgPreferencesProc(HWND hwndDlg,
Context = (PPREFERENCES_CONTEXT)((LONG_PTR)lParam);
Context->hwndDlg = hwndDlg;
Context->Mixer = SndMixerCreate(hwndDlg);
Context->Selected = (UINT)-1;
FillDevContext.PrefContext = Context;
FillDevContext.hComboBox = GetDlgItem(hwndDlg,
@ -141,6 +417,26 @@ DlgPreferencesProc(HWND hwndDlg,
SndMixerEnumProducts(Context->Mixer,
FillDeviceComboBox,
&FillDevContext);
/* initialize the list view control */
hwndControls = GetDlgItem(hwndDlg,
IDC_CONTROLS);
ListView_SetExtendedListViewStyle(hwndControls,
LVS_EX_CHECKBOXES);
GetClientRect(hwndControls,
&rcClient);
lvc.mask = LVCF_TEXT | LVCF_WIDTH;
lvc.pszText = TEXT("");
lvc.cx = rcClient.right;
SendMessage(hwndControls,
LVM_INSERTCOLUMN,
0,
(LPARAM)&lvc);
/* update all controls */
UpdatePrefDlgControls(Context,
(DWORD)-1);
return TRUE;
}
@ -222,6 +518,17 @@ MainWindowProc(HWND hwnd,
PostQuitMessage(0);
break;
}
case IDC_ABOUT:
{
HICON hAppIcon = (HICON)GetClassLongPtrW(hwnd,
GCLP_HICON);
ShellAbout(hwnd,
lpAppTitle,
NULL,
hAppIcon);
break;
}
}
break;
}
@ -350,7 +657,6 @@ UnregisterApplicationClasses(VOID)
static HWND
CreateApplicationWindow(VOID)
{
LPTSTR lpAppTitle;
HWND hWnd;
PMIXER_WINDOW MixerWindow = HeapAlloc(hAppHeap,
@ -361,14 +667,6 @@ CreateApplicationWindow(VOID)
return NULL;
}
/* load the application title */
if (AllocAndLoadString(&lpAppTitle,
hAppInstance,
IDS_SNDVOL32) == 0)
{
lpAppTitle = NULL;
}
if (mixerGetNumDevs() > 0)
{
hWnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT,
@ -401,11 +699,6 @@ CreateApplicationWindow(VOID)
LocalFree(lpErrMessage);
}
if (lpAppTitle != NULL)
{
LocalFree(lpAppTitle);
}
if (hWnd == NULL)
{
HeapFree(hAppHeap,
@ -426,6 +719,14 @@ WinMain(HINSTANCE hInstance,
hAppInstance = hInstance;
hAppHeap = GetProcessHeap();
/* load the application title */
if (AllocAndLoadString(&lpAppTitle,
hAppInstance,
IDS_SNDVOL32) == 0)
{
lpAppTitle = NULL;
}
InitCommonControls();
@ -454,6 +755,11 @@ WinMain(HINSTANCE hInstance,
DestroyWindow(hMainWnd);
UnregisterApplicationClasses();
if (lpAppTitle != NULL)
{
LocalFree(lpAppTitle);
}
return 0;
}

View file

@ -4,6 +4,7 @@
#include <windows.h>
#include <mmsystem.h>
#include <commctrl.h>
#include <shellapi.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
@ -63,6 +64,7 @@ typedef struct _SND_MIXER
} SND_MIXER, *PSND_MIXER;
typedef BOOL (CALLBACK *PFNSNDMIXENUMLINES)(PSND_MIXER Mixer, LPMIXERLINE Line, 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);
PSND_MIXER SndMixerCreate(HWND hWndNotification);
@ -73,7 +75,8 @@ 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);
BOOL SndMixerEnumLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context);
BOOL SndMixerEnumConnections(PSND_MIXER Mixer, DWORD LineID, PFNSNDMIXENUMCONNECTIONS EnumProc, PVOID Context);
/*
* MISC

View file

@ -4,7 +4,9 @@
<define name="__USE_W32API" />
<define name="UNICODE" />
<define name="_UNICODE" />
<define name="_WIN32_WINNT">0x6501</define>
<define name="_WIN32_IE">0x0500</define>
<define name="_WIN32_WINNT">0x0600</define>
<define name="WINVER">0x0600</define>
<library>ntdll</library>
<library>user32</library>
<library>gdi32</library>