2008-11-16 78 views
14

如何更改主音量级别?使用此代码更改主音量级别

[DllImport ("winmm.dll")] 
public static extern int waveOutSetVolume (IntPtr hwo, uint dwVolume); 

waveOutSetVolume (IntPtr.Zero, (((uint)uint.MaxValue & 0x0000ffff) | ((uint)uint.MaxValue << 16))); 

我可以设置波形音量,但如果主音量太低,这将不会产生任何影响。

感谢您的任何帮助。

+0

添加一些XP的音频脚本的链接。可能他们可以帮助... – VonC 2008-11-16 22:54:48

回答

30

好了,这里有云:

const int MAXPNAMELEN   = 32; 
const int MIXER_SHORT_NAME_CHARS = 16; 
const int MIXER_LONG_NAME_CHARS = 64; 

[Flags] enum MIXERLINE_LINEF : uint{ 
    ACTIVE  = 0x00000001, 
    DISCONNECTED = 0x00008000, 
    SOURCE  = 0x80000000 
} 
[Flags] enum MIXER   : uint{ 
    GETLINEINFOF_DESTINATION  = 0x00000000, 
    GETLINEINFOF_SOURCE   = 0x00000001, 
    GETLINEINFOF_LINEID   = 0x00000002, 
    GETLINEINFOF_COMPONENTTYPE = 0x00000003, 
    GETLINEINFOF_TARGETTYPE  = 0x00000004, 
    GETLINEINFOF_QUERYMASK  = 0x0000000F, 

    GETLINECONTROLSF_ALL   = 0x00000000, 
    GETLINECONTROLSF_ONEBYID  = 0x00000001, 
    GETLINECONTROLSF_ONEBYTYPE = 0x00000002, 
    GETLINECONTROLSF_QUERYMASK = 0x0000000F, 

    GETCONTROLDETAILSF_VALUE  = 0x00000000, 
    GETCONTROLDETAILSF_LISTTEXT = 0x00000001, 
    GETCONTROLDETAILSF_QUERYMASK = 0x0000000F, 

    OBJECTF_MIXER    = 0x00000000, 
    OBJECTF_WAVEOUT    = 0x10000000, 
    OBJECTF_WAVEIN    = 0x20000000, 
    OBJECTF_MIDIOUT    = 0x30000000, 
    OBJECTF_MIDIIN    = 0x40000000, 
    OBJECTF_AUX     = 0x50000000, 
    OBJECTF_HANDLE    = 0x80000000, 
    OBJECTF_HMIXER    = OBJECTF_HANDLE | OBJECTF_MIXER, 
    OBJECTF_HWAVEOUT    = OBJECTF_HANDLE | OBJECTF_WAVEOUT, 
    OBJECTF_HWAVEIN    = OBJECTF_HANDLE | OBJECTF_WAVEIN, 
    OBJECTF_HMIDIOUT    = OBJECTF_HANDLE | OBJECTF_MIDIOUT, 
    OBJECTF_HMIDIIN    = OBJECTF_HANDLE | OBJECTF_MIDIIN 
} 
[Flags] enum MIXERCONTROL_CT : uint{ 
    CLASS_MASK  = 0xF0000000, 
    CLASS_CUSTOM  = 0x00000000, 
    CLASS_METER  = 0x10000000, 
    CLASS_SWITCH  = 0x20000000, 
    CLASS_NUMBER  = 0x30000000, 
    CLASS_SLIDER  = 0x40000000, 
    CLASS_FADER  = 0x50000000, 
    CLASS_TIME  = 0x60000000, 
    CLASS_LIST  = 0x70000000, 

    SUBCLASS_MASK  = 0x0F000000, 

    SC_SWITCH_BOOLEAN = 0x00000000, 
    SC_SWITCH_BUTTON = 0x01000000, 

    SC_METER_POLLED = 0x00000000, 

    SC_TIME_MICROSECS = 0x00000000, 
    SC_TIME_MILLISECS = 0x01000000, 

    SC_LIST_SINGLE = 0x00000000, 
    SC_LIST_MULTIPLE = 0x01000000, 

    UNITS_MASK  = 0x00FF0000, 
    UNITS_CUSTOM  = 0x00000000, 
    UNITS_BOOLEAN  = 0x00010000, 
    UNITS_SIGNED  = 0x00020000, 
    UNITS_UNSIGNED = 0x00030000, 
    UNITS_DECIBELS = 0x00040000, /* in 10ths */ 
    UNITS_PERCENT  = 0x00050000, /* in 10ths */ 
} 
[Flags] enum MIXERCONTROL_CONTROLTYPE : uint{ 
    CUSTOM   = MIXERCONTROL_CT.CLASS_CUSTOM | MIXERCONTROL_CT.UNITS_CUSTOM, 
    BOOLEANMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_BOOLEAN, 
    SIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_SIGNED, 
    PEAKMETER  = SIGNEDMETER + 1, 
    UNSIGNEDMETER = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_UNSIGNED, 
    BOOLEAN  = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BOOLEAN | MIXERCONTROL_CT.UNITS_BOOLEAN, 
    ONOFF   = BOOLEAN + 1, 
    MUTE   = BOOLEAN + 2, 
    MONO   = BOOLEAN + 3, 
    LOUDNESS  = BOOLEAN + 4, 
    STEREOENH  = BOOLEAN + 5, 
    BASS_BOOST  = BOOLEAN + 0x00002277, 
    BUTTON   = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BUTTON | MIXERCONTROL_CT.UNITS_BOOLEAN, 
    DECIBELS  = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_DECIBELS, 
    SIGNED   = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_SIGNED, 
    UNSIGNED  = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_UNSIGNED, 
    PERCENT  = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_PERCENT, 
    SLIDER   = MIXERCONTROL_CT.CLASS_SLIDER | MIXERCONTROL_CT.UNITS_SIGNED, 
    PAN   = SLIDER + 1, 
    QSOUNDPAN  = SLIDER + 2, 
    FADER   = MIXERCONTROL_CT.CLASS_FADER | MIXERCONTROL_CT.UNITS_UNSIGNED, 
    VOLUME   = FADER + 1, 
    BASS   = FADER + 2, 
    TREBLE   = FADER + 3, 
    EQUALIZER  = FADER + 4, 
    SINGLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_SINGLE | MIXERCONTROL_CT.UNITS_BOOLEAN, 
    MUX   = SINGLESELECT + 1, 
    MULTIPLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_MULTIPLE | MIXERCONTROL_CT.UNITS_BOOLEAN, 
    MIXER   = MULTIPLESELECT + 1, 
    MICROTIME  = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MICROSECS | MIXERCONTROL_CT.UNITS_UNSIGNED, 
    MILLITIME  = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MILLISECS | MIXERCONTROL_CT.UNITS_UNSIGNED 
} 

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] 
struct MIXERLINE{ 
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] 
    public struct TargetInfo{ 
     public uint dwType; 
     public uint dwDeviceID; 
     public ushort wMid; 
     public ushort wPid; 
     public uint vDriverVersion; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)] 
     public string szPname; 
    } 

    public uint   cbStruct; 
    public uint   dwDestination; 
    public uint   dwSource; 
    public uint   dwLineID; 
    public MIXERLINE_LINEF fdwLine; 
    public uint   dwUser; 
    public uint   dwComponentType; 
    public uint   cChannels; 
    public uint   cConnection; 
    public uint   cControls; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_SHORT_NAME_CHARS)] 
    public string   szShortName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_LONG_NAME_CHARS)] 
    public string   szName; 
    public TargetInfo  Target; 
} 
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] 
struct MIXERCONTROL{ 
    [StructLayout(LayoutKind.Explicit)] 
    public struct BoundsInfo{ 
     [FieldOffset(0)] 
     public int lMinimum; 
     [FieldOffset(4)] 
     public int lMaximum; 
     [FieldOffset(0)] 
     public uint dwMinimum; 
     [FieldOffset(4)] 
     public uint dwMaximum; 
     [FieldOffset(8), MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] 
     public uint[] dwReserved; 
    } 
    [StructLayout(LayoutKind.Explicit)] 
    public struct MetricsInfo{ 
     [FieldOffset(0)] 
     public uint cSteps; 
     [FieldOffset(0)] 
     public uint cbCustomData; 
     [FieldOffset(4), MarshalAs(UnmanagedType.ByValArray, SizeConst=5)] 
     public uint[] dwReserved; 
    } 

