- Offizieller Beitrag
Seit Windows Vista verwaltet Windows im Soundmixer für jede Anwendung einen einzelnen Slider. Dadurch sind aber auch unsere ganzen Tools zur Lautstärkeregelung hinfällig.
Ich habe auch bisher keine Möglichkeit entdeckt, per DLL auf diese Regelung zuzugreifen.
Also habe ich auf die Wurzeln zurückgegriffen, mich durch die Childs und Child-Childs im Mixer gewühlt um an die Slider-Handle zu kommen. Diese sind sinnigerweise ohne Text und daher nicht direkt mit der Anwendung in Verbindung zu bringen. Aber über das darunter liegende Ctrl (Button für Stummschaltung) ist der Anwendungsname zu ermitteln und durch Positionsvergleich auch zuzuordnen.
Somit ist es nun möglich diese Slider auszulesen und auch zu setzen.
Das Mastervolume habe ich im Moment noch aussen vor, da kümmere ich mich später mal drum.
Edit: Habe gerade einen Fehler entdeckt, ProcessClose() killt leider nicht den Soundvolume-Prozess. Mal schauen, wie sich das ändern läßt.
Dadurch läßt sich der Mixer nicht per Klick auf das Lautsprechersymbol öffnen, da er bereits offen aber HIDE ist.
Funktionen:
_Win7_AppSoundGetApps
Ermittelt die anwendungspezifischen Slider im Soundmixer (Handle Slider + Anwendungsname)
_Win7_AppSoundRefresh
Aktualisieren der Anwendungen / Handle
_Win7_AppSoundGet
Gibt die lineare Position des Sliders zurück (0-100)
_Win7_AppSoundSet
Setzt die lineare Position des Sliders (0-100)
Win/_Sound.au3
#Region - TimeStamp
; 2012-07-26 23:34:55 v 0.1
#EndRegion - TimeStamp
#include-once
#include <GuiSlider.au3>
#include <WinAPI.au3>
OnAutoItExitRegister('_CloseSound')
[/autoit] [autoit][/autoit] [autoit]Global $__aSound_Apps = _Win7_AppSoundGetApps()
Global $__aSound_iPID
;===============================================================================
; Function Name....: _Win7_AppSoundGet
; Description......: Gibt die lineare Position des Sliders zurück (0-100)
; .................: für übergebenes Sliderhandle oder Anwendungsname
; Parameter(s).....: $hSlider Handle des Slider (aus _Win7_GetApps)
; .................: $sApp Name der Anwendung (aus _Win7_GetApps)
; Return Value(s)..: Linearer Wert des Sliders
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _Win7_AppSoundGet($hSlider=-1, $sApp='Systemsounds')
For $i = 0 To UBound($__aSound_Apps) -1
If $hSlider = -1 Then
If $__aSound_Apps[$i][1] = $sApp Then
Return 100 - _GUICtrlSlider_GetPos($__aSound_Apps[$i][0])
EndIf
Else
Return 100 - _GUICtrlSlider_GetPos($hSlider)
EndIf
Next
EndFunc ;==>_Win7_AppSoundGet
;===============================================================================
; Function Name....: _Win7_AppSoundSet
; Description......: Setzt die lineare Position des Sliders (0-100)
; .................: für übergebenes Sliderhandle oder Anwendungsname
; Parameter(s).....: $iVal der zu setzende Wert
; .................: $hSlider Handle des Slider (aus _Win7_GetApps)
; .................: $sApp Name der Anwendung (aus _Win7_GetApps)
; Return Value(s)..: keiner
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _Win7_AppSoundSet($iVal, $hSlider=-1, $sApp='Systemsounds')
For $i = 0 To UBound($__aSound_Apps) -1
If $hSlider = -1 Then
If $__aSound_Apps[$i][1] = $sApp Then
_GUICtrlSlider_SetPos($__aSound_Apps[$i][0], 100 - $iVal)
EndIf
Else
_GUICtrlSlider_SetPos($hSlider, 100 - $iVal)
EndIf
Next
EndFunc ;==>_Win7_AppSoundSet
;===============================================================================
; Function Name....: _Win7_AppSoundRefresh
; Description......: Aktualisieren der Anwendungen / Handle
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _Win7_AppSoundRefresh()
$__aSound_Apps = _Win7_AppSoundGetApps()
EndFunc ;==>_Win7_AppSoundRefresh
;===============================================================================
; Function Name....: _Win7_AppSoundGetApps
; Description......: Ermittelt die anwendungspezifischen Slider im Soundmixer
; Parameter(s).....: keine
; Requirement(s)...: OS Vista oder höher
; Return Value(s)..: 2D-Array [[Handle-Slider, Name Anwendung]]
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _Win7_AppSoundGetApps()
Local Const $GW_CHILD = 5
Local Const $GW_HWNDNEXT = 2
$__aSound_iPID = Run("sndvol", @WorkingDir, @SW_HIDE)
Local $hMixer = WinWait("Lautstärkemixer")
Local $oldOpt = Opt("WinTitleMatchMode", 2)
Opt("WinTitleMatchMode", $oldOpt)
Local $iTop, $iLeft, $aPos
_SystemGetWindowBorder($iTop, $iLeft)
Local $iInst = 2, $aWnd = WinGetPos("Lautstärkemixer")
Local $sText = StringReplace(ControlGetText("Lautstärkemixer", '', '[CLASS:ToolbarWindow32; INSTANCE:' & $iInst & ']'), 'Stumm für ', '')
Local $sApp
While $sText <> ""
$aPos = ControlGetPos("Lautstärkemixer", '', '[CLASS:ToolbarWindow32; INSTANCE:' & $iInst & ']')
$sApp &= $iLeft+$aPos[0]+$aWnd[0] & ',' & $iLeft+$aPos[0]+$aPos[2]+$aWnd[0] +5 & '|' & $sText & @LF
$iInst += 2
$sText = StringReplace(ControlGetText("Lautstärkemixer", '', '[CLASS:ToolbarWindow32; INSTANCE:' & $iInst & ']'), 'Stumm für ', '')
WEnd
Local $aTmp = StringSplit(StringTrimRight($sApp, 1), @LF), $aSplit
Local $aApp[$aTmp[0]][2]
For $i = 1 To $aTmp[0]
$aSplit = StringSplit($aTmp[$i], '|')
$aApp[$i-1][0] = $aSplit[1]
$aApp[$i-1][1] = $aSplit[2]
Next
Local $hChildMix = _WinAPI_GetWindow($hMixer, $GW_CHILD)
Local $hAppsOuter = _WinAPI_GetWindow($hChildMix, $GW_HWNDNEXT)
Local $hAppsInner = _WinAPI_GetWindow($hAppsOuter, $GW_CHILD)
Local $aHWnd[$aTmp[0]][2]
Local $hTmp = _WinAPI_GetWindow($hAppsInner, $GW_CHILD)
Local $hSub, $n = 0, $i = 0, $aRange
While $hTmp <> 0x00000000
$aHWnd[$i][0] = $hTmp
$hTmp = _WinAPI_GetWindow($hTmp, $GW_HWNDNEXT)
$i += 1
WEnd
For $i = 0 To $aTmp[0] -1
$hSub = _WinAPI_GetWindow($aHWnd[$i][0], $GW_CHILD)
$n = 0
While $hSub <> 0x00000000
$n += 1
If $n = 5 Then
$aHWnd[$i][0] = $hSub
$tRect = _WinAPI_GetWindowRect($hSub)
$aHWnd[$i][1] = DllStructGetData($tRect, 3)
For $j = 0 To $aTmp[0] -1
$aRange = StringSplit($aApp[$j][0], ',')
If $aHWnd[$i][1] > $aRange[1] And $aHWnd[$i][1] < $aRange[2] Then
$aHWnd[$i][1] = $aApp[$j][1]
ExitLoop
EndIf
Next
ExitLoop
EndIf
$hSub = _WinAPI_GetWindow($hSub, $GW_HWNDNEXT)
WEnd
Next
Return $aHWnd
EndFunc ;==>_Win7_AppSoundGetApps
Func _CloseSound()
ProcessClose($__aSound_iPID)
EndFunc
;===============================================================================
; Function Name....: _SystemGetWindowBorder
; Description......: Calculates side and top border of window
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _SystemGetWindowBorder(ByRef $_iTopBorder, ByRef $_iSideBorder)
Local Const $SM_CYCAPTION = 4, $SM_CYEDGE = 46, $SM_CYBORDER = 6, $SM_CXBORDER = 5, $SM_CXEDGE = 45
Local $aMetrics[5][2] = [[$SM_CYCAPTION], [$SM_CYEDGE], [$SM_CYBORDER], [$SM_CXBORDER], [$SM_CXEDGE]]
Local $dll = DllOpen("user32.dll"), $aRet
For $i = 0 To 4
$aRet = DllCall($dll, "int", "GetSystemMetrics", "int", $aMetrics[$i][0])
If IsArray($aRet) Then $aMetrics[$i][1] = $aRet[0]
Next
DllClose($dll)
$_iTopBorder = $aMetrics[0][1] + $aMetrics[1][1] + $aMetrics[2][1]
$_iSideBorder = $aMetrics[3][1] + $aMetrics[4][1]
EndFunc ;==>_SystemGetWindowBorder