[C#] 控制系统音量-第一章

来源:互联网 发布:纪录片知乎 编辑:程序博客网 时间:2024/05/22 13:19

一直想控制系统音量,但是似乎C#都有着很多的问题,索性去看API。

最后找到了一个外国友人的东西,外国友人写的类就是好看,感觉比自己写的要规范好多啊!

自己使用了此类后发现了一个问题,在XP系统下正常,但是Win7以上都不能正常使用。

然后又查了一下官方的解释,原来微软win7后就改动了底层的音量控制的东西。

现在贴出来,希望大家对大家有帮助,在后面将讲解在Win7及其以上怎么操作系统音量的问题!

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

转载请注明出处!

0 0
原创粉丝点击