    public uint      cbStruct; 
    public uint      dwControlID; 
    public MIXERCONTROL_CONTROLTYPE dwControlType; 
    public uint      fdwControl; 
    public uint      cMultipleItems; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_SHORT_NAME_CHARS)] 
    public string     szShortName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_LONG_NAME_CHARS)] 
    public string     szName; 
    public BoundsInfo    Bounds; 
    public MetricsInfo    Metrics; 
} 
[StructLayout(LayoutKind.Explicit)] 
struct MIXERLINECONTROLS{ 
    [FieldOffset(0)] 
    public uint cbStruct; 
    [FieldOffset(4)] 
    public uint dwLineID; 
    [FieldOffset(8)] 
    public uint dwControlID; 
    [FieldOffset(8)] // not a typo! overlaps previous field 
    public uint dwControlType; 
    [FieldOffset(12)] 
    public uint cControls; 
    [FieldOffset(16)] 
    public uint cbmxctrl; 
    [FieldOffset(20)] 
    public IntPtr pamxctrl; 
} 
[StructLayout(LayoutKind.Explicit)] 
struct MIXERCONTROLDETAILS{ 
    [FieldOffset(0)] 
    public uint cbStruct; 
    [FieldOffset(4)] 
    public uint dwControlID; 
    [FieldOffset(8)] 
    public uint cChannels; 
    [FieldOffset(12)] 
    public IntPtr hwndOwner; 
    [FieldOffset(12)] // not a typo! 
    public uint cMultipleItems; 
    [FieldOffset(16)] 
    public uint cbDetails; 
    [FieldOffset(20)] 
    public IntPtr paDetails; 
} 
[StructLayout(LayoutKind.Sequential)] 
struct VOLUME{ 
    public int left; 
    public int right; 
} 
struct MixerInfo{ 
    public uint volumeCtl; 
    public uint muteCtl; 
    public int minVolume; 
    public int maxVolume; 
} 

