使用C#设置Windows卷

Ald*_*991 5 c# windows volume

我一直在网上搜索从C#控制我的电脑音频的方法.我发现这个代码工作正常.

    public static float GetMasterVolume()
    {
        // get the speakers (1st render + multimedia) device
        IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator());
        IMMDevice speakers;
        const int eRender = 0;
        const int eMultimedia = 1;
        deviceEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, out speakers);

        object o;
        speakers.Activate(typeof(IAudioEndpointVolume).GUID, 0, IntPtr.Zero, out o);
        IAudioEndpointVolume aepv = (IAudioEndpointVolume)o;
        float volume = aepv.GetMasterVolumeLevelScalar();
        Marshal.ReleaseComObject(aepv);
        Marshal.ReleaseComObject(speakers);
        Marshal.ReleaseComObject(deviceEnumerator);
        return volume;
    }

    [ComImport]
    [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
    private class MMDeviceEnumerator
    {
    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IAudioEndpointVolume
    {
        void _VtblGap1_6();
        float GetMasterVolumeLevelScalar();
    }

    [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IMMDeviceEnumerator
    {
        void _VtblGap1_1();

        [PreserveSig]
        int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice);
    }

    [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IMMDevice
    {
        [PreserveSig]
        int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
    }
Run Code Online (Sandbox Code Playgroud)

那是getVolume函数.我认为必须采用类似的方式设置音量.我遇到过这种方法:

SetMasterVolumeLevelScalar()

HRESULT SetMasterVolumeLevelScalar(
  [in] float   fLevel,
  [in] LPCGUID pguidEventContext
);
Run Code Online (Sandbox Code Playgroud)

但我无法理解第二个参数.任何帮助,将不胜感激.

Tom*_*zzo 1

定义您的界面...

[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioEndpointVolume
{
    // ...
    Int32 GetMasterVolumeLevelScalar(ref Single pfLevel);
    Int32 SetMasterVolumeLevelScalar(Single fLevel, Guid pguidEventContext);
    // ...
}
Run Code Online (Sandbox Code Playgroud)

然后,在你的班级中,例如:

public class EndpointVolume
{
    private readonly Guid m_GuidEventContext;
    private IAudioEndpointVolume m_AudioEndpoint;

    public EndpointVolume()
    {
        m_GuidEventContext = Guid.NewGuid();
        m_AudioEndpoint = ...
    }

    public Single MasterVolume
    {
        get
        {
            Single level = 0.0f;
            Int32 res = m_AudioEndpoint.GetMasterVolumeLevelScalar(ref level);

            if (retVal != 0)
                throw new Exception("AudioEndpointVolume.GetMasterVolumeLevelScalar()");

            return level;
        }

        set
        {
            Single level = value;

            if (level < 0.0f)
                level = 0.0f;
            else if (level > 1.0f)
                level = 0.0f;

            Int32 res = m_AudioEndpoint.SetMasterVolumeLevelScalar(level, m_GuidEventContext);

            if (res!= 0)
                throw new Exception("AudioEndpointVolume.SetMasterVolumeLevelScalar()");
        }
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

pguidEventContext参数用于定义当前事件上下文,以便对主卷所做的更改反映到所有其他客户端。来自官方文档

IAudioEndpointVolumeCallback::OnNotify 方法的上下文值。此参数指向事件上下文 GUID。如果 SetMasterVolumeLevelScalar 调用更改端点的音量级别,则所有已向该端点注册 IAudioEndpointVolumeCallback 接口的客户端都将收到通知。在 OnNotify 方法的实现中,客户端可以检查事件上下文 GUID 以发现它或另一个客户端是否是卷更改事件的源。如果调用者为此参数提供 NULL 指针,则通知例程将接收上下文 GUID 值 GUID_NULL。