windows-nt/Source/XPSP1/NT/shell/osshell/control/mmsys/msacmcpl.c
2020-09-26 16:20:57 +08:00

1918 lines
52 KiB
C

//==========================================================================;
//
// cpl.c
//
// Copyright (c) 1991-1993 Microsoft Corporation. All Rights Reserved.
//
// Description:
//
//
// History:
// 07/94 VijR (Vij Rajarajan);
//
// 10/95 R Jernigan - removed link to Adv tab's treeview control
//
//==========================================================================;
#include "mmcpl.h"
#include <windowsx.h>
#include <mmsystem.h>
#include <dbt.h>
#include <ks.h>
#include <ksmedia.h>
#include <mmddkp.h>
#include <mmreg.h>
#include <msacm.h>
#include <msacmdrv.h>
#include <msacmdlg.h>
#include <stdlib.h>
#include "gfxui.h"
#include "drivers.h"
#include "advaudio.h"
#include "roland.h"
#include <objbase.h>
#include <setupapi.h>
#include <cfgmgr32.h>
#include <initguid.h>
#include <devguid.h>
#define WM_ACMMAP_ACM_NOTIFY (WM_USER + 100)
#include <memory.h>
#include <commctrl.h>
#include <prsht.h>
#include <regstr.h>
#include "trayvol.h"
#include "utils.h"
#include "medhelp.h"
/*
***************************************************************
* Defines
***************************************************************
*/
#ifndef DRV_F_ADD
#define DRV_F_ADD 0x00000000 // TODO: Should be in MMDDK.H
#define DRV_F_REMOVE 0x00000001
#define DRV_F_CHANGE 0x00000002
#define DRV_F_PROP_INSTR 0x00000004
#define DRV_F_NEWDEFAULTS 0x00000008
#define DRV_F_PARAM_IS_DEVNODE 0x10000000
#endif
#ifndef ACMHELPMSGCONTEXTMENU // TODO: Should
#define ACMHELPMSGCONTEXTMENU TEXT("acmchoose_contextmenu") // be in MSACM.H
#define ACMHELPMSGCONTEXTHELP TEXT("acmchoose_contexthelp")
#endif
#ifndef ACMFORMATCHOOSE_STYLEF_CONTEXTHELP // TODO: Should be in MSACM.H
#define ACMFORMATCHOOSE_STYLEF_CONTEXTHELP 0x00000080L
#endif
/*
***************************************************************
* Globals
***************************************************************
*/
BOOL gfLoadedACM;
UINT giDevChange = 0;
WNDPROC gfnPSProc = NULL;
HWND ghDlg;
/*
***************************************************************
* Typedefs
***************************************************************
*/
typedef struct tACMDRIVERSETTINGS
{
HACMDRIVERID hadid;
DWORD fdwSupport;
DWORD dwPriority;
} ACMDRIVERSETTINGS, FAR *LPACMDRIVERSETTINGS;
typedef struct _CplCodecInfo
{
TCHAR szDesc[128];
ACMDRIVERSETTINGS ads;
HICON hIcon;
BOOL fMadeIcon;
}CPLCODECINFO, * PCPLCODECINFO;
/*
***************************************************************
* File Globals
***************************************************************
*/
static CONST TCHAR aszFormatNumber[] = TEXT("%lu");
//
// These hold Window Message IDs for the two messages sent from the
// Customize dialog (acmFormatChoose) for context-sensitive help.
//
UINT guCustomizeContextMenu = WM_NULL;
UINT guCustomizeContextHelp = WM_NULL;
BOOL fHaveStartedAudioDialog = FALSE;
/*
***************************************************************
* extern
***************************************************************
*/
//
// this string variable must be large enough to hold the IDS_TXT_DISABLED
// resource string.. for USA, this is '(disabled)'--which is 11 bytes
// including the NULL terminator.
//
TCHAR gszDevEnabled[256];
TCHAR gszDevDisabled[256];
/*
***************************************************************
* Prototypes
***************************************************************
*/
BOOL PASCAL DoACMPropCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify);
BOOL PASCAL DoAudioCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify);
BOOL PASCAL CustomizeDialog(HWND hDlg, LPTSTR szNewFormat, DWORD cbSize);
void DoAdvancedSetup(HWND hwnd);
void WAVEOUTInit(HWND hDlg, PAUDIODLGINFO pai);
void WAVEINInit(HWND hDlg, PAUDIODLGINFO pai);
PCPLCODECINFO acmFindCodecInfo (WORD, WORD);
BOOL CALLBACK acmFindCodecInfoCallback (HACMDRIVERID, DWORD_PTR, DWORD);
void acmFreeCodecInfo (PCPLCODECINFO);
UINT acmCountCodecs (void);
BOOL CALLBACK acmCountCodecsEnum (HACMDRIVERID, DWORD_PTR, DWORD);
#ifndef ACM_DRIVERREMOVEF_UNINSTALL
#define ACM_DRIVERREMOVEF_UNINSTALL 0x00000001L
#endif
/*
***************************************************************
***************************************************************
*/
void acmDeleteCodec (WORD wMid, WORD wPid)
{
PCPLCODECINFO pci;
if ((pci = acmFindCodecInfo (wMid, wPid)) != NULL)
{
acmDriverRemove (pci->ads.hadid, ACM_DRIVERREMOVEF_UNINSTALL);
acmFreeCodecInfo (pci);
}
}
//--------------------------------------------------------------------------;
//
// INT_PTR DlgProcACMAboutBox
//
// Description:
//
//
// Arguments:
//
// Return (BOOL):
//
//
// History:
// 11/16/92 cjp [curtisp]
//
//--------------------------------------------------------------------------;
INT_PTR CALLBACK DlgProcACMAboutBox
(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
TCHAR ach[80];
TCHAR szFormat[80];
LPACMDRIVERDETAILS padd;
DWORD dw1;
DWORD dw2;
UINT uCmdId;
switch (uMsg)
{
case WM_INITDIALOG:
{
padd = (LPACMDRIVERDETAILSW)lParam;
if (NULL == padd)
{
DPF(0, "!DlgProcACMAboutBox: NULL driver details passed!");
return (TRUE);
}
//
// fill in all the static text controls with the long info
// returned from the driver
//
LoadString(ghInstance, IDS_ABOUT_TITLE, szFormat, sizeof(szFormat)/sizeof(TCHAR));
wsprintf(ach, szFormat, (LPTSTR)padd->szShortName);
SetWindowText(hwnd, ach);
//
// if the driver supplies an icon, then use it..
//
if (NULL != padd->hicon)
{
Static_SetIcon(GetDlgItem(hwnd, IDD_ABOUT_ICON_DRIVER), padd->hicon);
}
SetDlgItemText(hwnd, IDD_ABOUT_TXT_DESCRIPTION, padd->szLongName);
dw1 = padd->vdwACM;
dw2 = padd->vdwDriver;
LoadString(ghInstance, IDS_ABOUT_VERSION, szFormat, sizeof(szFormat)/sizeof(TCHAR));
wsprintf(ach, szFormat, HIWORD(dw2) >> 8, (BYTE)HIWORD(dw2), HIWORD(dw1) >> 8, (BYTE)HIWORD(dw1));
SetDlgItemText(hwnd,IDD_ABOUT_TXT_VERSION, ach);
SetDlgItemText(hwnd, IDD_ABOUT_TXT_COPYRIGHT, padd->szCopyright);
SetDlgItemText(hwnd, IDD_ABOUT_TXT_LICENSING, padd->szLicensing);
SetDlgItemText(hwnd, IDD_ABOUT_TXT_FEATURES, padd->szFeatures);
return (TRUE);
}
break;
case WM_COMMAND:
{
uCmdId = GET_WM_COMMAND_ID(wParam,lParam);
if ((uCmdId == IDOK) || (uCmdId == IDCANCEL))
EndDialog(hwnd, wParam == uCmdId);
return (TRUE);
}
break;
}
return (FALSE);
} // DlgProcACMAboutBox()
//--------------------------------------------------------------------------;
//
// void ControlAboutDriver
//
// Description:
//
//
// Arguments:
// HWND hwnd:
//
// LPACMDRIVERSETTINGS pads:
//
// Return (void):
//
// History:
// 09/08/93 cjp [curtisp]
//
//--------------------------------------------------------------------------;
STATIC void ControlAboutDriver
(
HWND hwnd,
LPACMDRIVERSETTINGS pads
)
{
PACMDRIVERDETAILSW padd;
MMRESULT mmr;
if (NULL == pads)
{
return;
}
//
// if the driver returns MMSYSERR_NOTSUPPORTED, then we need to
// display the info--otherwise, it supposedly displayed a dialog
// (or had a critical error?)
//
mmr = (MMRESULT)acmDriverMessage((HACMDRIVER)pads->hadid, ACMDM_DRIVER_ABOUT, (LPARAM)hwnd, 0L);
if ((MMRESULT)MMSYSERR_NOTSUPPORTED != mmr)
{
return;
}
//
// alloc some zero-init'd memory to hold the about box info
//
padd = (PACMDRIVERDETAILS)LocalAlloc(LPTR, sizeof(*padd));
if (NULL == padd)
{
DPF("!PACMDRIVERDETAILSA LocalAlloc failed");
return;
}
//
// get info and bring up a generic about box...
//
padd->cbStruct = sizeof(*padd);
mmr = (MMRESULT)acmDriverDetails(pads->hadid, padd, 0L);
if (MMSYSERR_NOERROR == mmr)
{
DialogBoxParam(ghInstance, MAKEINTRESOURCE(DLG_ABOUT_MSACM), hwnd, DlgProcACMAboutBox, (LPARAM)(LPVOID)padd);
}
LocalFree((HLOCAL)padd);
} // ControlAboutDriver()
//--------------------------------------------------------------------------;
//
// BOOL ControlConfigureDriver
//
// Description:
//
//
// Arguments:
// HWND hwnd:
//
// LPACMDRIVERSETTINGS pads:
//
// Return (BOOL):
//
// History:
// 06/15/93 cjp [curtisp]
//
//--------------------------------------------------------------------------;
STATIC BOOL ControlConfigureDriver
(
HWND hwnd,
LPACMDRIVERSETTINGS pads
)
{
if (NULL == pads)
{
return (FALSE);
}
if (acmDriverMessage((HACMDRIVER)pads->hadid,DRV_CONFIGURE,(LPARAM)hwnd,0L) == DRVCNF_RESTART)
{
DisplayMessage(hwnd, IDS_CHANGESAVED, IDS_RESTART, MB_OK);
}
return (TRUE);
} // ControlConfigureDriver()
STATIC void CommitCodecChanges(LPACMDRIVERSETTINGS pads)
{
MMRESULT mmr;
BOOL fDisabled;
DWORD fdwPriority;
mmr = (MMRESULT)acmDriverPriority(NULL, 0L, ACM_DRIVERPRIORITYF_BEGIN);
if (MMSYSERR_NOERROR != mmr)
{
DPF(0, "!ControlApplySettings: acmDriverPriority(end) failed! mmr=%u", mmr);
return;
}
fDisabled = (0 != (ACMDRIVERDETAILS_SUPPORTF_DISABLED & pads->fdwSupport));
fdwPriority = fDisabled ? ACM_DRIVERPRIORITYF_DISABLE : ACM_DRIVERPRIORITYF_ENABLE;
mmr = (MMRESULT)acmDriverPriority(pads->hadid, pads->dwPriority, fdwPriority);
if (MMSYSERR_NOERROR != mmr)
{
DPF(0, "!ControlApplySettings: acmDriverPriority(%.04Xh, %lu, %.08lXh) failed! mmr=%u",
pads->hadid, pads->dwPriority, fdwPriority, mmr);
}
mmr = (MMRESULT)acmDriverPriority(NULL, 0L, ACM_DRIVERPRIORITYF_END);
}
const static DWORD aACMDlgHelpIds[] = { // Context Help IDs
ID_DEV_SETTINGS, IDH_MMCPL_DEVPROP_SETTINGS,
IDD_CPL_BTN_ABOUT, IDH_MMCPL_DEVPROP_ABOUT,
IDC_ENABLE, IDH_MMCPL_DEVPROP_ENABLE,
IDC_DISABLE, IDH_MMCPL_DEVPROP_DISABLE,
IDC_DEV_ICON, NO_HELP,
IDC_DEV_DESC, NO_HELP,
IDC_DEV_STATUS, NO_HELP,
IDD_PRIORITY_TXT_FROMTO, IDH_MMCPL_DEVPROP_CHANGE_PRI,
IDD_PRIORITY_COMBO_PRIORITY, IDH_MMCPL_DEVPROP_CHANGE_PRI,
0, 0
};
INT_PTR CALLBACK ACMDlg(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
NMHDR FAR *lpnm;
static PCPLCODECINFO pci = NULL;
switch (uMsg)
{
case WM_NOTIFY:
{
lpnm = (NMHDR FAR *)lParam;
switch(lpnm->code)
{
case PSN_KILLACTIVE:
FORWARD_WM_COMMAND(hDlg, IDOK, 0, 0, SendMessage);
break;
case PSN_APPLY:
FORWARD_WM_COMMAND(hDlg, ID_APPLY, 0, 0, SendMessage);
break;
case PSN_SETACTIVE:
//FORWARD_WM_COMMAND(hDlg, ID_INIT, 0, 0, SendMessage);
break;
case PSN_RESET:
FORWARD_WM_COMMAND(hDlg, IDCANCEL, 0, 0, SendMessage);
break;
}
}
break;
case WM_INITDIALOG:
{
HWND hwndS = GetDlgItem(hDlg, IDC_DEV_STATUS);
LPARAM lpUser = ((LPPROPSHEETPAGE)lParam)->lParam;
if ((pci = acmFindCodecInfo (LOWORD(lpUser), HIWORD(lpUser))) == NULL)
{
FORWARD_WM_COMMAND(hDlg, IDCANCEL, 0, 0, SendMessage);
break;
}
acmMetrics((HACMOBJ)pci->ads.hadid, ACM_METRIC_DRIVER_PRIORITY, &(pci->ads.dwPriority));
acmMetrics((HACMOBJ)pci->ads.hadid, ACM_METRIC_DRIVER_SUPPORT, &(pci->ads.fdwSupport));
SendDlgItemMessage(hDlg, IDC_DEV_ICON, STM_SETICON, (WPARAM)pci->hIcon, 0L);
SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pci);
SetWindowText(GetDlgItem(hDlg, IDC_DEV_DESC), pci->szDesc);
LoadString (ghInstance, IDS_DEVENABLEDOK, gszDevEnabled, sizeof(gszDevEnabled)/sizeof(TCHAR));
LoadString (ghInstance, IDS_DEVDISABLED, gszDevDisabled, sizeof(gszDevDisabled)/sizeof(TCHAR));
if(pci->ads.fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)
{
SetWindowText(hwndS, gszDevDisabled);
CheckRadioButton(hDlg, IDC_ENABLE, IDC_DISABLE, IDC_DISABLE);
}
else
{
SetWindowText(hwndS, gszDevEnabled);
CheckRadioButton(hDlg, IDC_ENABLE, IDC_DISABLE, IDC_ENABLE);
}
EnableWindow(GetDlgItem(hDlg, ID_DEV_SETTINGS), (MMRESULT)acmDriverMessage((HACMDRIVER)pci->ads.hadid,DRV_QUERYCONFIGURE,0,0));
FORWARD_WM_COMMAND(hDlg, ID_INIT, 0, 0, SendMessage);
}
break;
case WM_DESTROY:
{
FORWARD_WM_COMMAND(hDlg, ID_REBUILD, 0, 0, SendMessage);
if (pci != NULL)
{
acmFreeCodecInfo (pci);
pci = NULL;
}
}
break;
case WM_CONTEXTMENU:
{
WinHelp ((HWND) wParam, NULL, HELP_CONTEXTMENU, (UINT_PTR) (LPTSTR) aACMDlgHelpIds);
return TRUE;
}
break;
case WM_HELP:
{
LPHELPINFO lphi = (LPVOID) lParam;
WinHelp (lphi->hItemHandle, NULL, HELP_WM_HELP, (UINT_PTR) (LPTSTR) aACMDlgHelpIds);
return TRUE;
}
break;
case WM_COMMAND:
{
HANDLE_WM_COMMAND(hDlg, wParam, lParam, DoACMPropCommand);
}
break;
}
return FALSE;
}
BOOL PASCAL DoACMPropCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify)
{
PCPLCODECINFO pci;
LPACMDRIVERSETTINGS pads;
static int iPriority = 0;
static BOOL fDisabled = TRUE;
static BOOL fRebuild;
HWND hwndS = GetDlgItem(hDlg, IDC_DEV_STATUS);
if ((pci = (PCPLCODECINFO)GetWindowLongPtr(hDlg,DWLP_USER)) == NULL)
{
return FALSE;
}
pads = &(pci->ads);
switch (id)
{
case ID_APPLY:
{
HWND hcb = GetDlgItem(hDlg, IDD_PRIORITY_COMBO_PRIORITY);
if ((fDisabled != Button_GetCheck(GetDlgItem(hDlg, IDC_DISABLE))) || (iPriority != ComboBox_GetCurSel(hcb)+1))
{
pads->fdwSupport ^= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
fDisabled = (0 != (pads->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED));
iPriority = pads->dwPriority = ComboBox_GetCurSel(hcb)+1;
CommitCodecChanges(pads);
fRebuild = TRUE;
}
return TRUE;
}
case ID_REBUILD:
{
if (fRebuild && pci)
{
SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)0);
fRebuild = FALSE;
}
}
break;
case ID_INIT:
{
TCHAR achFromTo[80];
TCHAR ach[80];
HWND hcb;
UINT u;
UINT nCodecs;
iPriority = (int)pads->dwPriority;
fDisabled = (0 != (pads->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED));
fRebuild = FALSE;
LoadString(ghInstance, IDS_PRIORITY_FROMTO, achFromTo, sizeof(achFromTo)/sizeof(TCHAR));
wsprintf(ach, achFromTo, iPriority);
SetDlgItemText(hDlg, IDD_PRIORITY_TXT_FROMTO, ach);
hcb = GetDlgItem(hDlg, IDD_PRIORITY_COMBO_PRIORITY);
nCodecs = acmCountCodecs();
for (u = 1; u <= (UINT)nCodecs; u++)
{
wsprintf(ach, aszFormatNumber, (DWORD)u);
ComboBox_AddString(hcb, ach);
}
ComboBox_SetCurSel(hcb, iPriority - 1);
}
break;
case IDD_PRIORITY_COMBO_PRIORITY:
{
switch (codeNotify)
{
case CBN_SELCHANGE:
{
PropSheet_Changed(GetParent(hDlg),hDlg);
}
break;
}
}
break;
case IDC_ENABLE:
{
SetWindowText(hwndS, gszDevEnabled);
CheckRadioButton(hDlg, IDC_ENABLE, IDC_DISABLE, IDC_ENABLE);
PropSheet_Changed(GetParent(hDlg),hDlg);
}
break;
case IDC_DISABLE:
{
SetWindowText(hwndS, gszDevDisabled);
CheckRadioButton(hDlg, IDC_ENABLE, IDC_DISABLE, IDC_DISABLE);
PropSheet_Changed(GetParent(hDlg),hDlg);
}
break;
case ID_DEV_SETTINGS:
{
ControlConfigureDriver(hDlg, pads);
}
break;
case IDD_CPL_BTN_ABOUT:
{
ControlAboutDriver(hDlg, pads);
}
break;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Microsoft Confidential - DO NOT COPY THIS METHOD INTO ANY APPLICATION, THIS MEANS YOU!!!
///////////////////////////////////////////////////////////////////////////////////////////
DWORD GetWaveOutID(BOOL *pfPreferred)
{
MMRESULT mmr;
DWORD_PTR dwWaveID = 0;
DWORD dwFlags = 0;
if (pfPreferred)
{
*pfPreferred = TRUE;
}
mmr = waveOutMessage(HWAVEOUT_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &dwWaveID, (DWORD_PTR) &dwFlags);
if (!mmr && pfPreferred)
{
*pfPreferred = dwFlags & 0x00000001;
}
return(DWORD)(dwWaveID);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Microsoft Confidential - DO NOT COPY THIS METHOD INTO ANY APPLICATION, THIS MEANS YOU!!!
///////////////////////////////////////////////////////////////////////////////////////////
void SetWaveOutID(DWORD dwWaveID, BOOL fPrefOnly)
{
MMRESULT mmr;
DWORD dwParam1, dwParam2;
DWORD dwFlags = fPrefOnly ? 0x00000001 : 0x00000000;
mmr = waveOutMessage(HWAVEOUT_MAPPER, DRVM_MAPPER_PREFERRED_SET, dwWaveID, dwFlags);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Microsoft Confidential - DO NOT COPY THIS METHOD INTO ANY APPLICATION, THIS MEANS YOU!!!
///////////////////////////////////////////////////////////////////////////////////////////
DWORD GetWaveInID(BOOL *pfPreferred)
{
MMRESULT mmr;
DWORD_PTR dwWaveID = 0;
DWORD dwFlags = 0;
if (pfPreferred)
{
*pfPreferred = TRUE;
}
mmr = waveInMessage(HWAVEIN_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &dwWaveID, (DWORD_PTR) &dwFlags);
if (!mmr && pfPreferred)
{
*pfPreferred = dwFlags & 0x00000001;
}
return(DWORD)(dwWaveID);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Microsoft Confidential - DO NOT COPY THIS METHOD INTO ANY APPLICATION, THIS MEANS YOU!!!
///////////////////////////////////////////////////////////////////////////////////////////
void SetWaveInID(DWORD dwWaveID, BOOL fPrefOnly)
{
MMRESULT mmr;
DWORD dwParam1, dwParam2;
DWORD dwFlags = fPrefOnly ? 0x00000001 : 0x00000000;
mmr = waveInMessage(HWAVEIN_MAPPER, DRVM_MAPPER_PREFERRED_SET, dwWaveID, dwFlags);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Microsoft Confidential - DO NOT COPY THIS METHOD INTO ANY APPLICATION, THIS MEANS YOU!!!
///////////////////////////////////////////////////////////////////////////////////////////
DWORD GetMIDIOutID(void)
{
MMRESULT mmr;
DWORD dwWaveID;
DWORD dwFlags = 0;
mmr = midiOutMessage(HMIDIOUT_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &dwWaveID, (DWORD_PTR) &dwFlags);
return(dwWaveID);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Microsoft Confidential - DO NOT COPY THIS METHOD INTO ANY APPLICATION, THIS MEANS YOU!!!
///////////////////////////////////////////////////////////////////////////////////////////
void SetMIDIOutID(DWORD dwWaveID)
{
MMRESULT mmr;
DWORD dwParam1, dwParam2;
mmr = midiOutMessage(HMIDIOUT_MAPPER, DRVM_MAPPER_PREFERRED_SET, dwWaveID, 0);
}
void GetPrefInfo(PAUDIODLGINFO pai, HWND hDlg )
{
MMRESULT mmr;
// Load WaveOut Info
pai->cNumOutDevs = waveOutGetNumDevs();
pai->uPrefOut = GetWaveOutID(&pai->fPrefOnly);
// Load WaveIn Info
pai->cNumInDevs = waveInGetNumDevs();
pai->uPrefIn = GetWaveInID(NULL);
// Load MIDI Out info
pai->cNumMIDIOutDevs = midiOutGetNumDevs();
pai->uPrefMIDIOut = GetMIDIOutID();
}
STATIC void EnablePlayVolCtrls(HWND hDlg, BOOL fEnable)
{
EnableWindow( GetDlgItem(hDlg, IDC_LAUNCH_SNDVOL) , fEnable);
EnableWindow( GetDlgItem(hDlg, IDC_PLAYBACK_ADVSETUP) , fEnable);
}
STATIC void EnableRecVolCtrls(HWND hDlg, BOOL fEnable, BOOL fControl)
{
EnableWindow( GetDlgItem(hDlg, IDC_LAUNCH_RECVOL) , fEnable);
EnableWindow( GetDlgItem(hDlg, IDC_RECORD_ADVSETUP) , fControl);
}
STATIC void EnableMIDIVolCtrls(HWND hDlg, BOOL fEnable)
{
EnableWindow( GetDlgItem(hDlg, IDC_LAUNCH_MUSICVOL) , fEnable);
}
STATIC void SetDeviceOut(PAUDIODLGINFO pai, UINT uID, HWND hDlg)
{
BOOL fEnabled = FALSE;
HMIXER hMixer = NULL;
UINT uMixID;
pai->uPrefOut = uID; // New device, lets setup buttons for this device
if(MMSYSERR_NOERROR == mixerGetID(HMIXEROBJ_INDEX(pai->uPrefOut), &uMixID, MIXER_OBJECTF_WAVEOUT))
{
if(MMSYSERR_NOERROR == mixerOpen(&hMixer, uMixID, 0L, 0L, 0L))
{
fEnabled = TRUE;
mixerClose(hMixer);
}
}
EnablePlayVolCtrls(hDlg, fEnabled);
}
DWORD CountInputs(DWORD dwMixID)
{
MIXERCAPS mc;
MMRESULT mmr;
DWORD dwCount = 0;
mmr = mixerGetDevCaps(dwMixID, &mc, sizeof(mc));
if (mmr == MMSYSERR_NOERROR)
{
MIXERLINE mlDst;
DWORD dwDestination;
DWORD cDestinations;
cDestinations = mc.cDestinations;
for (dwDestination = 0; dwDestination < cDestinations; dwDestination++)
{
mlDst.cbStruct = sizeof ( mlDst );
mlDst.dwDestination = dwDestination;
if (mixerGetLineInfo(HMIXEROBJ_INDEX(dwMixID), &mlDst, MIXER_GETLINEINFOF_DESTINATION ) == MMSYSERR_NOERROR)
{
if (mlDst.dwComponentType == (DWORD)MIXERLINE_COMPONENTTYPE_DST_WAVEIN || // needs to be a likely output destination
mlDst.dwComponentType == (DWORD)MIXERLINE_COMPONENTTYPE_DST_VOICEIN)
{
DWORD cConnections = mlDst.cConnections;
dwCount += mlDst.cControls;
if (cConnections)
{
DWORD dwSource;
for (dwSource = 0; dwSource < cConnections; dwSource++)
{
mlDst.dwDestination = dwDestination;
mlDst.dwSource = dwSource;
if (mixerGetLineInfo(HMIXEROBJ_INDEX(dwMixID), &mlDst, MIXER_GETLINEINFOF_SOURCE ) == MMSYSERR_NOERROR)
{
dwCount += mlDst.cControls;
}
}
}
}
}
}
}
return(dwCount);
}
STATIC void SetDeviceIn(PAUDIODLGINFO pai, UINT uID, HWND hDlg)
{
BOOL fEnabled = FALSE;
BOOL fControl = FALSE;
HMIXER hMixer = NULL;
UINT uMixID;
pai->uPrefIn = uID; // New device, lets setup buttons for this device
if( (MMSYSERR_NOERROR == mixerGetID(HMIXEROBJ_INDEX(pai->uPrefIn),&uMixID, MIXER_OBJECTF_WAVEIN)))
{
if( MMSYSERR_NOERROR == mixerOpen(&hMixer, uMixID, 0L, 0L, 0L))
{
if (CountInputs(uMixID))
{
fEnabled = TRUE;
// If the capture device is not GFX capable, then there are no tabs to display
fControl = GFXUI_CheckDevice(uMixID, GFXTYPE_CAPTURE);
}
mixerClose(hMixer);
}
}
EnableRecVolCtrls(hDlg, fEnabled, fControl);
}
STATIC void SetMIDIDeviceOut(PAUDIODLGINFO pai, UINT uID, HWND hDlg)
{
BOOL fEnabled = FALSE;
HMIXER hMixer = NULL;
UINT uMixID;
MIDIOUTCAPS moc;
MMRESULT mmr;
UINT mid;
pai->uPrefMIDIOut = uID; // New device, lets setup buttons for this device
if(MMSYSERR_NOERROR == mixerGetID(HMIXEROBJ_INDEX(pai->uPrefMIDIOut), &uMixID, MIXER_OBJECTF_MIDIOUT))
{
if(MMSYSERR_NOERROR == mixerOpen(&hMixer, uMixID, 0L, 0L, 0L))
{
fEnabled = TRUE;
mixerClose(hMixer);
}
}
EnableMIDIVolCtrls(hDlg, fEnabled);
fEnabled = FALSE;
mmr = midiOutGetDevCaps(pai->uPrefMIDIOut, &moc, sizeof(moc));
if (MMSYSERR_NOERROR == mmr)
{
if ((moc.wMid == MM_MICROSOFT) && (moc.wPid == MM_MSFT_WDMAUDIO_MIDIOUT) && (moc.wTechnology == MOD_SWSYNTH))
{
fEnabled = TRUE;
}
}
EnableWindow( GetDlgItem(hDlg, IDC_MUSIC_ABOUT) , fEnabled);
}
STDAPI_(void) DoRolandAbout(HWND hWnd)
{
UINT uWaveID = 0;
if (GetWaveID(&uWaveID) != (MMRESULT)MMSYSERR_ERROR)
{
WAVEOUTCAPS woc;
if (waveOutGetDevCaps(uWaveID, &woc, sizeof(woc)) == MMSYSERR_NOERROR)
{
RolandProp(hWnd, ghInstance, woc.szPname);
}
}
}
STATIC void SetPrefInfo(PAUDIODLGINFO pai, HWND hDlg )
{
HWND hwndCBPlay = GetDlgItem(hDlg, IDC_AUDIO_CB_PLAY);
HWND hwndCBRec = GetDlgItem(hDlg, IDC_AUDIO_CB_REC);
HWND hwndCBMIDI = GetDlgItem(hDlg, IDC_MUSIC_CB_PLAY);
HKEY hkeyAcm;
UINT item, deviceID;
TCHAR szPref[MAXSTR];
pai->fPrefOnly = Button_GetCheck(GetDlgItem(hDlg, IDC_AUDIO_PREF));
item = (UINT)ComboBox_GetCurSel(hwndCBPlay);
if (item != CB_ERR)
{
deviceID = (UINT)ComboBox_GetItemData(hwndCBPlay, item);
if(deviceID != pai->uPrefOut) // Make sure device changed
{
SetDeviceOut(pai, deviceID, hDlg); // Configure controls for this device
}
}
item = (UINT)ComboBox_GetCurSel(hwndCBRec);
if (item != CB_ERR)
{
deviceID = (UINT)ComboBox_GetItemData(hwndCBRec, item);
if( deviceID != pai->uPrefIn ) // Make sure device changed
{
SetDeviceIn(pai, deviceID, hDlg); // Configure controls for this device
}
}
item = (UINT)ComboBox_GetCurSel(hwndCBMIDI);
if (item != CB_ERR)
{
deviceID = (UINT)ComboBox_GetItemData(hwndCBMIDI, item);
if(deviceID != pai->uPrefMIDIOut) // Make sure device changed
{
SetMIDIDeviceOut(pai, deviceID, hDlg); // Configure controls for this device
}
}
SetWaveOutID(pai->uPrefOut, pai->fPrefOnly);
SetWaveInID(pai->uPrefIn, pai->fPrefOnly);
SetMIDIOutID(pai->uPrefMIDIOut);
WAVEOUTInit(hDlg, pai);
WAVEINInit(hDlg, pai);
// MIDI Devices are not remapped...
}
STATIC void MSACM_NotifyMapper(void)
{
waveOutMessage(HWAVEOUT_MAPPER, DRVM_MAPPER_RECONFIGURE, 0, DRV_F_NEWDEFAULTS);
waveInMessage(HWAVEIN_MAPPER, DRVM_MAPPER_RECONFIGURE, 0, DRV_F_NEWDEFAULTS);
midiOutMessage(HMIDIOUT_MAPPER, DRVM_MAPPER_RECONFIGURE, 0, DRV_F_NEWDEFAULTS);
}
STATIC void WAVEOUTInit(HWND hDlg, PAUDIODLGINFO pai)
{
HWND hwndCBPlay = GetDlgItem(hDlg, IDC_AUDIO_CB_PLAY);
MMRESULT mr;
UINT device;
TCHAR szNoAudio[128];
szNoAudio[0] = TEXT('\0');
ComboBox_ResetContent(hwndCBPlay);
if (pai->cNumOutDevs == 0)
{
LoadString (ghInstance, IDS_NOAUDIOPLAY, szNoAudio, sizeof(szNoAudio)/sizeof(TCHAR));
ComboBox_AddString(hwndCBPlay, szNoAudio);
ComboBox_SetItemData(hwndCBPlay, 0, (LPARAM)-1);
ComboBox_SetCurSel(hwndCBPlay, 0);
EnableWindow( hwndCBPlay, FALSE );
EnablePlayVolCtrls(hDlg, FALSE);
}
else
{
EnableWindow( hwndCBPlay, TRUE );
for (device = 0; device < pai->cNumOutDevs; device++)
{
WAVEOUTCAPS woc;
int newItem;
woc.szPname[0] = TEXT('\0');
if (waveOutGetDevCapsW(device, &woc, sizeof(woc)))
{
continue;
}
woc.szPname[sizeof(woc.szPname)/sizeof(TCHAR) - 1] = TEXT('\0');
newItem = ComboBox_AddString(hwndCBPlay, woc.szPname);
if (newItem != CB_ERR && newItem != CB_ERRSPACE)
{
ComboBox_SetItemData(hwndCBPlay, newItem, (LPARAM)device);
if (device == pai->uPrefOut)
{
ComboBox_SetCurSel(hwndCBPlay, newItem);
SetDeviceOut(pai, device, hDlg);
}
}
}
}
}
STATIC void WAVEINInit(HWND hDlg, PAUDIODLGINFO pai)
{
HWND hwndCBRec = GetDlgItem(hDlg, IDC_AUDIO_CB_REC);
MMRESULT mr;
UINT device;
TCHAR szNoAudio[128];
ComboBox_ResetContent(hwndCBRec);
if (pai->cNumInDevs == 0)
{
LoadString (ghInstance, IDS_NOAUDIOREC, szNoAudio, sizeof(szNoAudio)/sizeof(TCHAR));
ComboBox_AddString(hwndCBRec, szNoAudio);
ComboBox_SetItemData(hwndCBRec, 0, (LPARAM)-1);
ComboBox_SetCurSel(hwndCBRec, 0);
EnableWindow( hwndCBRec, FALSE );
EnableRecVolCtrls(hDlg, FALSE, FALSE);
}
else
{
EnableWindow( hwndCBRec, TRUE );
for (device = 0; device < pai->cNumInDevs; device++)
{
WAVEINCAPSW wic;
int newItem;
wic.szPname[0] = TEXT('\0');
if (waveInGetDevCapsW(device, &wic, sizeof(wic)))
{
continue;
}
wic.szPname[sizeof(wic.szPname)/sizeof(TCHAR) - 1] = TEXT('\0');
newItem = ComboBox_AddString(hwndCBRec, wic.szPname);
if (newItem != CB_ERR && newItem != CB_ERRSPACE)
{
ComboBox_SetItemData(hwndCBRec, newItem, (LPARAM)device);
if (device == pai->uPrefIn)
{
ComboBox_SetCurSel(hwndCBRec, newItem);
SetDeviceIn(pai, device, hDlg);
}
}
}
}
}
STATIC void MIDIInit(HWND hDlg, PAUDIODLGINFO pai)
{
HWND hwnd = GetDlgItem(hDlg, IDC_MUSIC_CB_PLAY);
MMRESULT mr;
UINT device;
TCHAR szNoAudio[128];
ComboBox_ResetContent(hwnd);
szNoAudio[0] = TEXT('\0');
EnableWindow( GetDlgItem(hDlg, IDC_MUSIC_ABOUT) , FALSE);
if (pai->cNumMIDIOutDevs == 0)
{
LoadString (ghInstance, IDS_NOMIDIPLAY, szNoAudio, sizeof(szNoAudio)/sizeof(TCHAR));
ComboBox_AddString(hwnd, szNoAudio);
ComboBox_SetItemData(hwnd, 0, (LPARAM)-1);
ComboBox_SetCurSel(hwnd, 0);
EnableWindow( hwnd, FALSE );
EnableMIDIVolCtrls(hDlg, FALSE);
}
else
{
EnableWindow( hwnd, TRUE );
for (device = 0; device < pai->cNumMIDIOutDevs; device++)
{
MIDIOUTCAPS moc;
int newItem;
moc.szPname[0] = TEXT('\0');
if (midiOutGetDevCapsW(device, &moc, sizeof(moc)))
{
continue;
}
moc.szPname[sizeof(moc.szPname)/sizeof(TCHAR) - 1] = TEXT('\0');
newItem = ComboBox_AddString(hwnd, moc.szPname);
if (newItem != CB_ERR && newItem != CB_ERRSPACE)
{
ComboBox_SetItemData(hwnd, newItem, (LPARAM)device);
if (device == pai->uPrefMIDIOut)
{
ComboBox_SetCurSel(hwnd, newItem);
SetMIDIDeviceOut(pai, device, hDlg);
}
}
}
}
}
STATIC void AudioDlgInit(HWND hDlg)
{
PAUDIODLGINFO pai = (PAUDIODLGINFO)LocalAlloc(LPTR, sizeof(AUDIODLGINFO));
if (!pai) return;
//
// Register context-sensitive help messages from the Customize dialog.
//
guCustomizeContextMenu = RegisterWindowMessage( ACMHELPMSGCONTEXTMENU );
guCustomizeContextHelp = RegisterWindowMessage( ACMHELPMSGCONTEXTHELP );
SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pai);
GetPrefInfo(pai, hDlg);
CheckDlgButton(hDlg, IDC_AUDIO_PREF, pai->fPrefOnly);
WAVEOUTInit(hDlg, pai);
WAVEINInit(hDlg, pai);
MIDIInit(hDlg, pai);
if (!(pai->cNumInDevs || pai->cNumOutDevs || pai->cNumMIDIOutDevs))
{
CheckDlgButton(hDlg, IDC_AUDIO_PREF, FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_AUDIO_PREF), FALSE);
}
}
const static DWORD aAudioHelpIds[] = { // Context Help IDs
IDC_GROUPBOX, IDH_COMM_GROUPBOX,
IDI_SPEAKERICON, IDH_COMM_GROUPBOX,
IDC_ICON_6, IDH_COMM_GROUPBOX,
IDC_TEXT_4, IDH_AUDIO_PLAY_PREFER_DEV,
IDC_AUDIO_CB_PLAY, IDH_AUDIO_PLAY_PREFER_DEV,
IDC_LAUNCH_SNDVOL, IDH_AUDIO_PLAY_VOL,
IDC_PLAYBACK_ADVSETUP, IDH_ADV_AUDIO_PLAY_PROP,
IDC_GROUPBOX_2, IDH_COMM_GROUPBOX,
IDI_RECORDICON, IDH_COMM_GROUPBOX,
IDC_ICON_7, IDH_COMM_GROUPBOX,
IDC_TEXT_8, IDH_AUDIO_REC_PREFER_DEV,
IDC_AUDIO_CB_REC, IDH_AUDIO_REC_PREFER_DEV,
IDC_LAUNCH_RECVOL, IDH_AUDIO_REC_VOL,
IDC_RECORD_ADVSETUP, IDH_ADV_AUDIO_REC_PROP,
IDC_GROUPBOX_3, IDH_COMM_GROUPBOX,
IDI_MUSICICON, IDH_COMM_GROUPBOX,
IDC_ICON_8, IDH_COMM_GROUPBOX,
IDC_TEXT_9, IDH_MIDI_SINGLE_INST_BUTTON,
IDC_MUSIC_CB_PLAY, IDH_MIDI_SINGLE_INST_BUTTON,
IDC_LAUNCH_MUSICVOL, IDH_AUDIO_MIDI_VOL,
IDC_MUSIC_ABOUT, IDH_ABOUT,
IDC_AUDIO_PREF, IDH_AUDIO_USE_PREF_ONLY,
0, 0
};
const static DWORD aCustomizeHelpIds[] = {
IDD_ACMFORMATCHOOSE_CMB_FORMAT, IDH_AUDIO_CUST_ATTRIB,
IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, IDH_AUDIO_CUST_FORMAT,
IDD_ACMFORMATCHOOSE_CMB_CUSTOM, IDH_AUDIO_CUST_NAME,
IDD_ACMFORMATCHOOSE_BTN_DELNAME, IDH_AUDIO_CUST_REMOVE,
IDD_ACMFORMATCHOOSE_BTN_SETNAME, IDH_AUDIO_CUST_SAVEAS,
0, 0
};
void WinMMDeviceChange(HWND hDlg)
{
PAUDIODLGINFO pai = (PAUDIODLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
// MSACM_NotifyMapper();
GetPrefInfo(pai, hDlg);
CheckDlgButton(hDlg, IDC_AUDIO_PREF, pai->fPrefOnly);
WAVEOUTInit(hDlg, pai);
WAVEINInit(hDlg, pai);
MIDIInit(hDlg, pai);
if (!(pai->cNumInDevs || pai->cNumOutDevs || pai->cNumMIDIOutDevs))
{
CheckDlgButton(hDlg, IDC_AUDIO_PREF, FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_AUDIO_PREF), FALSE);
}
}
LRESULT CALLBACK AudioTabProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
if (iMsg == giDevChange)
{
WinMMDeviceChange(ghDlg);
}
return CallWindowProc(gfnPSProc,hwnd,iMsg,wParam,lParam);
}
void InitDeviceChange(HWND hDlg)
{
gfnPSProc = (WNDPROC) SetWindowLongPtr(GetParent(hDlg),GWLP_WNDPROC,(LONG_PTR)AudioTabProc);
giDevChange = RegisterWindowMessage(TEXT("winmm_devicechange"));
}
void UninitDeviceChange(HWND hDlg)
{
SetWindowLongPtr(GetParent(hDlg),GWLP_WNDPROC,(LONG_PTR)gfnPSProc);
}
BOOL CALLBACK AudioDlg(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
NMHDR FAR *lpnm;
PAUDIODLGINFO pai;
switch (uMsg)
{
case WM_NOTIFY:
{
lpnm = (NMHDR FAR *)lParam;
switch(lpnm->code)
{
case PSN_KILLACTIVE:
FORWARD_WM_COMMAND(hDlg, IDOK, 0, 0, SendMessage);
break;
case PSN_APPLY:
FORWARD_WM_COMMAND(hDlg, ID_APPLY, 0, 0, SendMessage);
break;
case PSN_SETACTIVE:
FORWARD_WM_COMMAND(hDlg, ID_INIT, 0, 0, SendMessage);
break;
case PSN_RESET:
FORWARD_WM_COMMAND(hDlg, IDCANCEL, 0, 0, SendMessage);
break;
}
}
break;
case WM_INITDIALOG:
{
ghDlg = hDlg;
InitDeviceChange(hDlg);
if (!gfLoadedACM)
{
if (LoadACM())
{
gfLoadedACM = TRUE;
}
else
{
DPF("****Load ACM failed**\r\n");
ASSERT(FALSE);
ErrorBox(hDlg, IDS_CANTLOADACM, NULL);
ExitThread(0);
}
}
AudioDlgInit(hDlg);
}
break;
case WM_DESTROY:
{
UninitDeviceChange(hDlg);
pai = (PAUDIODLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
LocalFree((HLOCAL)pai);
if (gfLoadedACM)
{
if (!FreeACM())
{
DPF("****Free ACM failed**\r\n");
ASSERT(FALSE);
}
gfLoadedACM = FALSE;
}
}
break;
case WM_CONTEXTMENU:
{
WinHelp ((HWND) wParam, NULL, HELP_CONTEXTMENU, (UINT_PTR) (LPTSTR) aAudioHelpIds);
return TRUE;
}
break;
case WM_HELP:
{
LPHELPINFO lphi = (LPVOID) lParam;
WinHelp (lphi->hItemHandle, NULL, HELP_WM_HELP, (UINT_PTR) (LPTSTR) aAudioHelpIds);
return TRUE;
}
break;
case WM_COMMAND:
{
HANDLE_WM_COMMAND(hDlg, wParam, lParam, DoAudioCommand);
}
break;
default:
{
//
// Handle context-sensitive help messages from Customize dlg.
//
if( uMsg == guCustomizeContextMenu )
{
WinHelp( (HWND)wParam, NULL, HELP_CONTEXTMENU, (UINT_PTR)(LPTSTR)aCustomizeHelpIds );
}
else if( uMsg == guCustomizeContextHelp )
{
WinHelp( ((LPHELPINFO)lParam)->hItemHandle, NULL, HELP_WM_HELP, (UINT_PTR)(LPTSTR)aCustomizeHelpIds);
}
}
break;
}
return FALSE;
}
void ErrorMsgBox(HWND hDlg, UINT uTitle, UINT uMessage)
{
TCHAR szMsg[MAXSTR];
TCHAR szTitle[MAXSTR];
LoadString(ghInstance, IDS_ERROR_TITLE, szTitle, sizeof(szTitle)/sizeof(TCHAR));
LoadString(ghInstance, IDS_ERROR_NOSNDVOL, szMsg, sizeof(szMsg)/sizeof(TCHAR));
MessageBox(hDlg, szMsg,szTitle,MB_OK);
}
void LaunchPlaybackVolume(HWND hDlg)
{
HWND hwndCBPlay = GetDlgItem(hDlg, IDC_AUDIO_CB_PLAY);
UINT item;
item = (UINT)ComboBox_GetCurSel(hwndCBPlay);
if (item != CB_ERR)
{
TCHAR szCmd[MAXSTR];
UINT uDeviceID;
MMRESULT mmr;
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW;
uDeviceID = (UINT)ComboBox_GetItemData(hwndCBPlay, item);
mmr = mixerGetID(HMIXEROBJ_INDEX(uDeviceID), &uDeviceID, MIXER_OBJECTF_WAVEOUT);
if (mmr == MMSYSERR_NOERROR)
{
wsprintf(szCmd,TEXT("sndvol32.exe -D %d"),uDeviceID);
if (!CreateProcess(NULL,szCmd,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{
ErrorMsgBox(hDlg,IDS_ERROR_TITLE,IDS_ERROR_NOSNDVOL);
}
}
else
{
ErrorMsgBox(hDlg,IDS_ERROR_TITLE,IDS_ERROR_NOMIXER);
}
}
}
void LaunchRecordVolume(HWND hDlg)
{
HWND hwndCBRec = GetDlgItem(hDlg, IDC_AUDIO_CB_REC);
UINT item;
item = (UINT)ComboBox_GetCurSel(hwndCBRec);
if (item != CB_ERR)
{
TCHAR szCmd[MAXSTR];
UINT uDeviceID;
MMRESULT mmr;
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW;
uDeviceID = (UINT)ComboBox_GetItemData(hwndCBRec, item);
mmr = mixerGetID(HMIXEROBJ_INDEX(uDeviceID), &uDeviceID, MIXER_OBJECTF_WAVEIN);
if (mmr == MMSYSERR_NOERROR)
{
wsprintf(szCmd,TEXT("sndvol32.exe -R -D %d"),uDeviceID);
if (!CreateProcess(NULL,szCmd,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{
ErrorMsgBox(hDlg,IDS_ERROR_TITLE,IDS_ERROR_NOSNDVOL);
}
}
else
{
ErrorMsgBox(hDlg,IDS_ERROR_TITLE,IDS_ERROR_NOMIXER);
}
}
}
void LaunchMIDIVolume(HWND hDlg)
{
HWND hwndCBMIDI = GetDlgItem(hDlg, IDC_MUSIC_CB_PLAY);
UINT item;
item = (UINT)ComboBox_GetCurSel(hwndCBMIDI);
if (item != CB_ERR)
{
TCHAR szCmd[MAXSTR];
DWORD dwDeviceID;
MMRESULT mmr;
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW;
dwDeviceID = (UINT)ComboBox_GetItemData(hwndCBMIDI, item);
mmr = mixerGetID(HMIXEROBJ_INDEX(dwDeviceID), &dwDeviceID, MIXER_OBJECTF_MIDIOUT);
if (mmr == MMSYSERR_NOERROR)
{
wsprintf(szCmd,TEXT("sndvol32.exe -D %d"),dwDeviceID);
if (!CreateProcess(NULL,szCmd,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{
ErrorMsgBox(hDlg,IDS_ERROR_TITLE,IDS_ERROR_NOSNDVOL);
}
}
else
{
ErrorMsgBox(hDlg,IDS_ERROR_TITLE,IDS_ERROR_NOMIXER);
}
}
}
BOOL PASCAL DoAudioCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify)
{
PAUDIODLGINFO pai = (PAUDIODLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
if (!gfLoadedACM)
{
return FALSE;
}
switch (id)
{
case ID_APPLY:
{
SetPrefInfo(pai, hDlg);
}
break;
case IDC_AUDIO_CB_PLAY:
case IDC_AUDIO_CB_REC:
case IDC_MUSIC_CB_PLAY:
{
switch (codeNotify)
{
case CBN_SELCHANGE:
{
PropSheet_Changed(GetParent(hDlg),hDlg);
if ((id == IDC_AUDIO_CB_PLAY) || (id == IDC_AUDIO_CB_REC) || id == IDC_MUSIC_CB_PLAY)
{
int iIndex;
AUDIODLGINFO aiTmp;
PAUDIODLGINFO paiTmp = &aiTmp;
iIndex = ComboBox_GetCurSel(hwndCtl);
if (iIndex != CB_ERR)
{
if (id == IDC_AUDIO_CB_PLAY)
{
paiTmp->uPrefOut = (UINT)ComboBox_GetItemData(hwndCtl, iIndex);
SetDeviceOut(paiTmp, paiTmp->uPrefOut, hDlg);
}
else if (id == IDC_AUDIO_CB_REC)
{
paiTmp->uPrefIn = (UINT)ComboBox_GetItemData(hwndCtl, iIndex);
SetDeviceIn(paiTmp, paiTmp->uPrefIn, hDlg);
}
else if (id == IDC_MUSIC_CB_PLAY)
{
paiTmp->uPrefMIDIOut = (UINT)ComboBox_GetItemData(hwndCtl, iIndex);
SetMIDIDeviceOut(paiTmp, paiTmp->uPrefMIDIOut, hDlg);
}
}
}
}
break;
}
}
break;
case IDC_AUDIO_PREF:
{
PropSheet_Changed(GetParent(hDlg),hDlg);
}
break;
case IDC_MUSIC_ABOUT:
{
DoRolandAbout(hDlg);
}
break;
case IDC_LAUNCH_SNDVOL:
{
LaunchPlaybackVolume(hDlg);
}
break;
case IDC_LAUNCH_RECVOL:
{
LaunchRecordVolume(hDlg);
}
break;
case IDC_LAUNCH_MUSICVOL:
{
LaunchMIDIVolume(hDlg);
}
break;
case IDC_PLAYBACK_ADVSETUP:
{
HWND hwndCBPlay = GetDlgItem(hDlg, IDC_AUDIO_CB_PLAY);
DWORD dwDeviceID;
UINT u;
TCHAR szPrefOut[MAXSTR];
u = (UINT)ComboBox_GetCurSel(hwndCBPlay);
if (u != CB_ERR)
{
ComboBox_GetLBText(hwndCBPlay, u, (LPARAM)(LPVOID)szPrefOut);
dwDeviceID = (DWORD)ComboBox_GetItemData(hwndCBPlay, u);
AdvancedAudio(hDlg, ghInstance, gszWindowsHlp, dwDeviceID, szPrefOut, FALSE);
}
}
break;
case IDC_RECORD_ADVSETUP:
{
HWND hwndCBRec = GetDlgItem(hDlg, IDC_AUDIO_CB_REC);
DWORD dwDeviceID;
UINT u;
TCHAR szPrefIn[MAXSTR];
u = (UINT)ComboBox_GetCurSel(hwndCBRec);
if (u != CB_ERR)
{
ComboBox_GetLBText(hwndCBRec, u, (LPARAM)(LPVOID)szPrefIn);
dwDeviceID = (DWORD)ComboBox_GetItemData(hwndCBRec, u);
AdvancedAudio(hDlg, ghInstance, gszWindowsHlp, dwDeviceID, szPrefIn, TRUE);
}
}
break;
}
return FALSE;
}
BOOL PASCAL CustomizeDialog(HWND hDlg, LPTSTR szNewFormat, DWORD cbSize)
{
BOOL fRet = FALSE; // assume the worse
ACMFORMATCHOOSE cwf;
LRESULT lr;
DWORD dwMaxFormatSize;
PWAVEFORMATEX spWaveFormat;
TCHAR szCustomize[64];
lr = acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT,(LPVOID)&dwMaxFormatSize);
if (lr != 0)
{
goto CustomizeOut;
}
/* This LocalAlloc is freed in WAVE.C: DestroyWave() */
spWaveFormat = (PWAVEFORMATEX)LocalAlloc(LPTR, (UINT)dwMaxFormatSize);
_fmemset(&cwf, 0, sizeof(cwf));
LoadString(ghInstance, IDS_CUSTOMIZE, szCustomize, sizeof(szCustomize)/sizeof(TCHAR));
cwf.cbStruct = sizeof(cwf);
cwf.hwndOwner = hDlg;
cwf.fdwStyle = ACMFORMATCHOOSE_STYLEF_CONTEXTHELP;
cwf.fdwEnum = ACM_FORMATENUMF_INPUT;
cwf.pszTitle = (LPTSTR)szCustomize;
cwf.pwfx = (LPWAVEFORMATEX)spWaveFormat;
cwf.cbwfx = dwMaxFormatSize;
cwf.pszName = szNewFormat;
cwf.cchName = cbSize;
lr = acmFormatChooseW(&cwf);
if (lr == MMSYSERR_NOERROR)
{
fRet = TRUE;
}
#ifdef DEBUG
else
{
TCHAR a[200];
wsprintf(a,TEXT("MSACMCPL: acmFormatChoose failed (lr=%u).\n"),lr);
OutputDebugString(a);
}
#endif
CustomizeOut:
return fRet; // return our result
} /* NewSndDialog() */
///////////////////////////////////////////////////////////////////////////////
void acmFreeCodecInfo (PCPLCODECINFO pcci)
{
if (pcci->fMadeIcon && pcci->hIcon)
{
DestroyIcon (pcci->hIcon);
pcci->hIcon = NULL;
pcci->fMadeIcon = FALSE;
}
LocalFree ((HANDLE)pcci);
}
typedef struct // FindCodecData
{
BOOL fFound;
ACMDRIVERDETAILSW add;
WORD wMid, wPid;
HACMDRIVERID hadid;
DWORD fdwSupport;
} FindCodecData;
PCPLCODECINFO acmFindCodecInfo (WORD wMidMatch, WORD wPidMatch)
{
MMRESULT mmr;
FindCodecData fcd;
PCPLCODECINFO pcci;
fcd.fFound = FALSE;
fcd.wMid = wMidMatch;
fcd.wPid = wPidMatch;
// fcd.add is filled in by acmFindCodecCallback during the following enum:
mmr = (MMRESULT)acmDriverEnum (acmFindCodecInfoCallback,
(DWORD_PTR)&fcd, // (data passed as arg2 to callback)
ACM_DRIVERENUMF_NOLOCAL |
ACM_DRIVERENUMF_DISABLED);
if (MMSYSERR_NOERROR != mmr)
{
return NULL;
}
if (!fcd.fFound)
{
return NULL;
}
// Congratulations--we found a matching ACM driver. Now
// we need to create a CPLCODECINFO structure to describe it,
// so the rest of the code in this file will work without
// mods. <<sigh>> A CPLCODECINFO structure doesn't have
// anything special--it's just a place to track info about
// an ACM driver. The most important thing is the HACMDRIVERID.
//
if ((pcci = (PCPLCODECINFO)LocalAlloc(LPTR, sizeof(CPLCODECINFO))) == NULL)
{
return NULL;
}
lstrcpy (pcci->szDesc, fcd.add.szLongName);
pcci->ads.hadid = fcd.hadid;
pcci->ads.fdwSupport = fcd.fdwSupport;
pcci->fMadeIcon = FALSE;
if ((pcci->hIcon = fcd.add.hicon) == NULL)
{
int cxIcon, cyIcon;
cxIcon = (int)GetSystemMetrics (SM_CXICON);
cyIcon = (int)GetSystemMetrics (SM_CYICON);
pcci->hIcon = LoadImage (myInstance,
MAKEINTRESOURCE( IDI_ACM ),
IMAGE_ICON, cxIcon, cyIcon, LR_DEFAULTCOLOR);
pcci->fMadeIcon = TRUE;
}
acmMetrics ((HACMOBJ)pcci->ads.hadid,
ACM_METRIC_DRIVER_PRIORITY,
&(pcci->ads.dwPriority));
return pcci;
}
BOOL CALLBACK acmFindCodecInfoCallback (HACMDRIVERID hadid,
DWORD_PTR dwUser,
DWORD fdwSupport)
{
FindCodecData *pfcd;
// dwUser is really a pointer to a FindCodecData
// structure, supplied by the guy who called acmDriverEnum.
//
if ((pfcd = (FindCodecData *)dwUser) == NULL)
{
return FALSE;
}
// No details? Try the next driver.
//
pfcd->add.cbStruct = sizeof(pfcd->add);
if (acmDriverDetailsW (hadid, &pfcd->add, 0L) != MMSYSERR_NOERROR)
{
return TRUE;
}
// Great. Now see if the driver we found matches
// pfcd->wMid/wPad; if so we're done, else keep searching.
//
if ((pfcd->wMid == pfcd->add.wMid) && (pfcd->wPid == pfcd->add.wPid) )
{
pfcd->hadid = hadid;
pfcd->fFound = TRUE;
pfcd->fdwSupport = fdwSupport;
return FALSE; // found it! leave pfcd->add intact and leave.
}
return TRUE; // not the right driver--keep looking
}
UINT acmCountCodecs (void)
{
MMRESULT mmr;
UINT nCodecs = 0;
mmr = (MMRESULT)acmDriverEnum (acmCountCodecsEnum,
(DWORD_PTR)&nCodecs,
ACM_DRIVERENUMF_NOLOCAL |
ACM_DRIVERENUMF_DISABLED);
if (MMSYSERR_NOERROR != mmr)
{
return 0;
}
return nCodecs;
}
BOOL CALLBACK acmCountCodecsEnum (HACMDRIVERID hadid,
DWORD_PTR dwUser,
DWORD fdwSupport)
{
UINT *pnCodecs;
// dwUser is really a pointer to a UINT being used to
// count the number of codecs we encounter.
//
if ((pnCodecs = (UINT *)dwUser) == NULL)
{
return FALSE;
}
++ (*pnCodecs);
return TRUE; // keep counting
}