在.NET程序中控制系统音量

来源:互联网 发布:h5网站制作软件 编辑:程序博客网 时间:2024/05/17 01:49

在windows下控制系统音量,需要通过使用win32的WDM audio components(winmm.dll)来实现,为了方便起见,将其封装到了一个AudioMixerHelper类中,可以直接通过GetVolume()和SetVolume方法来改变音量。


using System; 
using System.Runtime.InteropServices;  
 
namespace Microsoft 
{  
     public class AudioMixerHelper 
     { 
         public const int MMSYSERR_NOERROR = 0;
 
         public const int MAXPNAMELEN = 32;
 
         public const int MIXER_LONG_NAME_CHARS = 64;
 
         public const int MIXER_SHORT_NAME_CHARS = 16;
 
         public const int MIXER_GETLINEINFOF_COMPONENTTYPE  = 0x3;
 
         public const int MIXER_GETCONTROLDETAILSF_VALUE = 0x0;
 
         public const int MIXER_GETLINECONTROLSF_ONEBYTYPE  = 0x2;
 
         public const int MIXER_SETCONTROLDETAILSF_VALUE = 0x0;
 
         public const int MIXERLINE_COMPONENTTYPE_DST_FIRST = 0x0;
 
         public const int MIXERLINE_COMPONENTTYPE_SRC_FIRST = 0x1000;
 
         public const int MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = 
              (MIXERLINE_COMPONENTTYPE_DST_FIRST + 4);
 
         public const int MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = 
              (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3);
 
         public const int MIXERLINE_COMPONENTTYPE_SRC_LINE = 
              (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2);
 
         public const int MIXERCONTROL_CT_CLASS_FADER = 0x50000000;
 
         public const int MIXERCONTROL_CT_UNITS_UNSIGNED = 0x30000;
 
         public const int MIXERCONTROL_CONTROLTYPE_FADER = 
              (MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED);
 
         public const int MIXERCONTROL_CONTROLTYPE_VOLUME = 
              (MIXERCONTROL_CONTROLTYPE_FADER + 1);   
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int mixerClose (int hmx);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int mixerGetControlDetailsA (int hmxobj,ref 
              MIXERCONTROLDETAILS pmxcd , int fdwDetails);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int mixerGetDevCapsA(int uMxId, MIXERCAPS 
              pmxcaps, int cbmxcaps);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int mixerGetID (int hmxobj, int pumxID, int 
              fdwId);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int  mixerGetLineControlsA (int hmxobj,ref 
              MIXERLINECONTROLS pmxlc, int fdwControls);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int  mixerGetLineInfoA (int hmxobj,ref 
              MIXERLINE pmxl , int fdwInfo);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int  mixerGetNumDevs();
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int  mixerMessage(int hmx , int uMsg , int 
              dwParam1 , int dwParam2);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int  mixerOpen  (out int phmx , int uMxId , 
              int dwCallback , int dwInstance , int fdwOpen);
 
         [DllImport("winmm.dll", CharSet=CharSet.Ansi)] 
         private static extern int  mixerSetControlDetails(int hmxobj ,ref 
              MIXERCONTROLDETAILS pmxcd  , int fdwDetails);
 
  
         public struct MIXERCAPS 
         { 
              public int wMid;
 
              public int wPid;
 
              public int vDriverVersion;
 
              [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)]
 
              public string szPname;
 
              public int fdwSupport;
 
              public int cDestinations; 
         } 
 
 
         public struct MIXERCONTROL 
         { 
              public int cbStruct;
 
              public int dwControlID;
 
              public int dwControlType;
 
              public int fdwControl;
 
              public int cMultipleItems;
 
              [MarshalAs( UnmanagedType.ByValTStr, 
                    SizeConst=MIXER_SHORT_NAME_CHARS)] 
              public string szShortName ; 

              [MarshalAs( UnmanagedType.ByValTStr, 
                    SizeConst=MIXER_LONG_NAME_CHARS)] 
              public string szName;
 
              public int lMinimum;
 
              public int lMaximum;
 
              [MarshalAs(UnmanagedType.U4, SizeConst=10)] 
              public int reserved; 
         }
 
 
 
         public struct MIXERCONTROLDETAILS 
         { 
              public int cbStruct;
 
              public int dwControlID;
 
              public int cChannels;
 
              public int item;
 
              public int cbDetails;
 
              public IntPtr paDetails; 
         }
  
 
         public struct MIXERCONTROLDETAILS_UNSIGNED
         { 
              public int dwValue;
         }
 
 
 
         public struct MIXERLINE
          { 
              public int cbStruct; 

              public int dwDestination; 

              public int dwSource; 

              public int dwLineID;
 
              public int fdwLine;
 
              public int dwUser;
 
              public int dwComponentType;
 
              public int cChannels;
 
              public int cConnections;
 
              public int cControls;
 
              [MarshalAs(UnmanagedType.ByValTStr, 
                    SizeConst=MIXER_SHORT_NAME_CHARS)] 
              public string szShortName;
 
              [MarshalAs(UnmanagedType.ByValTStr, 
                    SizeConst=MIXER_LONG_NAME_CHARS )] 
              public string szName;
 
              public int dwType;
 
              public int dwDeviceID;
 
              public int wMid;
 
              public int wPid;
 
              public int vDriverVersion ;
 