[DllImport("WinMM.dll", CharSet=CharSet.Auto)] 
static extern uint mixerGetLineInfo  (IntPtr hmxobj, ref MIXERLINE pmxl, MIXER flags); 

[DllImport("WinMM.dll", CharSet=CharSet.Auto)] 
static extern uint mixerGetLineControls (IntPtr hmxobj, ref MIXERLINECONTROLS pmxlc, MIXER flags); 

[DllImport("WinMM.dll", CharSet=CharSet.Auto)] 
static extern uint mixerGetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags); 

[DllImport("WinMM.dll", CharSet=CharSet.Auto)] 
static extern uint mixerSetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags); 

static MixerInfo GetMixerControls(){ 
    MIXERLINE   mxl = new MIXERLINE(); 
    MIXERLINECONTROLS mlc = new MIXERLINECONTROLS(); 
    mxl.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINE)); 
    mlc.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINECONTROLS)); 

    mixerGetLineInfo(IntPtr.Zero, ref mxl, MIXER.OBJECTF_MIXER | MIXER.GETLINEINFOF_DESTINATION); 

    mlc.dwLineID = mxl.dwLineID; 
    mlc.cControls = mxl.cControls; 
    mlc.cbmxctrl = (uint)Marshal.SizeOf(typeof(MIXERCONTROL)); 
    mlc.pamxctrl = Marshal.AllocHGlobal((int)(mlc.cbmxctrl * mlc.cControls)); 

    mixerGetLineControls(IntPtr.Zero, ref mlc, MIXER.OBJECTF_MIXER | MIXER.GETLINECONTROLSF_ALL); 

    MixerInfo rtn = new MixerInfo(); 

    for(int i = 0; i < mlc.cControls; i++){ 
     MIXERCONTROL mxc = (MIXERCONTROL)Marshal.PtrToStructure((IntPtr)((int)mlc.pamxctrl + (int)mlc.cbmxctrl * i), typeof(MIXERCONTROL)); 
     switch(mxc.dwControlType){ 
     case MIXERCONTROL_CONTROLTYPE.VOLUME: 
      rtn.volumeCtl = mxc.dwControlID; 
      rtn.minVolume = mxc.Bounds.lMinimum; 
      rtn.maxVolume = mxc.Bounds.lMaximum; 
      break; 
     case MIXERCONTROL_CONTROLTYPE.MUTE: 
      rtn.muteCtl = mxc.dwControlID; 
      break; 
     } 
    } 

    Marshal.FreeHGlobal(mlc.pamxctrl); 

    return rtn; 
} 
static VOLUME GetVolume(MixerInfo mi){ 
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); 
    mcd.cbStruct  = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); 
    mcd.dwControlID = mi.volumeCtl; 
    mcd.cMultipleItems = 0; 
    mcd.cChannels  = 2; 
    mcd.cbDetails  = (uint)Marshal.SizeOf(typeof(int)); 
    mcd.paDetails  = Marshal.AllocHGlobal((int)mcd.cbDetails); 

    mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); 

    VOLUME rtn = (VOLUME)Marshal.PtrToStructure(mcd.paDetails, typeof(VOLUME)); 

    Marshal.FreeHGlobal(mcd.paDetails); 

    return rtn; 
} 
static bool IsMuted(MixerInfo mi){ 
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); 
    mcd.cbStruct  = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); 
    mcd.dwControlID = mi.muteCtl; 
    mcd.cMultipleItems = 0; 
    mcd.cChannels  = 1; 
    mcd.cbDetails  = 4; 
    mcd.paDetails  = Marshal.AllocHGlobal((int)mcd.cbDetails); 

    mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); 

    int rtn = Marshal.ReadInt32(mcd.paDetails); 

    Marshal.FreeHGlobal(mcd.paDetails); 

    return rtn != 0; 
} 
static void AdjustVolume(MixerInfo mi, int delta){ 
    VOLUME volume = GetVolume(mi); 

    if(delta > 0){ 
     volume.left = Math.Min(mi.maxVolume, volume.left + delta); 
     volume.right = Math.Min(mi.maxVolume, volume.right + delta); 
    }else{ 
     volume.left = Math.Max(mi.minVolume, volume.left + delta); 
     volume.right = Math.Max(mi.minVolume, volume.right + delta); 
    } 

    SetVolume(mi, volume); 
} 
static void SetVolume(MixerInfo mi, VOLUME volume){ 
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); 
    mcd.cbStruct  = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); 
    mcd.dwControlID = mi.volumeCtl; 
    mcd.cMultipleItems = 0; 
    mcd.cChannels  = 2; 
    mcd.cbDetails  = (uint)Marshal.SizeOf(typeof(int)); 
    mcd.paDetails  = Marshal.AllocHGlobal((int)mcd.cbDetails); 

    Marshal.StructureToPtr(volume, mcd.paDetails, false); 

    mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); 

    Marshal.FreeHGlobal(mcd.paDetails); 
} 
static void SetMute(MixerInfo mi, bool mute){ 
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS(); 
    mcd.cbStruct  = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS)); 
    mcd.dwControlID = mi.muteCtl; 
    mcd.cMultipleItems = 0; 
    mcd.cChannels  = 1; 
    mcd.cbDetails  = 4; 
    mcd.paDetails  = Marshal.AllocHGlobal((int)mcd.cbDetails); 

    Marshal.WriteInt32(mcd.paDetails, mute ? 1 : 0); 

    mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER); 

    Marshal.FreeHGlobal(mcd.paDetails); 
} 

