2008-11-16 10 views
14

¿Cómo puedo cambiar el nivel de volumen maestro? Usando este códigoCambio del nivel de volumen maestro

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

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

Puedo configurar el volumen de la onda, pero si el volumen maestro es demasiado bajo, esto no tendrá ningún efecto.

Gracias por cualquier ayuda.

+0

Agregue algunos enlaces de script Xp Audio. Puede ser que puedan ayudar ... – VonC

Respuesta

30

bien, aquí va:

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); 
} 

Este código es enorme y fea. Es una traducción de algunos códigos C++, y al tener que definir todas las cosas de P/Invoke, es mucho más código. Pero lo probé y funciona. Para usarlo, simplemente necesita algo como:

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

o

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

o

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

o

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

ADVERTENCIA

Debido al uso de ints de tamaño fijo y offsets de campo, esto puede fallar fantásticamente en Windows de 64 bits. No sé, no lo he probado y no he prestado suficiente atención para saber si estos tamaños de campo se amplían a 64 bits. salvedad Codor

EDITAR

En aras de la simplicidad (relativamente hablando), he dejado a cabo cualquier tratamiento de errores.Deberías verificar los códigos de retorno de todas las funciones de mixerXXX, pero lo dejaré como un ejercicio para el lector (léase como: yo era demasiado vago para hacer esto).

+0

Gracias, funciona genial. – lacop

+2

Nota: esto no cambiará el nivel de volumen del sistema en vista/windows 7 - sin habilitar el modo de compatibilidad, de todos modos la excepción – rogerdpack

+0

[windows 7] se produce en "Marshal.FreeHGlobal (mcd.paDetails);" en "SetVolume": ** Se produjo una excepción no controlada del tipo 'System.Runtime.InteropServices.COMException' en mscorlib.dll Información adicional: El identificador no es válido. (Excepción de HRESULT: 0x80070006 (E_HANDLE)) ** – jondinham

6

Para el volumen principal (para Vista y superior), que sería:

ISimpleAudioVolume::SetMasterVolume

Como se explica here, que puede referirse a la sección:

Core Audio APIs in Windows Vista por más.

Esta llamada no es una llamada Fundación de Medios sino un WASAPI (Windows Audio Session API): ISimpleAudioVolume :: SetMasterVolume (El método SetMasterVolume ajusta el nivel de volumen principal para la sesión de audio.)

Esto puede ser sin embargo, es difícil hacer que la IU del Media Center refleje el nuevo nivel de sonido establecido por esa llamada, como esta thread illustrates.

Para Windows Xp, puedes estudiar este script y tal vez this other script.
Audio Library también podría ser de su interés.

Se da también una vieja Audio Project qué parte del volumen principal hasa:

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

Parece que esto está disponible solo en Vista, necesito poder configurar el volumen también en XP. Gracias por tu respuesta de todos modos. – lacop

+0

No estoy seguro de si ISimpleAudioVolume es suficiente para ajustar el volumen maestro; sin embargo, es posible que necesite usar IAudioEndpointVolume, etc. en su lugar ... – rogerdpack

0

Utilice esta biblioteca gratuita, es simple y hace el trabajo. InputSimulator

Simula una pulsación de tecla. Sólo tiene que añadir esta referencia y llamar a cualquier lugar que desee métodos estáticos como éstas:

InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_UP); 

    InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_DOWN); 

    InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_MUTE); 

Entonces, si usted desea conseguir el nivel vokume amo hacer:

// 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; 

esta manera usted tener en nivel el volumen actual en formato 0-1 (por ej., 52% es 0.52) Si desea tenerlo en formato 0-100, simplemente haga el nivel * 100

Cuestiones relacionadas