예제 #1
0
 private static void ReverseMute()
 {
     InvokeTryCatch("WinXpVolumeOperate.ReverseMute", () =>
     {
         // 如果系统是静音状态 则 解除静音, 如果不是静音状态 则 设为静音
         WinXpDllInterface.keybd_event(WinXpDllInterface.VK_VOLUME_MUTE, WinXpDllInterface.MapVirtualKey(WinXpDllInterface.VK_VOLUME_MUTE, 0), WinXpDllInterface.KEYEVENTF_EXTENDEDKEY, 0);
         WinXpDllInterface.keybd_event(WinXpDllInterface.VK_VOLUME_MUTE, WinXpDllInterface.MapVirtualKey(WinXpDllInterface.VK_VOLUME_MUTE, 0), WinXpDllInterface.KEYEVENTF_EXTENDEDKEY | WinXpDllInterface.KEYEVENTF_KEYUP, 0);
     });
 }
예제 #2
0
            private static WinXpDllInterface.MIXER InnerGetMixer(int i, uint type, uint ctrlType, out int currVolume)
            {
                currVolume = -1;

                WinXpDllInterface.LINECONTROLS  mlc  = new WinXpDllInterface.LINECONTROLS();
                WinXpDllInterface.MIXERLINE     mxl  = new WinXpDllInterface.MIXERLINE();
                WinXpDllInterface.MIXERDETAILS  xdl  = new WinXpDllInterface.MIXERDETAILS();
                WinXpDllInterface.UMIXERDETAILS uxdl = new WinXpDllInterface.UMIXERDETAILS();

                WinXpDllInterface.MIXER mixerControl = new WinXpDllInterface.MIXER();

                mxl.cbStruct        = (uint)Marshal.SizeOf(mxl);
                mxl.dwComponentType = (uint)type;
                int details = WinXpDllInterface.mixerGetLineInfoA(i, ref mxl, WinXpDllInterface.MIXER_GETLINEINFOF_COMPONENTTYPE);

                if (WinXpDllInterface.MMSYSERR_NOERROR == details)
                {
                    int mcSize  = 152;
                    int control = Marshal.SizeOf(typeof(WinXpDllInterface.MIXER));
                    mlc.pamxctrl = Marshal.AllocCoTaskMem(mcSize);
                    mlc.cbStruct = (uint)Marshal.SizeOf(mlc);

                    mlc.dwLineID  = mxl.dwLineID;
                    mlc.dwControl = (uint)ctrlType;
                    mlc.cControls = 1;
                    mlc.cbmxctrl  = (uint)mcSize;

                    mixerControl.cbStruct = mcSize;

                    details = WinXpDllInterface.mixerGetLineControlsA(i, ref mlc, WinXpDllInterface.MIXER_GETLINECONTROLSF_ONEBYTYPE);
                    bool result = WinXpDllInterface.MMSYSERR_NOERROR == details;
                    if (result)
                    {
                        mixerControl = (WinXpDllInterface.MIXER)Marshal.PtrToStructure(mlc.pamxctrl, typeof(WinXpDllInterface.MIXER));

                        int mcDetailsSize     = Marshal.SizeOf(typeof(WinXpDllInterface.MIXERDETAILS));
                        int mcDetailsUnsigned = Marshal.SizeOf(typeof(WinXpDllInterface.UMIXERDETAILS));
                        xdl.cbStruct    = mcDetailsSize;
                        xdl.dwControlID = mixerControl.dwControlID;
                        xdl.paDetails   = Marshal.AllocCoTaskMem(mcDetailsUnsigned);
                        xdl.cChannels   = 1;
                        xdl.item        = 0;
                        xdl.cbDetails   = mcDetailsUnsigned;
                        details         = WinXpDllInterface.mixerGetControlDetailsA(i, ref xdl, WinXpDllInterface.MIXER_GETCONTROLDETAILSF_VALUE);
                        uxdl            = (WinXpDllInterface.UMIXERDETAILS)Marshal.PtrToStructure(xdl.paDetails, typeof(WinXpDllInterface.UMIXERDETAILS));
                        currVolume      = uxdl.dwValue;

                        return(mixerControl);
                    }
                }

                return(mixerControl);
            }
예제 #3
0
            private static int GetVolume()
            {
                int result = 0;

                InvokeTryCatch("WinXpVolumeOperate.GetVolume", () =>
                {
                    int currVolume;
                    int mixerControl;

                    WinXpDllInterface.mixerOpen(out mixerControl, 0, 0, 0, 0);
                    uint type = WinXpDllInterface.MIXERCONTROL_CONTROLTYPE_VOLUME;

                    InnerGetMixer(mixerControl, WinXpDllInterface.MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, out currVolume);
                    WinXpDllInterface.mixerClose(mixerControl);

                    result = currVolume;
                });
                return(result);
            }
예제 #4
0
            private static bool InnerSetMixer(int i, WinXpDllInterface.MIXER mixer, int volume)
            {
                WinXpDllInterface.MIXERDETAILS  xdl  = new WinXpDllInterface.MIXERDETAILS();
                WinXpDllInterface.UMIXERDETAILS uxdl = new WinXpDllInterface.UMIXERDETAILS();

                xdl.item        = 0;
                xdl.dwControlID = mixer.dwControlID;
                xdl.cbStruct    = Marshal.SizeOf(xdl);
                xdl.cbDetails   = Marshal.SizeOf(uxdl);

                xdl.cChannels = 1;
                uxdl.dwValue  = volume;

                xdl.paDetails = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(WinXpDllInterface.UMIXERDETAILS)));
                Marshal.StructureToPtr(uxdl, xdl.paDetails, false);

                int details = WinXpDllInterface.mixerSetControlDetails(i, ref xdl, WinXpDllInterface.MIXER_SETCONTROLDETAILSF_VALUE);

                return(WinXpDllInterface.MMSYSERR_NOERROR == details);
            }
예제 #5
0
            private static WinXpDllInterface.MIXERINFO InnerGetMixerInfo()
            {
                WinXpDllInterface.MIXERLINE    mxl = new WinXpDllInterface.MIXERLINE();
                WinXpDllInterface.LINECONTROLS mlc = new WinXpDllInterface.LINECONTROLS();
                mxl.cbStruct = (uint)Marshal.SizeOf(typeof(WinXpDllInterface.MIXERLINE));
                mlc.cbStruct = (uint)Marshal.SizeOf(typeof(WinXpDllInterface.LINECONTROLS));

                WinXpDllInterface.mixerGetLineInfo(0, ref mxl, WinXpDllInterface.MIXER_OBJECTF_MIXER | WinXpDllInterface.MIXER_GETLINEINFOF_DESTINATION);

                mlc.dwLineID  = mxl.dwLineID;
                mlc.cControls = mxl.cControls;
                mlc.cbmxctrl  = (uint)Marshal.SizeOf(typeof(WinXpDllInterface.MIXERCONTROL));
                mlc.pamxctrl  = Marshal.AllocHGlobal((int)(mlc.cbmxctrl * mlc.cControls));

                WinXpDllInterface.mixerGetLineControls(0, ref mlc, WinXpDllInterface.MIXER_OBJECTF_MIXER | WinXpDllInterface.MIXER_GETLINECONTROLSF_ALL);

                WinXpDllInterface.MIXERINFO rtn = new WinXpDllInterface.MIXERINFO();

                for (int i = 0; i < mlc.cControls; i++)
                {
                    WinXpDllInterface.MIXERCONTROL mxc = (WinXpDllInterface.MIXERCONTROL)Marshal.PtrToStructure((IntPtr)((int)mlc.pamxctrl + (int)mlc.cbmxctrl * i), typeof(WinXpDllInterface.MIXERCONTROL));
                    switch (mxc.dwControlType)
                    {
                    case WinXpDllInterface.MIXERCONTROL_CONTROLTYPE_VOLUME:
                        rtn.volumeCtl = mxc.dwControlID;
                        rtn.minVolume = mxc.Bounds.lMinimum;
                        rtn.maxVolume = mxc.Bounds.lMaximum;
                        break;

                    case WinXpDllInterface.MIXERCONTROL_CONTROLTYPE_MUTE:
                        rtn.muteCtl = mxc.dwControlID;
                        break;
                    }
                }

                Marshal.FreeHGlobal(mlc.pamxctrl);

                return(rtn);
            }
예제 #6
0
            private static bool GetIsMuted()
            {
                bool result = false;

                InvokeTryCatch("WinXpVolumeOperate.GetIsMuted", () =>
                {
                    WinXpDllInterface.MIXERINFO mixer  = InnerGetMixerInfo();
                    WinXpDllInterface.MIXERDETAILS mcd = new WinXpDllInterface.MIXERDETAILS();
                    mcd.cbStruct    = Marshal.SizeOf(typeof(WinXpDllInterface.MIXERDETAILS));
                    mcd.dwControlID = (int)mixer.muteCtl;
                    mcd.cChannels   = 1;
                    mcd.cbDetails   = 4;
                    mcd.paDetails   = Marshal.AllocHGlobal((int)mcd.cbDetails);

                    WinXpDllInterface.mixerGetControlDetails(0, ref mcd, WinXpDllInterface.MIXER_GETCONTROLDETAILSF_VALUE | WinXpDllInterface.MIXER_OBJECTF_MIXER);
                    int rtn = Marshal.ReadInt32(mcd.paDetails);
                    Marshal.FreeHGlobal(mcd.paDetails);

                    result = rtn != 0;
                });
                return(result);
            }
예제 #7
0
            private static void SetVolume(int volume)
            {
                InvokeTryCatch("WinXpVolumeOperate.SetVolume", () =>
                {
                    int currVolume;
                    int mixerControl;

                    WinXpDllInterface.mixerOpen(out mixerControl, 0, 0, 0, 0);
                    uint controlType = WinXpDllInterface.MIXERCONTROL_CONTROLTYPE_VOLUME;
                    WinXpDllInterface.MIXER mixer = InnerGetMixer(mixerControl, WinXpDllInterface.MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, controlType, out currVolume);

                    bool setSucceed = false;
                    for (int i = 0; i < 3; i++)
                    {
                        if (volume > mixer.lMaximum)
                        {
                            volume = mixer.lMaximum;
                        }
                        if (volume < mixer.lMinimum)
                        {
                            volume = mixer.lMinimum;
                        }
                        InnerSetMixer(mixerControl, mixer, volume);
                        mixer = InnerGetMixer(mixerControl, WinXpDllInterface.MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, controlType, out currVolume);

                        if (volume == currVolume)
                        {
                            setSucceed = true; break;
                        }                                                       //如果设置失败, 则最多重试3次
                    }

                    WinXpDllInterface.mixerClose(mixerControl);
                    if (!setSucceed)
                    {
                        throw new Exception("多次尝试设置 Xp操作系统音量 失败 (该异常可能是偶发异常, 可以忽略)!");
                    }
                });
            }