2008-11-16 14 views
14

Jak zmienić główny poziom głośności? Korzystanie z tego kodu:Zmiana poziomu głośności głównej

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

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

Mogę ustawić głośność fali, ale jeśli głośność główna jest zbyt niska, nie będzie to miało żadnego efektu.

Dzięki za pomoc.

+0

Dodaj linki do skryptów Xp Audio. Być może mogą pomóc ... – VonC

Odpowiedz

30

Dobra, tu idzie:

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

Kod ten jest ogromny i brzydkie. Jest to tłumaczenie części kodu C++ i przy konieczności definiowania wszystkich rzeczy P/Invoke, jest o wiele więcej kodu. Ale testowałem to i działa. Aby z niego skorzystać, wystarczy coś takiego:

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

lub

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

lub

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

lub

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

UWAGA

Ze względu na użycie stałych rozmiarów szablonów i przesunięć pól, może to nie działać fantastycznie w 64-bitowym systemie Windows. Nie wiem, nie przetestowałem tego i nie poświęcałem wystarczająco dużo uwagi, aby wiedzieć, czy te pola powiększają się do 64 bitów. zastrzeżenie codor

EDIT

Dla uproszczenia (relatywnie), mam pominąć żadnej obsługi błędów.Powinieneś naprawdę sprawdzić kody powrotu wszystkich funkcji mixerXXX, ale zostawię to jako ćwiczenie dla czytelnika (czytaj: byłem zbyt leniwy, aby to zrobić).

+0

Dziękuję, działa świetnie. – lacop

+2

UWAGA: nie spowoduje to zmiany głośności systemu na Vista/Windows 7 - bez włączania trybu zgodności, tak czy inaczej – rogerdpack

+0

Wystąpi wyjątek [Windows 7] w "Marshal.FreeHGlobal (mcd.paDetails);" w "SetVolume": ** Wystąpił nieobsługiwany wyjątek typu "System.Runtime.InteropServices.COMException" w pliku mscorlib.dll Dodatkowe informacje: Uchwyt jest nieprawidłowy. (Wyjątek od HRESULT: 0x80070006 (E_HANDLE)) ** – jondinham

6

Dla master volume (dla Vista i powyżej), które byłyby:

ISimpleAudioVolume::SetMasterVolume

Jak wyjaśniono here, można znaleźć w sekcji:

Core Audio APIs in Windows Vista więcej.

Ta rozmowa nie jest wezwaniem Fundacja Mediów ale WASAPI (Windows Audio Session API) wezwanie: ISimpleAudioVolume :: SetMasterVolume (Metoda SetMasterVolume ustawia poziom głośności Master dla sesji audio.)

To może być trudne jednak, aby interfejs użytkownika Media Center odzwierciedlał nowy poziom głośności ustawiony przez to połączenie, ponieważ jest to thread illustrates.

W przypadku systemu Windows XP można studiować to script i może this other script.
Audio Library może również zainteresować.

Jest też ten stary Audio Project których część Hasa głośności:

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

Wygląda na to, że jest to dostępne tylko w widoku perspektywicznym, muszę mieć możliwość ustawienia głośności również w XP. Dziękuję za odpowiedź. – lacop

+0

Nie jestem pewien, czy ISimpleAudioVolume wystarcza do dostosowania głównego woluminu, ale może być konieczne użycie IAudioEndpointVolume itp. Zamiast ... – rogerdpack

0

Użyj tej bezpłatnej biblioteki, jest to proste i wykonaj zadanie. InputSimulator

Symuluje naciśnięcie klawisza. Trzeba tylko dodać to odwołanie i zadzwonić gdziekolwiek chcesz metody statyczne, takie jak:

InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_UP); 

    InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_DOWN); 

    InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_MUTE); 

Następnie, jeśli chcesz uzyskać poziom mistrz vokume zrobić:

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

Spowoduje to będziesz mieć poziom aktualnej objętości w formacie 0-1 (np. 52% to 0,52) Jeśli chcesz mieć go w formacie 0-100, po prostu wykonaj poziom * 100

Powiązane problemy