此代码是巨大的和丑陋的。它是一些C++代码的翻译,并且必须定义所有的P/Invoke内容,这是更多的代码。但是我已经测试过了,它很有用。要使用它,你只需要像:

MixerInfo mi = GetMixerControls(); 
AdjustVolume(mi, 100); // add 100 to the current volume 

MixerInfo mi = GetMixerControls(); 
AdjustVolume(mi, (mi.maxVolume - mi.minVolume)/10); // increase the volume by 10% of total range 

MixerInfo mi = GetMixerControls(); 
SetVolume(mi, mi.maxVolume); // let's get this party crunk'd! 

MixerInfo mi = GetMixerControls(); 
SetMute(mi, true); // shhhh!!!!!! 

警告

由于使用了固定大小的整数和字段偏移量,在64位Windows上这可能会失败。我不知道,我没有测试过,也没有足够的注意,知道这些字段大小是否扩展到64位。 警告codor

编辑

为了简单(相对而言)的缘故,我已经离开了任何错误处理。你应该真的检查所有mixerXXX函数的返回代码,但是我会把它作为读者的练习(读作:我懒得这样做)。

6

对于主卷(对于Vista和以上),这将是:

ISimpleAudioVolume::SetMasterVolume

如所解释的here,可参考以下部分:

Core Audio APIs in Windows Vista更多。

