Advertisement
Guest User

azoapes

a guest
Jul 2nd, 2009
477
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.77 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5.  
  6. namespace VistaVolumeControl
  7. {
  8.  
  9.     /// <summary>
  10.  
  11.     /// This class allows to read and change the master volume in Vista (End Point Volume)
  12.  
  13.     /// </summary>
  14.  
  15.     public class EndpointVolume
  16.     {
  17.  
  18.         #region Interface to COM objects
  19.  
  20.         const int DEVICE_STATE_ACTIVE = 0x00000001;
  21.  
  22.         const int DEVICE_STATE_DISABLE = 0x00000002;
  23.  
  24.         const int DEVICE_STATE_NOTPRESENT = 0x00000004;
  25.  
  26.         const int DEVICE_STATE_UNPLUGGED = 0x00000008;
  27.  
  28.         const int DEVICE_STATEMASK_ALL = 0x0000000f;
  29.  
  30.         [DllImport("ole32.Dll")]
  31.  
  32.         static public extern uint CoCreateInstance(ref Guid clsid,
  33.  
  34.         [MarshalAs(UnmanagedType.IUnknown)] object inner,
  35.  
  36.         uint context,
  37.  
  38.         ref Guid uuid,
  39.  
  40.         [MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject);
  41.  
  42.  
  43.  
  44.         // C Header file : Include Mmdeviceapi.h (Windows Vista SDK)
  45.  
  46.         [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"),
  47.  
  48.         InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  49.  
  50.         public interface IAudioEndpointVolume
  51.         {
  52.  
  53.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE RegisterControlChangeNotify(/* [in] */__in IAudioEndpointVolumeCallback *pNotify) = 0;
  54.  
  55.             //int RegisterControlChangeNotify(IntPtr pNotify);
  56.  
  57.             int RegisterControlChangeNotify(DelegateMixerChange pNotify);
  58.  
  59.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UnregisterControlChangeNotify(/* [in] */ __in IAudioEndpointVolumeCallback *pNotify) = 0;
  60.  
  61.             //int UnregisterControlChangeNotify(IntPtr pNotify);
  62.  
  63.             int UnregisterControlChangeNotify(DelegateMixerChange pNotify);
  64.  
  65.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelCount(/* [out] */ __out UINT *pnChannelCount) = 0;
  66.  
  67.             int GetChannelCount(ref uint pnChannelCount);
  68.  
  69.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevel( /* [in] */ __in float fLevelDB,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
  70.  
  71.             int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext);
  72.  
  73.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevelScalar( /* [in] */ __in float fLevel,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
  74.  
  75.             int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
  76.  
  77.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevel(/* [out] */ __out float *pfLevelDB) = 0;
  78.  
  79.             int GetMasterVolumeLevel(ref float pfLevelDB);
  80.  
  81.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevelScalar( /* [out] */ __out float *pfLevel) = 0;
  82.  
  83.             int GetMasterVolumeLevelScalar(ref float pfLevel);
  84.  
  85.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetChannelVolumeLevel(/* [in] */__in UINT nChannel,float fLevelDB,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
  86.  
  87.             int SetChannelVolumeLevel(uint nChannel, float fLevelDB, Guid pguidEventContext);
  88.  
  89.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetChannelVolumeLevelScalar(/* [in] */ __in UINT nChannel,float fLevel,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
  90.  
  91.             int SetChannelVolumeLevelScalar(uint nChannel, float fLevel, Guid pguidEventContext);
  92.  
  93.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelVolumeLevel(/* [in] */ __in UINT nChannel,/* [out] */__out float *pfLevelDB) = 0;
  94.  
  95.             int GetChannelVolumeLevel(uint nChannel, ref float pfLevelDB);
  96.  
  97.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelVolumeLevelScalar(/* [in] */__in UINT nChannel,/* [out] */__out float *pfLevel) = 0;
  98.  
  99.             int GetChannelVolumeLevelScalar(uint nChannel, ref float pfLevel);
  100.  
  101.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMute( /* [in] *__in BOOL bMute, /* [unique][in] */ LPCGUID pguidEventContext) = 0;
  102.  
  103.             int SetMute(bool bMute, Guid pguidEventContext);
  104.  
  105.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMute( /* [out] */ __out BOOL *pbMute) = 0;
  106.  
  107.             int GetMute(ref bool pbMute);
  108.  
  109.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVolumeStepInfo( /* [out] */ __out UINT *pnStep,/* [out] */__out UINT *pnStepCount) = 0;
  110.  
  111.             int GetVolumeStepInfo(ref uint pnStep, ref uint pnStepCount);
  112.  
  113.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VolumeStepUp( /* [unique][in] */ LPCGUID pguidEventContext) = 0;
  114.  
  115.             int VolumeStepUp(Guid pguidEventContext);
  116.  
  117.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE VolumeStepDown(/* [unique][in] */ LPCGUID pguidEventContext) = 0;
  118.  
  119.             int VolumeStepDown(Guid pguidEventContext);
  120.  
  121.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE QueryHardwareSupport(/* [out] */ __out DWORD *pdwHardwareSupportMask) = 0;
  122.  
  123.             int QueryHardwareSupport(ref uint pdwHardwareSupportMask);
  124.  
  125.             //virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVolumeRange( /* [out] */ __out float *pflVolumeMindB,/* [out] */ __out float *pflVolumeMaxdB,/* [out] */ __out float *pflVolumeIncrementdB) = 0;
  126.  
  127.             int GetVolumeRange(ref float pflVolumeMindB, ref float pflVolumeMaxdB, ref float pflVolumeIncrementdB);
  128.  
  129.         }
  130.  
  131.         [Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"),
  132.  
  133.         InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  134.  
  135.         public interface IMMDeviceCollection
  136.         {
  137.  
  138.             //HRESULT GetCount([out, annotation("__out")] UINT* pcDevices);
  139.  
  140.             int GetCount(ref uint pcDevices);
  141.  
  142.             //HRESULT Item([in, annotation("__in")]UINT nDevice, [out, annotation("__out")] IMMDevice** ppDevice);
  143.  
  144.             int Item(uint nDevice, ref IntPtr ppDevice);
  145.  
  146.         }
  147.  
  148.         [Guid("D666063F-1587-4E43-81F1-B948E807363F"),
  149.  
  150.         InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  151.  
  152.         public interface IMMDevice
  153.         {
  154.  
  155.             //HRESULT Activate([in, annotation("__in")] REFIID iid, [in, annotation("__in")] DWORD dwClsCtx, [in,unique, annotation("__in_opt")] PROPVARIANT* pActivationParams, [out,iid_is(iid), annotation("__out")] void** ppInterface);
  156.  
  157.             int Activate(ref Guid iid, uint dwClsCtx, IntPtr pActivationParams, ref IntPtr ppInterface);
  158.  
  159.             //HRESULT OpenPropertyStore([in, annotation("__in")] DWORD stgmAccess, [out, annotation("__out")] IPropertyStore** ppProperties);
  160.  
  161.             int OpenPropertyStore(int stgmAccess, ref IntPtr ppProperties);
  162.  
  163.             //HRESULT GetId([out,annotation("__deref_out")] LPWSTR* ppstrId);
  164.  
  165.             int GetId(ref string ppstrId);
  166.  
  167.             //HRESULT GetState([out, annotation("__out")] DWORD* pdwState);
  168.  
  169.             int GetState(ref int pdwState);
  170.  
  171.         }
  172.  
  173.         [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"),
  174.  
  175.         //[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"),
  176.  
  177.         InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  178.  
  179.         public interface IMMDeviceEnumerator
  180.         {
  181.  
  182.             //HRESULT EnumAudioEndpoints([in, annotation("__in")] EDataFlow dataFlow, [in, annotation("__in")] DWORD dwStateMask, [out, annotation("__out")] IMMDeviceCollection** ppDevices);
  183.  
  184.             int EnumAudioEndpoints(EDataFlow dataFlow, int dwStateMask, ref IntPtr ppDevices);
  185.  
  186.             //HRESULT GetDefaultAudioEndpoint([in, annotation("__in")] EDataFlow dataFlow, [in, annotation("__in")] ERole role, [out, annotation("__out")] IMMDevice** ppEndpoint);
  187.  
  188.             int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, ref IntPtr ppEndpoint);
  189.  
  190.             //HRESULT GetDevice([, annotation("__in")]LPCWSTR pwstrId, [out, annotation("__out")] IMMDevice** ppDevice);
  191.  
  192.             int GetDevice(string pwstrId, ref IntPtr ppDevice);
  193.  
  194.             //HRESULT RegisterEndpointNotificationCallback([in, annotation("__in")] IMMNotificationClient* pClient);
  195.  
  196.             int RegisterEndpointNotificationCallback(IntPtr pClient);
  197.  
  198.             //HRESULT UnregisterEndpointNotificationCallback([in, annotation("__in")] IMMNotificationClient* pClient);
  199.  
  200.             int UnregisterEndpointNotificationCallback(IntPtr pClient);
  201.  
  202.         }
  203.  
  204.         [Flags]
  205.  
  206.         enum CLSCTX : uint
  207.         {
  208.  
  209.             CLSCTX_INPROC_SERVER = 0x1,
  210.  
  211.             CLSCTX_INPROC_HANDLER = 0x2,
  212.  
  213.             CLSCTX_LOCAL_SERVER = 0x4,
  214.  
  215.             CLSCTX_INPROC_SERVER16 = 0x8,
  216.  
  217.             CLSCTX_REMOTE_SERVER = 0x10,
  218.  
  219.             CLSCTX_INPROC_HANDLER16 = 0x20,
  220.  
  221.             CLSCTX_RESERVED1 = 0x40,
  222.  
  223.             CLSCTX_RESERVED2 = 0x80,
  224.  
  225.             CLSCTX_RESERVED3 = 0x100,
  226.  
  227.             CLSCTX_RESERVED4 = 0x200,
  228.  
  229.             CLSCTX_NO_CODE_DOWNLOAD = 0x400,
  230.  
  231.             CLSCTX_RESERVED5 = 0x800,
  232.  
  233.             CLSCTX_NO_CUSTOM_MARSHAL = 0x1000,
  234.  
  235.             CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000,
  236.  
  237.             CLSCTX_NO_FAILURE_LOG = 0x4000,
  238.  
  239.             CLSCTX_DISABLE_AAA = 0x8000,
  240.  
  241.             CLSCTX_ENABLE_AAA = 0x10000,
  242.  
  243.             CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000,
  244.  
  245.             CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
  246.  
  247.             CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
  248.  
  249.             CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER
  250.  
  251.         }
  252.  
  253.         public enum EDataFlow
  254.         {
  255.  
  256.             eRender,
  257.  
  258.             eCapture,
  259.  
  260.             eAll,
  261.  
  262.             EDataFlow_enum_count
  263.  
  264.         }
  265.  
  266.         public enum ERole
  267.         {
  268.  
  269.             eConsole,
  270.  
  271.             eMultimedia,
  272.  
  273.             eCommunications,
  274.  
  275.             ERole_enum_count
  276.  
  277.         }
  278.  
  279.         #endregion
  280.  
  281.         // Private internal var
  282.  
  283.         object oEnumerator = null;
  284.  
  285.         IMMDeviceEnumerator iMde = null;
  286.  
  287.         object oDevice = null;
  288.  
  289.         IMMDevice imd = null;
  290.  
  291.         object oEndPoint = null;
  292.  
  293.         IAudioEndpointVolume iAudioEndpoint = null;
  294.  
  295.         // TODO
  296.  
  297.         // Problem #1 : I can't handle a volume changed event by other applications
  298.  
  299.         // (example while using the program SndVol.exe)
  300.  
  301.         public delegate void DelegateMixerChange();
  302.  
  303.         //public DelegateMixerChange delMixerChange = null;
  304.  
  305.         public delegate void MixerChangedEventHandler();
  306.  
  307.         //public event MixerChangedEventHandler MixerChanged;
  308.  
  309.         #region Class Constructor and Dispose public methods
  310.  
  311.         /// <summary>
  312.  
  313.         /// Constructor
  314.  
  315.         /// </summary>
  316.  
  317.         public EndpointVolume()
  318.         {
  319.  
  320.             const uint CLSCTX_INPROC_SERVER = 1;
  321.  
  322.             Guid clsid = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E");
  323.  
  324.             Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
  325.  
  326.             oEnumerator = null;
  327.  
  328.             uint hResult = CoCreateInstance(ref clsid, null, CLSCTX_INPROC_SERVER, ref IID_IUnknown, out oEnumerator);
  329.  
  330.             if (hResult != 0 || oEnumerator == null)
  331.             {
  332.                 throw new Exception("CoCreateInstance() pInvoke failed");
  333.             }
  334.  
  335.             iMde = oEnumerator as IMMDeviceEnumerator;
  336.  
  337.             if (iMde == null)
  338.             {
  339.                 throw new Exception("COM cast failed to IMMDeviceEnumerator");
  340.             }
  341.  
  342.             IntPtr pDevice = IntPtr.Zero;
  343.  
  344.             int retVal = iMde.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eConsole, ref pDevice);
  345.  
  346.             if (retVal != 0)
  347.             {
  348.                 throw new Exception("IMMDeviceEnumerator.GetDefaultAudioEndpoint()");
  349.             }
  350.  
  351.             int dwStateMask = DEVICE_STATE_ACTIVE | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED;
  352.  
  353.             IntPtr pCollection = IntPtr.Zero;
  354.  
  355.             retVal = iMde.EnumAudioEndpoints(EDataFlow.eRender, dwStateMask, ref pCollection);
  356.  
  357.             if (retVal != 0)
  358.             {
  359.                 throw new Exception("IMMDeviceEnumerator.EnumAudioEndpoints()");
  360.             }
  361.  
  362.             oDevice = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(pDevice);
  363.  
  364.             imd = oDevice as IMMDevice;
  365.  
  366.             if (imd == null)
  367.             {
  368.                 throw new Exception("COM cast failed to IMMDevice");
  369.             }
  370.  
  371.             Guid iid = new Guid("5CDF2C82-841E-4546-9722-0CF74078229A");
  372.  
  373.             uint dwClsCtx = (uint)CLSCTX.CLSCTX_ALL;
  374.  
  375.             IntPtr pActivationParams = IntPtr.Zero;
  376.  
  377.             IntPtr pEndPoint = IntPtr.Zero;
  378.  
  379.             retVal = imd.Activate(ref iid, dwClsCtx, pActivationParams, ref pEndPoint);
  380.  
  381.             if (retVal != 0)
  382.             {
  383.                 throw new Exception("IMMDevice.Activate()");
  384.             }
  385.  
  386.             oEndPoint = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(pEndPoint);
  387.  
  388.             iAudioEndpoint = oEndPoint as IAudioEndpointVolume;
  389.  
  390.             if (iAudioEndpoint == null)
  391.             {
  392.                 throw new Exception("COM cast failed to IAudioEndpointVolume");
  393.             }
  394.  
  395.             /*
  396.  
  397.             delMixerChange = new DelegateMixerChange(MixerChange);
  398.  
  399.             retVal = iAudioEndpoint.RegisterControlChangeNotify(delMixerChange);
  400.  
  401.             if (retVal != 0)
  402.  
  403.             {
  404.  
  405.             throw new Exception("iAudioEndpoint.RegisterControlChangeNotify(delMixerChange)");
  406.  
  407.             }
  408.  
  409.             */
  410.  
  411.         }
  412.  
  413.         /// <summary>
  414.  
  415.         /// Call this method to release all com objetcs
  416.  
  417.         /// </summary>
  418.  
  419.         public virtual void Dispose()
  420.         {
  421.  
  422.             /*
  423.  
  424.             if (delMixerChange != null && iAudioEndpoint != null)
  425.  
  426.             {
  427.  
  428.             iAudioEndpoint.UnregisterControlChangeNotify(delMixerChange);
  429.  
  430.             }
  431.  
  432.             */
  433.  
  434.             if (iAudioEndpoint != null)
  435.             {
  436.                 System.Runtime.InteropServices.Marshal.ReleaseComObject(iAudioEndpoint);
  437.                 iAudioEndpoint = null;
  438.             }
  439.  
  440.             if (oEndPoint != null)
  441.             {
  442.                 System.Runtime.InteropServices.Marshal.ReleaseComObject(oEndPoint);
  443.                 oEndPoint = null;
  444.             }
  445.  
  446.             if (imd != null)
  447.             {
  448.                 System.Runtime.InteropServices.Marshal.ReleaseComObject(imd);
  449.                 imd = null;
  450.             }
  451.  
  452.             if (oDevice != null)
  453.             {
  454.  
  455.                 System.Runtime.InteropServices.Marshal.ReleaseComObject(oDevice);
  456.  
  457.                 oDevice = null;
  458.  
  459.             }
  460.  
  461.             //System.Runtime.InteropServices.Marshal.ReleaseComObject(pCollection);
  462.  
  463.             if (iMde != null)
  464.             {
  465.  
  466.                 System.Runtime.InteropServices.Marshal.ReleaseComObject(iMde);
  467.  
  468.                 iMde = null;
  469.  
  470.             }
  471.  
  472.             if (oEnumerator != null)
  473.             {
  474.  
  475.                 System.Runtime.InteropServices.Marshal.ReleaseComObject(oEnumerator);
  476.  
  477.                 oEnumerator = null;
  478.  
  479.             }
  480.  
  481.         }
  482.  
  483.         #endregion
  484.  
  485.         #region Private internal functions
  486.  
  487.         private void MixerChange()
  488.         {
  489.  
  490.             /*
  491.  
  492.             if (MixerChanged != null)
  493.  
  494.             // Notify (raise) event
  495.  
  496.             MixerChanged();
  497.  
  498.             */
  499.  
  500.         }
  501.  
  502.         #endregion
  503.  
  504.         #region Public properties
  505.  
  506.         /// <summary>
  507.  
  508.         /// Get/set the master volume level. Valid range is from 0.00F (0%) to 1.00F (100%).
  509.  
  510.         /// </summary>
  511.  
  512.         public float MasterVolume
  513.         {
  514.  
  515.             get
  516.             {
  517.  
  518.                 float level = 0.0F;
  519.  
  520.                 int retVal = iAudioEndpoint.GetMasterVolumeLevelScalar(ref level);
  521.  
  522.                 if (retVal != 0)
  523.                 {
  524.  
  525.                     throw new Exception("IAudioEndpointVolume.GetMasterVolumeLevelScalar()");
  526.  
  527.                 }
  528.  
  529.                 return level;
  530.  
  531.             }
  532.  
  533.             set
  534.             {
  535.  
  536.                 float level = value;
  537.  
  538.                 Guid nullGuid;
  539.  
  540.                 //nullGuid = new Guid("{00000000-0000-0000-0000-000000000000}"); // null
  541.  
  542.                 // {dddddddd-dddd-dddd-dddd-dddddddddddd}
  543.  
  544.                 nullGuid = Guid.Empty;
  545.  
  546.                 int retVal = iAudioEndpoint.SetMasterVolumeLevelScalar(level, nullGuid);
  547.  
  548.                 if (retVal != 0)
  549.                 {
  550.  
  551.                     throw new Exception("IAudioEndpointVolume.SetMasterVolumeLevelScalar()");
  552.  
  553.                 }
  554.  
  555.             }
  556.  
  557.         }
  558.  
  559.         #endregion
  560.  
  561.         #region Public Methods
  562.  
  563.         /// <summary>
  564.  
  565.         /// Increase the master volume
  566.  
  567.         /// </summary>
  568.  
  569.         public void VolumeUp()
  570.         {
  571.  
  572.             Guid nullGuid;
  573.  
  574.             //nullGuid = new Guid("{00000000-0000-0000-0000-000000000000}"); // null
  575.  
  576.             // {dddddddd-dddd-dddd-dddd-dddddddddddd}
  577.  
  578.             nullGuid = Guid.Empty;
  579.  
  580.             int retVal = iAudioEndpoint.VolumeStepUp(nullGuid);
  581.  
  582.             if (retVal != 0)
  583.             {
  584.  
  585.                 throw new Exception("IAudioEndpointVolume.SetMute()");
  586.  
  587.             }
  588.  
  589.         }
  590.  
  591.         /// <summary>
  592.  
  593.         /// Decrease the master volume
  594.  
  595.         /// </summary>
  596.  
  597.         public void VolumeDown()
  598.         {
  599.  
  600.             Guid nullGuid;
  601.  
  602.             //nullGuid = new Guid("{00000000-0000-0000-0000-000000000000}"); // null
  603.  
  604.             // {dddddddd-dddd-dddd-dddd-dddddddddddd}
  605.  
  606.             nullGuid = Guid.Empty;
  607.  
  608.             int retVal = iAudioEndpoint.VolumeStepDown(nullGuid);
  609.  
  610.         }
  611.  
  612.         #endregion
  613.  
  614.     }
  615.  
  616. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement