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); }); }
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); }
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); }
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); }
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); }
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); }
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操作系统音量 失败 (该异常可能是偶发异常, 可以忽略)!"); } }); }