sanmoking 发表于 2011-7-20 13:49:09

如何通过api获取系统静音状态

这个是网上搜到的c++的代码,小弟看不懂,那位高手给改成au3,谢谢。、、C/C++ code

BOOL IsSystemMute(UINT &uMute)
{
//uMute为0时系统非静音,否则是静音,函数返回成功与否
HMIXER hMixer;
MIXERLINE mixerline;
MIXERLINECONTROLS mlcs;
MIXERCONTROL mc;
MIXERCONTROLDETAILS_BOOLEAN mcdMute;
MIXERCONTROLDETAILS mcd;

try
{
if (MMSYSERR_NOERROR == mixerOpen(&hMixer, 0, 0, 0, 0))
{
RtlZeroMemory(&mixerline, sizeof(MIXERLINE));
mixerline.cbStruct = sizeof(MIXERLINE);
mixerline.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
if (MMSYSERR_NOERROR == mixerGetLineInfo((HMIXEROBJ)hMixer, &mixerline, MIXER_GETLINEINFOF_COMPONENTTYPE))
{
RtlZeroMemory(&mlcs, sizeof(MIXERLINECONTROLS));
mlcs.cbStruct = sizeof(MIXERLINECONTROLS);
mlcs.dwLineID = mixerline.dwLineID;
mlcs.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
mlcs.cControls = 1;
mlcs.cbmxctrl = sizeof(MIXERCONTROL);
mlcs.pamxctrl = & mc;
if (MMSYSERR_NOERROR == mixerGetLineControls((HMIXEROBJ)hMixer, &mlcs, MIXER_GETLINECONTROLSF_ONEBYTYPE))
{
RtlZeroMemory(&mcd, sizeof(MIXERCONTROLDETAILS));
mcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
mcd.dwControlID = mc.dwControlID;
mcd.cChannels = 1;
mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
mcd.paDetails = &mcdMute;
if (MMSYSERR_NOERROR == mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_VALUE))
{
uMute = mcdMute.fValue;
return TRUE;
}
}
}
}
mixerClose(hMixer);
return FALSE;
}
catch (...)
{
mixerClose(hMixer);
return FALSE;
}
}

sanmoking 发表于 2011-7-20 13:51:41

delphi可行代码一段!!都是api,翻译成vb就ok.

unit   funVolume;

interface

uses   MMSystem,   Dialogs;

Type   TDeviceName   =   (Master,   Microphone,   WaveOut,   Synth);

function   GetVolumeMute(DN:TDeviceName)   :   Boolean;
procedure   SetVolumeMute(DN:TDeviceName;   Value:Boolean);

implementation

//获取静音
function   GetVolumeMute(DN:TDeviceName)   :   Boolean;
var
hMix:   HMIXER;
mxlc:   MIXERLINECONTROLS;
mxcd:   TMIXERCONTROLDETAILS;
vol:   TMIXERCONTROLDETAILS_UNSIGNED;
mxc:   MIXERCONTROL;
mxl:   TMixerLine;
intRet:   Integer;
nMixerDevs:   Integer;
mcdMute:   MIXERCONTROLDETAILS_BOOLEAN;
begin
//   Check   if   Mixer   is   available
nMixerDevs   :=   mixerGetNumDevs();
if   (nMixerDevs   <   1)   then
begin
      Exit;
end;

//   open   the   mixer
intRet   :=   mixerOpen(@hMix,   0,   0,   0,   0);
if   intRet   =   MMSYSERR_NOERROR   then
begin
      case   DN   of
          Master   :   mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
          Microphone   :
                        mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
          WaveOut   :   mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
          Synth   :   mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
      end;
      mxl.cbStruct               :=   SizeOf(mxl);

      //   mixerline   info
      intRet   :=   mixerGetLineInfo(hMix,   @mxl,   MIXER_GETLINEINFOF_COMPONENTTYPE);

      if   intRet   =   MMSYSERR_NOERROR   then
      begin
          FillChar(mxlc,   SizeOf(mxlc),0);
          mxlc.cbStruct   :=   SizeOf(mxlc);
          mxlc.dwLineID   :=   mxl.dwLineID;
          mxlc.dwControlType   :=   MIXERCONTROL_CONTROLTYPE_MUTE;
          mxlc.cControls   :=   1;
          mxlc.cbmxctrl   :=   SizeOf(mxc);
          mxlc.pamxctrl   :=   @mxc;

          //   Get   the   mute   control
          intRet   :=   mixerGetLineControls(hMix,   @mxlc,   MIXER_GETLINECONTROLSF_ONEBYTYPE);

          if   intRet   =   MMSYSERR_NOERROR   then
          begin
            FillChar(mxcd,   SizeOf(mxcd),0);
            mxcd.cbStruct   :=   SizeOf(TMIXERCONTROLDETAILS);
            mxcd.dwControlID   :=   mxc.dwControlID;
            mxcd.cChannels   :=   1;
            mxcd.cbDetails   :=   SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
            mxcd.paDetails   :=   @mcdMute;

            //   Get   mute
            intRet   :=   mixerGetControlDetails(hMix,   @mxcd,   MIXER_SETCONTROLDETAILSF_VALUE);

            if   mcdMute.fValue   =   0   then   Result:=false
            else   Result   :=   True;

            if   intRet   <>   MMSYSERR_NOERROR   then
                  ShowMessage( 'SetControlDetails   Error ');
          end
          else
            ShowMessage( 'GetLineInfo   Error ');
      end;

      intRet   :=   mixerClose(hMix);
end;
end;

//设置静音
procedure   SetVolumeMute(DN:TDeviceName;   Value:Boolean);
var
hMix:   HMIXER;
mxlc:   MIXERLINECONTROLS;
mxcd:   TMIXERCONTROLDETAILS;
vol:   TMIXERCONTROLDETAILS_UNSIGNED;
mxc:   MIXERCONTROL;
mxl:   TMixerLine;
intRet:   Integer;
nMixerDevs:   Integer;
mcdMute:   MIXERCONTROLDETAILS_BOOLEAN;
begin
//   Check   if   Mixer   is   available
nMixerDevs   :=   mixerGetNumDevs();
if   (nMixerDevs   <   1)   then
begin
      Exit;
end;

//   open   the   mixer
intRet   :=   mixerOpen(@hMix,   0,   0,   0,   0);
if   intRet   =   MMSYSERR_NOERROR   then
begin
      case   DN   of
          Master   :   mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
          Microphone   :
                        mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
          WaveOut   :   mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
          Synth   :   mxl.dwComponentType   :=   MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
      end;
      mxl.cbStruct               :=   SizeOf(mxl);

      //   mixerline   info
      intRet   :=   mixerGetLineInfo(hMix,   @mxl,   MIXER_GETLINEINFOF_COMPONENTTYPE);

      if   intRet   =   MMSYSERR_NOERROR   then
      begin
          FillChar(mxlc,   SizeOf(mxlc),0);
          mxlc.cbStruct   :=   SizeOf(mxlc);
          mxlc.dwLineID   :=   mxl.dwLineID;
          mxlc.dwControlType   :=   MIXERCONTROL_CONTROLTYPE_MUTE;
          mxlc.cControls   :=   1;
          mxlc.cbmxctrl   :=   SizeOf(mxc);
          mxlc.pamxctrl   :=   @mxc;

          //   Get   the   mute   control
          intRet   :=   mixerGetLineControls(hMix,   @mxlc,   MIXER_GETLINECONTROLSF_ONEBYTYPE);

          if   intRet   =   MMSYSERR_NOERROR   then
          begin
            FillChar(mxcd,   SizeOf(mxcd),0);
            mxcd.cbStruct   :=   SizeOf(TMIXERCONTROLDETAILS);
            mxcd.dwControlID   :=   mxc.dwControlID;
            mxcd.cChannels   :=   1;
            mxcd.cbDetails   :=   SizeOf(MIXERCONTROLDETAILS_BOOLEAN);
            mxcd.paDetails   :=   @mcdMute;

            //   Set   and   UnSet   mute
            mcdMute.fValue   :=   Ord(Value);
            intRet   :=   mixerSetControlDetails(hMix,   @mxcd,   MIXER_SETCONTROLDETAILSF_VALUE);

            if   intRet   <>   MMSYSERR_NOERROR   then
                  ShowMessage( 'SetControlDetails   Error ');
          end
          else
            ShowMessage( 'GetLineInfo   Error ');
      end;

      intRet   :=   mixerClose(hMix);
end;
end;

end.

sanmoking 发表于 2011-7-20 13:58:57

实在不行就换AutoHotkey了。。。。

sanmoking 发表于 2011-7-20 16:09:21

本帖最后由 sanmoking 于 2011-7-20 17:41 编辑

