📄 sndvol32.c
字号:
/*
* 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
*/
/* $Id: sndvol32.c 23148 2006-07-18 14:39:37Z hpoussin $
*
* 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;
LPTSTR lpAppTitle;
#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;
UINT Selected;
DWORD SelectedLine;
DWORD PlaybackID;
DWORD RecordingID;
UINT OtherLines;
TCHAR DeviceName[128];
DWORD tmp;
} 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;
UNREFERENCED_PARAMETER(Mixer);
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 BOOL CALLBACK
PrefDlgAddLine(PSND_MIXER Mixer,
LPMIXERLINE Line,
UINT DisplayControls,
PVOID Context)
{
PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
UNREFERENCED_PARAMETER(Mixer);
UNREFERENCED_PARAMETER(DisplayControls);
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;
HWND hwndControls;
LVITEM lvi;
UINT i;
UNREFERENCED_PARAMETER(Mixer);
UNREFERENCED_PARAMETER(LineID);
if (Line->cControls != 0)
{
hwndControls = GetDlgItem(PrefContext->hwndDlg,
IDC_CONTROLS);
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = PrefContext->tmp++;
lvi.iSubItem = 0;
lvi.pszText = Line->szName;
lvi.lParam = (LPARAM)Line->dwSource;
i = SendMessage(hwndControls,
LVM_INSERTITEM,
0,
(LPARAM)&lvi);
if (i != (UINT)-1)
{
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,
SelLine);
}
}
return TRUE;
}
static VOID
UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context,
DWORD LineID)
{
UINT OldID, MixerID = 0;
INT DeviceCbIndex;
/* select the mixer */
DeviceCbIndex = SendDlgItemMessage(Context->hwndDlg,
IDC_MIXERDEVICE,
CB_GETCURSEL,
0,
0);
if (DeviceCbIndex != CB_ERR)
{
MixerID = SendDlgItemMessage(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;
SndMixerGetProductName(Context->Mixer,
Context->DeviceName,
sizeof(Context->DeviceName) / sizeof(Context->DeviceName[0]));
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 */
SendDlgItemMessage(Context->hwndDlg,
IDC_LINE,
CB_SETCURSEL,
0,
0);
}
EnableWindow(GetDlgItem(Context->hwndDlg,
IDC_LINE),
FALSE);
EnableWindow(GetDlgItem(Context->hwndDlg,
IDC_OTHER),
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;
(void)ListView_DeleteAllItems(GetDlgItem(Context->hwndDlg,
IDC_CONTROLS));
Context->tmp = 0;
SndMixerEnumConnections(Context->Mixer,
LineID,
PrefDlgAddConnection,
Context);
}
}
static INT_PTR CALLBACK
DlgPreferencesProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PPREFERENCES_CONTEXT Context;
switch (uMsg)
{
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)
{
DWORD LineID;
DWORD Index;
Index = SendDlgItemMessage(hwndDlg,
IDC_LINE,
CB_GETCURSEL,
0,
0);
if (Index != CB_ERR)
{
LineID = SendDlgItemMessage(hwndDlg,
IDC_LINE,
CB_GETITEMDATA,
Index,
0);
if (LineID != CB_ERR)
{
UpdatePrefDlgControls(Context,
LineID);
}
}
}
break;
}
case IDC_PLAYBACK:
{
UpdatePrefDlgControls(Context,
Context->PlaybackID);
EnableWindow(GetDlgItem(hwndDlg,
IDC_LINE),
FALSE);
break;
}
case IDC_RECORDING:
{
UpdatePrefDlgControls(Context,
Context->RecordingID);
EnableWindow(GetDlgItem(hwndDlg,
IDC_LINE),
FALSE);
break;
}
case IDC_OTHER:
{
INT LineCbIndex;
DWORD LineID;
EnableWindow(GetDlgItem(hwndDlg,
IDC_LINE),
TRUE);
LineCbIndex = SendDlgItemMessage(hwndDlg,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -