zoukankan      html  css  js  c++  java
  • 在.NET程序中控制系统音量

    在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 ,00);

                  
    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 ,00);

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

             }


         }


    }


     

    本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利
  • 相关阅读:
    python 包管理工具 pip 的配置
    Python 变量作用域 LEGB (下)—— Enclosing function locals
    Python 变量作用域 LEGB (上)—— Local,Global,Builtin
    2020 Java 面试题 小结 (答案慢慢补上,有错误请指出)
    mysql 根据日期(date)做年,月,日分组统计查询
    jvm指令
    正则表达式 分割地址 获取省市区详细地址
    .Net 异常记录
    WCF设计服务协议(一)
    plsql ORA-01789:查询块具有不正确的结果列数
  • 原文地址:https://www.cnblogs.com/roger/p/107592.html
Copyright © 2011-2022 走看看