该呼叫不是媒体基金会的电话,但WASAPI(Windows音频会话API)调用: ISimpleAudioVolume :: SetMasterVolume(该SetMasterVolume方法设置音频会议的主音量电平。)

这可能是但难以使媒体中心的用户界面反映出该电话所设置的新声级,如此thread illustrates它。

对于windows xp,你可以学习script或者this other script
Audio Library也可能是感兴趣的。

还有这个老Audio Project该公会主音量部分:

BOOL CVolumeDlg::amdInitialize() 
{ 
    ASSERT(m_hMixer == NULL); 

    // get the number of mixer devices present in the system 
    m_nNumMixers = ::mixerGetNumDevs(); 

    m_hMixer = NULL; 
    ::ZeroMemory(&m_mxcaps, sizeof(MIXERCAPS)); 

    m_strDstLineName.Empty(); 
    m_strVolumeControlName.Empty(); 
    m_dwMinimum = 0; 
    m_dwMaximum = 0; 
    m_dwVolumeControlID = 0; 

    // open the first mixer 
    // A "mapper" for audio mixer devices does not currently exist. 
    if (m_nNumMixers != 0) 
    { 
     if (::mixerOpen(&m_hMixer, 
         0, 
         reinterpret_cast<DWORD>(this->GetSafeHwnd()), 
         NULL, 
         MIXER_OBJECTF_MIXER | CALLBACK_WINDOW) 
      != MMSYSERR_NOERROR) 
     { 
      return FALSE; 
     } 

     if (::mixerGetDevCaps(reinterpret_cast<UINT>(m_hMixer), 
           &m_mxcaps, sizeof(MIXERCAPS)) 
      != MMSYSERR_NOERROR) 
     { 
      return FALSE; 
     } 
    } 

    return TRUE; 
} 

BOOL CVolumeDlg::amdUninitialize() 
{ 
    BOOL bSucc = TRUE; 

    if (m_hMixer != NULL) 
    { 
     bSucc = (::mixerClose(m_hMixer) == MMSYSERR_NOERROR); 
     m_hMixer = NULL; 
    } 

    return bSucc; 
} 