              [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)] 
              public string szPname ; 
         }
 
 
 
         public struct MIXERLINECONTROLS 
         { 
              public int cbStruct;
 
              public int dwLineID;
  
              public int dwControl;
 
              public int cControls;
 
              public int cbmxctrl;
 
              public IntPtr pamxctrl; 
         }
  
 
         private static bool GetVolumeControl(int hmixer, int componentType, 
              int ctrlType, out MIXERCONTROL mxc, out int vCurrentVol) 
         { 
              // This function attempts to obtain a mixer control. 
              // Returns True if successful.
 
              MIXERLINECONTROLS mxlc = new MIXERLINECONTROLS(); 
              MIXERLINE mxl = new MIXERLINE(); 
              MIXERCONTROLDETAILS pmxcd = new MIXERCONTROLDETAILS(); 
              MIXERCONTROLDETAILS_UNSIGNED du = new MIXERCONTROLDETAILS_UNSIGNED(); 
              mxc = new MIXERCONTROL();
 
              int rc; 
              bool retValue; 
              vCurrentVol = -1; 
  
              mxl.cbStruct = Marshal.SizeOf(mxl); 
              mxl.dwComponentType = componentType;
   
              rc = mixerGetLineInfoA(hmixer,ref mxl, 
                   MIXER_GETLINEINFOF_COMPONENTTYPE );   
 
              if(MMSYSERR_NOERROR == rc) 
              {
 
                   int sizeofMIXERCONTROL = 152; 
                   int ctrl = Marshal.SizeOf(typeof(MIXERCONTROL));
 
                   mxlc.pamxctrl = Marshal.AllocCoTaskMem(sizeofMIXERCONTROL); 
                   mxlc.cbStruct = Marshal.SizeOf(mxlc); 
                   mxlc.dwLineID = mxl.dwLineID; 
                   mxlc.dwControl = ctrlType; 
                   mxlc.cControls = 1; 
                   mxlc.cbmxctrl = sizeofMIXERCONTROL;  
 
                   // Allocate a buffer for the control 
                   mxc.cbStruct = sizeofMIXERCONTROL; 
 
                   // Get the control 
                   rc = mixerGetLineControlsA(hmixer,ref mxlc, 
                       MIXER_GETLINECONTROLSF_ONEBYTYPE); 
 
                   if(MMSYSERR_NOERROR == rc) 
                   { 
                       retValue = true;
  
                       // Copy the control into the destination structure 
                       mxc = (MIXERCONTROL)Marshal.PtrToStructure( 
                            mxlc.pamxctrl,typeof(MIXERCONTROL)); 
                   } 
                   else 
                   { 
                       retValue = false; 
                   }
 
                   int sizeofMIXERCONTROLDETAILS = 
                       Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
 
                   int sizeofMIXERCONTROLDETAILS_UNSIGNED = 
                       Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_UNSIGNED));
 
                   pmxcd.cbStruct = sizeofMIXERCONTROLDETAILS; 
                   pmxcd.dwControlID = mxc.dwControlID; 
                   pmxcd.paDetails =
                          Marshal.AllocCoTaskMem(sizeofMIXERCONTROLDETAILS_UNSIGNED) ; 
                   pmxcd.cChannels = 1; 
                   pmxcd.item = 0;
                   pmxcd.cbDetails = sizeofMIXERCONTROLDETAILS_UNSIGNED;
  
                   rc = mixerGetControlDetailsA(hmixer,ref pmxcd, 
                       MIXER_GETCONTROLDETAILSF_VALUE); 
  
                   du = (MIXERCONTROLDETAILS_UNSIGNED)Marshal.PtrToStructure( 
                       pmxcd.paDetails, typeof(MIXERCONTROLDETAILS_UNSIGNED));
   
                   vCurrentVol = du.dwValue; 
  
                   return retValue; 
              }  
              retValue = false; 

              return retValue; 
         } 
 
 
         private static bool SetVolumeControl(int hmixer, MIXERCONTROL mxc, 
              int volume)
          { 
              // This function sets the value for a volume control. 
              // Returns True if successful
 
              bool retValue; 
              int rc;
 
              MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS(); 
              MIXERCONTROLDETAILS_UNSIGNED vol = new 
                   MIXERCONTROLDETAILS_UNSIGNED(); 
  
              mxcd.item = 0; 
              mxcd.dwControlID = mxc.dwControlID; 
              mxcd.cbStruct = Marshal.SizeOf(mxcd); 
              mxcd.cbDetails = Marshal.SizeOf(vol); 
 
              // Allocate a buffer for the control value buffer 
              mxcd.cChannels = 1; 
              vol.dwValue = volume;
  
              // Copy the data into the control value buffer 
              mxcd.paDetails = Marshal.AllocCoTaskMem(Marshal.SizeOf( 
                   typeof(MIXERCONTROLDETAILS_UNSIGNED))); 
              Marshal.StructureToPtr(vol, mxcd.paDetails,false); 
  
              // Set the control value 
              rc = mixerSetControlDetails(hmixer,ref mxcd, 
                   MIXER_SETCONTROLDETAILSF_VALUE);
   
              if(MMSYSERR_NOERROR == rc)
              { 
                   retValue = true; 
              } 
              else
              { 
                   retValue = false; 
              }

              return retValue; 
         }  
 
         public static int GetVolume() 
         { 
              int mixer; 
              MIXERCONTROL volCtrl = new MIXERCONTROL(); 

              int currentVol; 
              mixerOpen(out mixer,0 ,0 ,0, 0);
 
              int type = MIXERCONTROL_CONTROLTYPE_VOLUME; 
              GetVolumeControl(mixer, 
                   MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out 
                   currentVol); 
              mixerClose(mixer);
  
              return currentVol; 
         } 
 
 
         public static void SetVolume(int vVolume) 
         {
 
              int mixer; 
              MIXERCONTROL volCtrl = new MIXERCONTROL();
 
              int currentVol; 
              mixerOpen(out mixer,0 ,0 ,0, 0);
 
              int type = MIXERCONTROL_CONTROLTYPE_VOLUME; 
              GetVolumeControl(mixer, 
                   MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out 
                   currentVol);
 
              if(vVolume > volCtrl.lMaximum) vVolume = volCtrl.lMaximum;
 
              if(vVolume < volCtrl.lMinimum) vVolume = volCtrl.lMinimum;
 
              SetVolumeControl(mixer, volCtrl, vVolume);
 
              GetVolumeControl(mixer, 
                   MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,type,out volCtrl, out 
                   currentVol);
 
              if(vVolume != currentVol) 
              {
                   throw new Exception("Cannot Set Volume"); 
              } 
              mixerClose(mixer); 
         } 
     } 
}
 
 
 

原创粉丝点击