Mixer: Mute-Status von Anwendungen auslesen

  • hi ..

    ich versuche seit einigen tagen den "mute-status" der anwendungen im lautstärkemixer auszulesen (also nicht das master-volume, das funzt über WinGetText).
    bislang leider ohne erfolg :(

    1. idee: tooltip-text auslesen und nach ": AnwendungsName" suchen (bekomme das tooltip-handle, kann es aber nicht in einen string umwandeln)
    2. idee: image/bitmap des buttons auslesen (aber mein bitmap-index ist immer null)

    all konstruktiven kommentare erwünscht :)

    Einmal editiert, zuletzt von UPIA (7. August 2012 um 22:54)

  • hi bugfix,
    danke für deine antwort,
    hab schon etliche zeilen von dir zu diesem thema durchgelesen :)
    leider brauch ichs für win7. klappt auch schon alles, bis auf die mute-states.

    bass.dll hab ich auch getestet, aber ohne erfolg.
    welche bass-funktion würde mir denn da weiterhelfen??

    • Offizieller Beitrag

    Mit der Bass habe ich noch nie gearbeitet.
    Habs jetzt mal auf die herkömmliche Weise versucht. Aber leider ist im Win7 Mixer keine Checkbox sondern ein Picture-Button zum Stummschalten.
    Hier mal eine seeehr schräge Variante :D, leider muss dazu dass Mixerfenster kurzzeitig sichtbar sein. Ich überprüfe hier, ob das rote Sperrsymbol (bei Mute) auf dem Button liegt.

    [autoit]

    ConsoleWrite(_IsMute('Windows Media Player') & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Func _IsMute($sApplication) ; gibt den Mute-Status zurück True=Mute
    Local $sTitle = "Lautstärkemixer"
    Local $oldOpt = Opt("WinTitleMatchMode", 2)
    Local $sText, $aWnd, $iTop, $iLeft, $aPos, $fReturn = True
    _SystemGetWindowBorder($iTop, $iLeft)
    $iPID = Run("sndvol")
    WinWaitActive($sTitle)
    $aWnd = WinGetPos($sTitle)
    For $i = 1 To 12
    $sText = ControlGetText($sTitle, '', '[CLASS:ToolbarWindow32; INSTANCE:' & $i & ']')
    If StringInStr($sText, $sApplication) Then
    $aPos = ControlGetPos($sTitle, '', '[CLASS:ToolbarWindow32; INSTANCE:' & $i & ']')
    PixelSearch($iLeft+$aPos[0]+$aWnd[0], $iTop+$aPos[1]+$aWnd[1], $iLeft+$aPos[0]+$aPos[2]+$aWnd[0], $iTop+$aPos[1]+$aPos[3]+$aWnd[1], 0xED0000, 50)
    If @error Then $fReturn = False
    ExitLoop
    EndIf
    Next
    Opt("WinTitleMatchMode", $oldOpt)
    ProcessClose($iPID)
    Return $fReturn
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    ;===============================================================================
    ; 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

    [/autoit]
  • .. ja das mit dem fenster oeffnen ist das problem (da mein applet für games ist und genau das verhindert werden soll).
    ausserdem wusste ich nicht ob man mit pixel-search das fenster scrollen muss/kann, wenn viele anwendungen da sind.
    EDIT... ja man muss scrollen/resizen, habs probiert ...
    wenigstens mal eine funktionierende möglichkeit den mute-status herauszufinden.

    soweit mal 1000 dank.
    :rock:

    EDIT2: nur der vollständigkeit halber ..
    ich habe die funktion für mehrere (max 24 andwendungen) so abgeändert

    Spoiler anzeigen

    thema lass ich mal offen, vielleicht hat ja noch jemand eine idee, wie das bei win7 ohne fensteröffnen geht ..
    die hoffnung stirbt nie :party:

    3 Mal editiert, zuletzt von UPIA (26. Juli 2012 um 14:00)

  • EDIT:

    Hab ne alternative Loesung gefunden und hier gepostet: https://autoit.de/index.php?page…9925#post259925

    Momentan verwende ich diese Version:
    + geht im versteckten fenster
    + findet alle Programme ohne Scroll/Resize
    - dauert 1 sekunde (bis der tooltip 'aufgeht')
    + der tooltip wird ausgelesen, bevor er sichtbar wird (kein flickern)

    Spoiler anzeigen
    [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Deutsches Windows
    Global $mixer_MuteStrPrefix = "Stummschaltung für "
    Global $mixer_MuteStrSuffix = " aufheben"
    Global $mixer_hwnd = "Lautstärkemixer" ; get this handle from $pID = Run(SndVol.exe) (international)

    [/autoit] [autoit][/autoit] [autoit]

    ; Mute Status ermitteln für ein Programm (nicht Master!)
    ; ------------------------------------------------------
    ; $pos = Nummer der App (Reihenfolge beachten)
    ; opt: $name = Name der App (oder Teil des Namens)
    ; Rückgabe: 0=mute, 1=laut, -1=undefiniert
    ; by UPIA

    [/autoit] [autoit][/autoit] [autoit]

    Func _AppGetMuteState($pos, $name='')
    Local $delay = 1000
    Local $ret = -1
    local $prefix = "[CLASS:ToolbarWindow32; INSTANCE:"
    local $suffix = "]"
    Local $str = ''
    Local $hToolBar = ControlGetHandle($mixer_hwnd, "", $prefix & String($pos*2) & $suffix)
    local $hToolTip = _GUICtrlToolbar_GetToolTips($hToolBar) ; tooltip/window handle
    ControlFocus($mixer_hwnd, "", $prefix & String($pos*2) & $suffix)
    Sleep($delay)
    For $i = 1 To 100 ; warten bis Tooltip oeffnet
    $str = WinGetTitle($hToolTip)
    If $str <> "" Then
    ExitLoop
    EndIf
    Sleep(10)
    Next
    If $str <> '' Then
    If StringInStr($str, $mixer_MuteStrPrefix) > 0 And StringInStr($str, $mixer_MuteStrSuffix) > 0 And StringInStr($str, $name) > 0 Then
    $ret = 0
    Else
    $ret = 1
    EndIf
    EndIf
    ControlFocus($mixer_hwnd, "", "[CLASS:SPD_GroupBox; INSTANCE:1]"); workaround für "UnFocus"
    Return $ret
    EndFunc

    [/autoit]

    ... den Namen, die Lautstärke und die ID der Apps beziehe ich so:
    (die letzte ID/Name ist immer das Standardgerät/Default Device - diesen MuteState kann man mit WinGetText() auslesen)

    Spoiler anzeigen
    [autoit]


    Func _MixerGetAll($ini=0)
    Local $cTrl_N_prefix = "[CLASS:Static; INSTANCE:"
    Local $cTrl_V_prefix = "[CLASS:msctls_trackbar32; INSTANCE:"
    Local $cTrl_suffix = "]"
    Local $apps[1][4] = [[0,0,0,0]]
    Local $index = 0
    While 1
    Local $name = ControlGetText($mixer_hwnd, "", $cTrl_N_prefix & ((3 * $index) + 2) & $cTrl_suffix)
    If $name = "" Then ExitLoop
    Local $vol = 100 - ( _GUICtrlSlider_GetPos( ControlGetHandle( $mixer_hwnd, "", ( $cTrl_V_prefix & ($index + 1) & $cTrl_suffix ) ) ) )
    $index += 1
    Local $id = $index
    ReDim $apps[$index+1][4]
    $apps[0][0] = $index
    $apps[$index][0] = StringStripWS($name, 3)
    $apps[$index][1] = $vol
    $apps[$index][2] = -1 ; wird später gesetzt
    $apps[$index][3] = $id
    WEnd
    EndFunc

    [/autoit]


    ORIGINAL:

    wow!!!,
    ich hab vieles schon aus deinen postings gelernt und die funktionen schon selbst gebastelt, aber natürlich nicht so schick
    ausserdem hab ich noch ein par andere sachen geproggt, die dazu gut passen ...
    1. Gerätenamen und Gerätezustand auslesen (Play und Rec Devices)
    2. mit 1. lässt sich auch das Master-Mute ermitteln indem man mit WinGetText den string ": DefaultPlayDevice" ermittelt, geht vielleicht auch nur mit ": " aber evtl. nicht eindeutig
    3. geräte (de)aktivieren
    4. geräte als standard / standardkomm setzen
    4b. gerätewechsel erzwingen (einfach nur indem man standard wechselt und das alte standard gerät kurz deaktiviert und wieder aktiviert (sinnvoll für games und andere progs)
    (5.) mute state für anwendungen auf "nicht gemutet" setzen wenn das volume geändert wurde (ich kann in meinem fall kein pixelsearch verwenden)
    ...
    ich kann das mal posten wenn du willst, bin aber grad noch dabei einige funktionen einheitlich umbenennen
    das ganze brauch ich für ein G-series LCD applet

    aber dafür bekommst du natürlich 2x :rock::rock:
    :thumbup:

    10 Mal editiert, zuletzt von UPIA (10. August 2012 um 13:22)