BOOL CVolumeDlg::amdGetMasterVolumeControl() 
{ 
    if (m_hMixer == NULL) 
    { 
     return FALSE; 
    } 

    // get dwLineID 
    MIXERLINE mxl; 
    mxl.cbStruct = sizeof(MIXERLINE); 
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    if (::mixerGetLineInfo(reinterpret_cast<HMIXEROBJ>(m_hMixer), 
          &mxl, 
          MIXER_OBJECTF_HMIXER | 
          MIXER_GETLINEINFOF_COMPONENTTYPE) 
     != MMSYSERR_NOERROR) 
    { 
     return FALSE; 
    } 

    // get dwControlID 
    MIXERCONTROL mxc; 
    MIXERLINECONTROLS mxlc; 
    mxlc.cbStruct = sizeof(MIXERLINECONTROLS); 
    mxlc.dwLineID = mxl.dwLineID; 
    mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; 
    mxlc.cControls = 1; 
    mxlc.cbmxctrl = sizeof(MIXERCONTROL); 
    mxlc.pamxctrl = &mxc; 
    if (::mixerGetLineControls(reinterpret_cast<HMIXEROBJ>(m_hMixer), 
           &mxlc, 
           MIXER_OBJECTF_HMIXER | 
           MIXER_GETLINECONTROLSF_ONEBYTYPE) 
     != MMSYSERR_NOERROR) 
    { 
     return FALSE; 
    } 

    // store dwControlID 
    m_strDstLineName = mxl.szName; 
    m_strVolumeControlName = mxc.szName; 
    m_dwMinimum = mxc.Bounds.dwMinimum; 
    m_dwMaximum = mxc.Bounds.dwMaximum; 
    m_dwVolumeControlID = mxc.dwControlID; 

    return TRUE; 
} 

BOOL CVolumeDlg::amdGetMasterVolumeValue(DWORD &dwVal) const 
{ 
    if (m_hMixer == NULL) 
    { 
     return FALSE; 
    } 

    MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; 
    MIXERCONTROLDETAILS mxcd; 
    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); 
    mxcd.dwControlID = m_dwVolumeControlID; 
    mxcd.cChannels = 1; 
    mxcd.cMultipleItems = 0; 
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); 
    mxcd.paDetails = &mxcdVolume; 
    if (::mixerGetControlDetails(reinterpret_cast<HMIXEROBJ>(m_hMixer), 
           &mxcd, 
           MIXER_OBJECTF_HMIXER | 
           MIXER_GETCONTROLDETAILSF_VALUE) 
     != MMSYSERR_NOERROR) 
    { 
     return FALSE; 
    } 

    dwVal = mxcdVolume.dwValue; 

    return TRUE; 
} 

BOOL CVolumeDlg::amdSetMasterVolumeValue(DWORD dwVal) const 
{ 
    if (m_hMixer == NULL) 
    { 
     return FALSE; 
    } 

    MIXERCONTROLDETAILS_UNSIGNED mxcdVolume = { dwVal }; 
    MIXERCONTROLDETAILS mxcd; 
    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); 
    mxcd.dwControlID = m_dwVolumeControlID; 
    mxcd.cChannels = 1; 
    mxcd.cMultipleItems = 0; 
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); 
    mxcd.paDetails = &mxcdVolume; 
    if (::mixerSetControlDetails(reinterpret_cast<HMIXEROBJ>(m_hMixer), 
           &mxcd, 
           MIXER_OBJECTF_HMIXER | 
           MIXER_SETCONTROLDETAILSF_VALUE) 
     != MMSYSERR_NOERROR) 
    { 
     return FALSE; 
    } 

    return TRUE; 
} 
+0

看起来这只是在Vista中可用,我需要能够在XP中设置音量。无论如何,谢谢你的回答。 – lacop 2008-11-16 20:36:07

+0

我不确定ISimpleAudioVolume是否足以调整主音量,但是您可能需要使用IAudioEndpointVolume等。 – rogerdpack 2013-09-04 19:49:09

0

使用此免费的图书馆,它的简单和做的工作。 InputSimulator

它模拟一个按键。 你只需要添加此引用,并调用任何你想要的静态方法像这样:

InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_UP); 

    InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_DOWN); 

    InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_MUTE); 

然后,如果你想获得主vokume级别做:

// volume update 
    MMDevice defaultDevice = new MMDeviceEnumerator() 
     .GetDefaultAudioEndpoint(DataFlow.Render‌​, Role.Multimedia); 
    // veloce attesa per l'aggiornamento del volume 
    Thread.Sleep(100); 
    float level = defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar; 

这样做,你会有级别的当前量0-1格式(例如,52%是0.52)如果你想拥有它的0-100格式简单地做等级* 100