在windows下控制系统音量,需要通过使用win32的WDM audio components(winmm.dll)来实现,为了方便起见,将其封装到了一个AudioMixerHelper类中,可以直接通过GetVolume()和SetVolume方法来改变音量。
using System;
using System.Runtime.InteropServices;
namespace Microsoft
{
public class AudioMixerHelper
{
public const int MMSYSERR_NOERROR = 0;
public const int MAXPNAMELEN = 32;
public const int MIXER_LONG_NAME_CHARS = 64;
public const int MIXER_SHORT_NAME_CHARS = 16;
public const int MIXER_GETLINEINFOF_COMPONENTTYPE = 0x3;
public const int MIXER_GETCONTROLDETAILSF_VALUE = 0x0;
public const int MIXER_GETLINECONTROLSF_ONEBYTYPE = 0x2;
public const int MIXER_SETCONTROLDETAILSF_VALUE = 0x0;
public const int MIXERLINE_COMPONENTTYPE_DST_FIRST = 0x0;
public const int MIXERLINE_COMPONENTTYPE_SRC_FIRST = 0x1000;
public const int MIXERLINE_COMPONENTTYPE_DST_SPEAKERS =
(MIXERLINE_COMPONENTTYPE_DST_FIRST + 4);
public const int MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE =
(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3);
public const int MIXERLINE_COMPONENTTYPE_SRC_LINE =
(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2);
public const int MIXERCONTROL_CT_CLASS_FADER = 0x50000000;
public const int MIXERCONTROL_CT_UNITS_UNSIGNED = 0x30000;
public const int MIXERCONTROL_CONTROLTYPE_FADER =
(MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED);
public const int MIXERCONTROL_CONTROLTYPE_VOLUME =
(MIXERCONTROL_CONTROLTYPE_FADER + 1);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerClose (int hmx);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetControlDetailsA (int hmxobj,ref
MIXERCONTROLDETAILS pmxcd , int fdwDetails);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetDevCapsA(int uMxId, MIXERCAPS
pmxcaps, int cbmxcaps);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetID (int hmxobj, int pumxID, int
fdwId);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetLineControlsA (int hmxobj,ref
MIXERLINECONTROLS pmxlc, int fdwControls);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetLineInfoA (int hmxobj,ref
MIXERLINE pmxl , int fdwInfo);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetNumDevs();
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerMessage(int hmx , int uMsg , int
dwParam1 , int dwParam2);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerOpen (out int phmx , int uMxId ,
int dwCallback , int dwInstance , int fdwOpen);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerSetControlDetails(int hmxobj ,ref
MIXERCONTROLDETAILS pmxcd , int fdwDetails);
public struct MIXERCAPS
{
public int wMid;
public int wPid;
public int vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)]
public string szPname;
public int fdwSupport;
public int cDestinations;
}
public struct MIXERCONTROL
{
public int cbStruct;
public int dwControlID;
public int dwControlType;
public int fdwControl;
public int cMultipleItems;
[MarshalAs( UnmanagedType.ByValTStr,
SizeConst=MIXER_SHORT_NAME_CHARS)]
public string szShortName ;
[MarshalAs( UnmanagedType.ByValTStr,
SizeConst=MIXER_LONG_NAME_CHARS)]
public string szName;
public int lMinimum;
public int lMaximum;
[MarshalAs(UnmanagedType.U4, SizeConst=10)]
public int reserved;
}
public struct MIXERCONTROLDETAILS
{
public int cbStruct;
public int dwControlID;
public int cChannels;
public int item;
public int cbDetails;
public IntPtr paDetails;
}
public struct MIXERCONTROLDETAILS_UNSIGNED
{
public int dwValue;
}
public struct MIXERLINE
{
public int cbStruct;
public int dwDestination;
public int dwSource;
public int dwLineID;
public int fdwLine;
public int dwUser;
public int dwComponentType;
public int cChannels;
public int cConnections;
public int cControls;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=MIXER_SHORT_NAME_CHARS)]
public string szShortName;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=MIXER_LONG_NAME_CHARS )]
public string szName;
public int dwType;
public int dwDeviceID;
public int wMid;
public int wPid;
public int vDriverVersion ;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)]
public string szPname ;
}
public struct MIXERLINECONTROLS
{
public int cbStruct;
public int dwLineID;
public int dwControl;
public int cControls;
public int cbmxctrl;
public IntPtr pamxctrl;
}
private static bool GetVolumeControl(int hmixer, int componentType,
int ctrlType, out MIXERCONTROL mxc, out int vCurrentVol)
{
// This function attempts to obtain a mixer control.
// Returns True if successful.
MIXERLINECONTROLS mxlc = new MIXERLINECONTROLS();
MIXERLINE mxl = new MIXERLINE();
MIXERCONTROLDETAILS pmxcd = new MIXERCONTROLDETAILS();
MIXERCONTROLDETAILS_UNSIGNED du = new
MIXERCONTROLDETAILS_UNSIGNED();
mxc = new MIXERCONTROL();
int rc;
bool retValue;
vCurrentVol = -1;
mxl.cbStruct = Marshal.SizeOf(mxl);
mxl.dwComponentType = componentType;
rc = mixerGetLineInfoA(hmixer,ref mxl,
MIXER_GETLINEINFOF_COMPONENTTYPE );
if(MMSYSERR_NOERROR == rc)
{
int sizeofMIXERCONTROL = 152;
int ctrl = Marshal.SizeOf(typeof(MIXERCONTROL));
mxlc.pamxctrl = Marshal.AllocCoTaskMem(sizeofMIXERCONTROL);
mxlc.cbStruct = Marshal.SizeOf(mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControl = ctrlType;
mxlc.cControls = 1;
mxlc.cbmxctrl = sizeofMIXERCONTROL;
// Allocate a buffer for the control
mxc.cbStruct = sizeofMIXERCONTROL;
// Get the control
rc = mixerGetLineControlsA(hmixer,ref mxlc,
MIXER_GETLINECONTROLSF_ONEBYTYPE);
if(MMSYSERR_NOERROR == rc)
{
retValue = true;
// Copy the control into the destination structure
mxc = (MIXERCONTROL)Marshal.PtrToStructure(
mxlc.pamxctrl,typeof(MIXERCONTROL));
}
else
{
retValue = false;
}
int sizeofMIXERCONTROLDETAILS =
Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
int sizeofMIXERCONTROLDETAILS_UNSIGNED =
Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_UNSIGNED));
pmxcd.cbStruct = sizeofMIXERCONTROLDETAILS;
pmxcd.dwControlID = mxc.dwControlID;
pmxcd.paDetails =
Marshal.AllocCoTaskMem(sizeofMIXERCONTROLDETAILS_UNSIGNED) ;
pmxcd.cChannels = 1;
pmxcd.item = 0;
pmxcd.cbDetails = sizeofMIXERCONTROLDETAILS_UNSIGNED;
rc = mixerGetControlDetailsA(hmixer,ref pmxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
du = (MIXERCONTROLDETAILS_UNSIGNED)Marshal.PtrToStructure(
pmxcd.paDetails, typeof(MIXERCONTROLDETAILS_UNSIGNED));
vCurrentVol = du.dwValue;
return retValue;
}
retValue = false;
return retValue;
}
private static bool SetVolumeControl(int hmixer, MIXERCONTROL mxc,
int volume)
{
// This function sets the value for a volume control.
// Returns True if successful
bool retValue;
int rc;
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
MIXERCONTROLDETAILS_UNSIGNED vol = new
MIXERCONTROLDETAILS_UNSIGNED();
mxcd.item = 0;
mxcd.dwControlID = mxc.dwControlID;
mxcd.cbStruct = Marshal.SizeOf(mxcd);
mxcd.cbDetails = Marshal.SizeOf(vol);
// Allocate a buffer for the control value buffer
mxcd.cChannels = 1;
vol.dwValue = volume;
// Copy the data into the control value buffer
mxcd.paDetails = Marshal.AllocCoTaskMem(Marshal.SizeOf(
typeof(MIXERCONTROLDETAILS_UNSIGNED)));
Marshal.StructureToPtr(vol, mxcd.paDetails,false);
// Set the control value
rc = mixerSetControlDetails(hmixer,ref mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
if(MMSYSERR_NOERROR == rc)
{
retValue = true;
}
else
{
retValue = false;
} return retValue;
}
public static int GetVolume()
{
int mixer;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
mixerOpen(out mixer,0 ,0 ,0, 0);
int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out
currentVol);
mixerClose(mixer);
return currentVol;
}
public static void SetVolume(int vVolume)
{
int mixer;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
mixerOpen(out mixer,0 ,0 ,0, 0);
int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out
currentVol);
if(vVolume > volCtrl.lMaximum) vVolume = volCtrl.lMaximum;
if(vVolume < volCtrl.lMinimum) vVolume = volCtrl.lMinimum;
SetVolumeControl(mixer, volCtrl, vVolume);
GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out
currentVol);
if(vVolume != currentVol)
{
throw new Exception("Cannot Set Volume");
}
mixerClose(mixer);
}
}
}
using System.Runtime.InteropServices;
namespace Microsoft
{
public class AudioMixerHelper
{
public const int MMSYSERR_NOERROR = 0;
public const int MAXPNAMELEN = 32;
public const int MIXER_LONG_NAME_CHARS = 64;
public const int MIXER_SHORT_NAME_CHARS = 16;
public const int MIXER_GETLINEINFOF_COMPONENTTYPE = 0x3;
public const int MIXER_GETCONTROLDETAILSF_VALUE = 0x0;
public const int MIXER_GETLINECONTROLSF_ONEBYTYPE = 0x2;
public const int MIXER_SETCONTROLDETAILSF_VALUE = 0x0;
public const int MIXERLINE_COMPONENTTYPE_DST_FIRST = 0x0;
public const int MIXERLINE_COMPONENTTYPE_SRC_FIRST = 0x1000;
public const int MIXERLINE_COMPONENTTYPE_DST_SPEAKERS =
(MIXERLINE_COMPONENTTYPE_DST_FIRST + 4);
public const int MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE =
(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3);
public const int MIXERLINE_COMPONENTTYPE_SRC_LINE =
(MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2);
public const int MIXERCONTROL_CT_CLASS_FADER = 0x50000000;
public const int MIXERCONTROL_CT_UNITS_UNSIGNED = 0x30000;
public const int MIXERCONTROL_CONTROLTYPE_FADER =
(MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED);
public const int MIXERCONTROL_CONTROLTYPE_VOLUME =
(MIXERCONTROL_CONTROLTYPE_FADER + 1);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerClose (int hmx);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetControlDetailsA (int hmxobj,ref
MIXERCONTROLDETAILS pmxcd , int fdwDetails);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetDevCapsA(int uMxId, MIXERCAPS
pmxcaps, int cbmxcaps);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetID (int hmxobj, int pumxID, int
fdwId);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetLineControlsA (int hmxobj,ref
MIXERLINECONTROLS pmxlc, int fdwControls);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetLineInfoA (int hmxobj,ref
MIXERLINE pmxl , int fdwInfo);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerGetNumDevs();
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerMessage(int hmx , int uMsg , int
dwParam1 , int dwParam2);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerOpen (out int phmx , int uMxId ,
int dwCallback , int dwInstance , int fdwOpen);
[DllImport("winmm.dll", CharSet=CharSet.Ansi)]
private static extern int mixerSetControlDetails(int hmxobj ,ref
MIXERCONTROLDETAILS pmxcd , int fdwDetails);
public struct MIXERCAPS
{
public int wMid;
public int wPid;
public int vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)]
public string szPname;
public int fdwSupport;
public int cDestinations;
}
public struct MIXERCONTROL
{
public int cbStruct;
public int dwControlID;
public int dwControlType;
public int fdwControl;
public int cMultipleItems;
[MarshalAs( UnmanagedType.ByValTStr,
SizeConst=MIXER_SHORT_NAME_CHARS)]
public string szShortName ;
[MarshalAs( UnmanagedType.ByValTStr,
SizeConst=MIXER_LONG_NAME_CHARS)]
public string szName;
public int lMinimum;
public int lMaximum;
[MarshalAs(UnmanagedType.U4, SizeConst=10)]
public int reserved;
}
public struct MIXERCONTROLDETAILS
{
public int cbStruct;
public int dwControlID;
public int cChannels;
public int item;
public int cbDetails;
public IntPtr paDetails;
}
public struct MIXERCONTROLDETAILS_UNSIGNED
{
public int dwValue;
}
public struct MIXERLINE
{
public int cbStruct;
public int dwDestination;
public int dwSource;
public int dwLineID;
public int fdwLine;
public int dwUser;
public int dwComponentType;
public int cChannels;
public int cConnections;
public int cControls;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=MIXER_SHORT_NAME_CHARS)]
public string szShortName;
[MarshalAs(UnmanagedType.ByValTStr,
SizeConst=MIXER_LONG_NAME_CHARS )]
public string szName;
public int dwType;
public int dwDeviceID;
public int wMid;
public int wPid;
public int vDriverVersion ;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)]
public string szPname ;
}
public struct MIXERLINECONTROLS
{
public int cbStruct;
public int dwLineID;
public int dwControl;
public int cControls;
public int cbmxctrl;
public IntPtr pamxctrl;
}
private static bool GetVolumeControl(int hmixer, int componentType,
int ctrlType, out MIXERCONTROL mxc, out int vCurrentVol)
{
// This function attempts to obtain a mixer control.
// Returns True if successful.
MIXERLINECONTROLS mxlc = new MIXERLINECONTROLS();
MIXERLINE mxl = new MIXERLINE();
MIXERCONTROLDETAILS pmxcd = new MIXERCONTROLDETAILS();
MIXERCONTROLDETAILS_UNSIGNED du = new
MIXERCONTROLDETAILS_UNSIGNED();
mxc = new MIXERCONTROL();
int rc;
bool retValue;
vCurrentVol = -1;
mxl.cbStruct = Marshal.SizeOf(mxl);
mxl.dwComponentType = componentType;
rc = mixerGetLineInfoA(hmixer,ref mxl,
MIXER_GETLINEINFOF_COMPONENTTYPE );
if(MMSYSERR_NOERROR == rc)
{
int sizeofMIXERCONTROL = 152;
int ctrl = Marshal.SizeOf(typeof(MIXERCONTROL));
mxlc.pamxctrl = Marshal.AllocCoTaskMem(sizeofMIXERCONTROL);
mxlc.cbStruct = Marshal.SizeOf(mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControl = ctrlType;
mxlc.cControls = 1;
mxlc.cbmxctrl = sizeofMIXERCONTROL;
// Allocate a buffer for the control
mxc.cbStruct = sizeofMIXERCONTROL;
// Get the control
rc = mixerGetLineControlsA(hmixer,ref mxlc,
MIXER_GETLINECONTROLSF_ONEBYTYPE);
if(MMSYSERR_NOERROR == rc)
{
retValue = true;
// Copy the control into the destination structure
mxc = (MIXERCONTROL)Marshal.PtrToStructure(
mxlc.pamxctrl,typeof(MIXERCONTROL));
}
else
{
retValue = false;
}
int sizeofMIXERCONTROLDETAILS =
Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
int sizeofMIXERCONTROLDETAILS_UNSIGNED =
Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_UNSIGNED));
pmxcd.cbStruct = sizeofMIXERCONTROLDETAILS;
pmxcd.dwControlID = mxc.dwControlID;
pmxcd.paDetails =
Marshal.AllocCoTaskMem(sizeofMIXERCONTROLDETAILS_UNSIGNED) ;
pmxcd.cChannels = 1;
pmxcd.item = 0;
pmxcd.cbDetails = sizeofMIXERCONTROLDETAILS_UNSIGNED;
rc = mixerGetControlDetailsA(hmixer,ref pmxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
du = (MIXERCONTROLDETAILS_UNSIGNED)Marshal.PtrToStructure(
pmxcd.paDetails, typeof(MIXERCONTROLDETAILS_UNSIGNED));
vCurrentVol = du.dwValue;
return retValue;
}
retValue = false;
return retValue;
}
private static bool SetVolumeControl(int hmixer, MIXERCONTROL mxc,
int volume)
{
// This function sets the value for a volume control.
// Returns True if successful
bool retValue;
int rc;
MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
MIXERCONTROLDETAILS_UNSIGNED vol = new
MIXERCONTROLDETAILS_UNSIGNED();
mxcd.item = 0;
mxcd.dwControlID = mxc.dwControlID;
mxcd.cbStruct = Marshal.SizeOf(mxcd);
mxcd.cbDetails = Marshal.SizeOf(vol);
// Allocate a buffer for the control value buffer
mxcd.cChannels = 1;
vol.dwValue = volume;
// Copy the data into the control value buffer
mxcd.paDetails = Marshal.AllocCoTaskMem(Marshal.SizeOf(
typeof(MIXERCONTROLDETAILS_UNSIGNED)));
Marshal.StructureToPtr(vol, mxcd.paDetails,false);
// Set the control value
rc = mixerSetControlDetails(hmixer,ref mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
if(MMSYSERR_NOERROR == rc)
{
retValue = true;
}
else
{
retValue = false;
} return retValue;
}
public static int GetVolume()
{
int mixer;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
mixerOpen(out mixer,0 ,0 ,0, 0);
int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out
currentVol);
mixerClose(mixer);
return currentVol;
}
public static void SetVolume(int vVolume)
{
int mixer;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
mixerOpen(out mixer,0 ,0 ,0, 0);
int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out
currentVol);
if(vVolume > volCtrl.lMaximum) vVolume = volCtrl.lMaximum;
if(vVolume < volCtrl.lMinimum) vVolume = volCtrl.lMinimum;
SetVolumeControl(mixer, volCtrl, vVolume);
GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out
currentVol);
if(vVolume != currentVol)
{
throw new Exception("Cannot Set Volume");
}
mixerClose(mixer);
}
}
}
本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利