用AutoHotkey写了个小工具,运行之后写入注册表系统静音状态【on/off】,然后就可以用au3读取了。。#NoTrayIcon
SoundGet, master_mute, , mute
RegWrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\sanmoking, vol, %master_mute%
当然也可以修改xp任务栏的标题(原始的任务栏标题是空的)
#NoTrayIcon SoundGet, master_mute, , mute
WinSetTitle, ahk_class Shell_TrayWnd, , %master_mute%



里面的vol是例子。

gzh888666 发表于 2011-7-26 10:45:03

没明白是怎么回事,AU3一样可以写入注册表呀

happytc 发表于 2011-7-26 11:37:56

看到楼主的帖子,帖个原来我写的得到声音大小的函数,给你做个参考:

Func _WaveOutGetVolume()
    Local Const $MMSYSERR_NOERROR = 0
        Local $Ptr, $aRet, $WaveVolume = -1
   
    $Ptr = DllStructCreate ("dword")
    If @error Then SetError(2, -1, -2)
    $aRet = DllCall("winmm.dll", "long", "waveOutGetVolume", "long", -1, "long", DllStructGetPtr ($Ptr))
    If ($aRet == $MMSYSERR_NOERROR) Then
      $WaveVolume = Round(Dec(StringRight(Hex(DllStructGetData($Ptr, 1), 8), 4)) / 0xFFFF * 100)
    Else
      SetError(1, 0, -1)
    EndIf

    Return $WaveVolume
EndFunc

sanmoking 发表于 2011-7-27 17:13:36

本帖最后由 sanmoking 于 2011-7-27 17:20 编辑

回复 5# gzh888666


    我的意思是,我需要au3来获取系统是否静音,但是au3本身没有这方面的函数,想用api,自己又不懂,所以在网上找了两段其他语言写的,希望高手给改成au3的,但是没人帮忙,于是看了下ahk的函数列表,发现直接有获取静音状态的函数,于是自己用ahk凑活着写了个exe来获取系统静音状态,就是这句代码SoundGet, master_mute, , mute但是怎么让我的au3程序来读取ahk获取到的静音状态呢,那就让ahk把读取到的状态写入注册表,然后au3去读,au3读完之后立即删除这个注册表。
所以au3想获取静音状态的话先运行一下那个ahk写的exe,然后去读注册表,然后删注册表。

sanmoking 发表于 2011-7-27 17:17:51

回复 6# happytc


    获取音量的我已经用那个Audio.au3的udf了,主要是这个udf用来获取系统静音状态的方法竟然是运行xp的音量程序sndvol32,然后读取静音的选择框是否打勾。。。。。实在太郁闷了,所以就想看是否有更好的方法来获取系统静音状态。

ahk就有直接的函数。

gzh888666 发表于 2011-7-27 21:51:51

ControlCommand("","",1000,"IsChecked")=1
这个可以用嘛?

powerofos 发表于 2011-7-27 23:40:55

回复 8# sanmoking



嘿嘿,我都不知道到我该不该说我想到的方法了...

之前用BASS.DLL编写过东西,当系统静音后,_BASS_GetVolume() 函数返回1。

这函数返回的音量值是 0 - 1, 所以还需要用你的方法检测是否是因为音量100%造成的返回值1。

杀鸡用牛刀!

{:face (394):}

sanmoking 发表于 2011-7-28 17:28:12

本帖最后由 sanmoking 于 2011-7-28 20:35 编辑

回复 9# gzh888666
这个不就是检测音量窗口静音的复选框是否勾选的代码么?
而且必须得先运行sndvol32.exe
或者手动打开音量调节窗口

ControlCommand("","",1000,"IsChecked")

>>>> 窗口 <<<<
标题:      主音量
类:      Volume Control
坐标:      338, 38
大小:      488, 279
样式:      0x14CA0044
扩展样式:0x00010100
句柄:      0x00180722

>>>> 控件 <<<<
类:      Button
接口:      2
类别名:      Button2
名称:      
高级(类):      
ID:      1000
文本:      全部静音(&M)
坐标:      6, 185
大小:      90, 15
控件点击坐标:21, 8
样式:      0x50010003
扩展样式:0x00000004
句柄:      0x00140896

ceoguang 发表于 2011-7-28 21:19:14

本帖最后由 ceoguang 于 2011-7-30 14:49 编辑


这是C++编译的,要转换成AUTOIT的话要写太多代码了,不过好像Audio.au3那个UDF都有相关结构体的定义.
页: [1]
查看完整版本: 如何通过api获取系统静音状态