Sign in to follow this  
Followers 0
Dav1d

Program specific volume control (UDF)

5 posts in this topic

#1 ·  Posted (edited)

Tested to work under Win7. Should work with Vista as well.

Usage:

WinSetVolume("title", 50) - Set volume (0-100)

WinSetVolume("title", "mute") - Mute

WinSetVolume("title", "unmute") - Unmute

WinSetVolume("title", "toggle") - Toggles mute state

Returns 1 on success, 0 on failure.

Please note:

  • For non-English platforms you'll need to alter the $localized string (e.g. for Dutch: $localized = "Dempen voor ").
  • Setting the volume to 0 is not the same as muting.
  • This function doesn't respect the WinTitleMatchMode setting, it will always match titles as if in mode 1.

On how it functions:

  • The keypress after setting the slider's position is needed to trigger Windows to adjust the volume, otherwise it won't become effective. Just FYI, if you wondered.
  • Since there's no easy way to determine whether or not a given window is muted, the volume level is being re-set which results in unmuting (though it possibly already was), so we're certain of it's state. Afterwards it 'presses' the mute button, if applicable.

Any questions, bug reports or ideas are welcome. I appreciate if you let me know if this was of use to you.

#include <GuiConstantsEx.au3>
#include <GuiSlider.au3>

Func WinSetVolume($targetTitle, $targetVolume = "toggle")

    Const $localized = "Mute for "
    
    $currentActive = WinGetHandle("[active]")
    $mixerPid = Run(@SystemDir & "\SndVol.exe -r", "", @SW_HIDE)
    $mixerHandle = WinWaitActive("[CLASS:#32770]")
    WinActivate($currentActive)

    $iSlider = 1
    $iButton = 2

    While 1

        $currentButton = ControlGetText("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]")
        
        If @error Then
            ProcessClose($mixerPid)
            Return 0
        ElseIf StringInStr($currentButton, $localized & $targetTitle, 1) = 1 Then
        
            If NOT ($targetVolume == "toggle") Then
            
                $sliderHandle = ControlGetHandle("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]")
                
                If IsInt($targetVolume) Then
                    $setVolume = -($targetVolume-100)
                Else
                    $setVolume = _GUICtrlSlider_GetPos($sliderHandle)
                EndIf
            
                If $setVolume < 100 Then
                    _GUICtrlSlider_SetPos($sliderHandle, $setVolume+1)
                    ControlSend("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]", "{UP}")
                Else
                    _GUICtrlSlider_SetPos($sliderHandle, $setVolume-1)
                    ControlSend("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]", "{DOWN}")
                EndIf
            
            EndIf
            
            If $targetVolume == "toggle" OR $targetVolume == "mute" Then ControlCommand("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]", "SendCommandID", 305)

            WinClose($mixerHandle)
            Return 1

        EndIf
        
        $iSlider += 1
        $iButton += 2        

    WEnd

EndFunc
Edited by Dav1d
1 person likes this

Share this post


Link to post
Share on other sites



Wow!

Looks really useful! I'll use this some time!

Share this post


Link to post
Share on other sites

Very cool find. I didn't know you could set the volume for apps individually. This actually helps with my Soundblaster X-Fi's screwed up Dolby Digital and DTS encoding (for some reason normal sound is extremely overdriven, and everything needs to be turned way down in volume).

Share this post


Link to post
Share on other sites

Very useful... exactly what I needed.

I did notice one slight problem. If there's no match for $targetTitle, the function will loop infinitely.

There's an easy fix, of course. I just added

If $currentButton = "" Then Return 0

below

$currentButton = ControlGetText("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]")

and it's good to go.

Thanks for the UDF!

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

OK, that wasn't quite right. I forgot to shut down the instance of SndVol.exe

Here's the UDF, corrected and complete.

Again, thanks!

TAC

#include <GuiConstantsEx.au3>
#include <GuiSlider.au3>

Func WinSetVolume($targetTitle, $targetVolume = "toggle")

    Const $localized = "Mute for "

    $currentActive = WinGetHandle("[active]")
    $mixerPid = Run(@SystemDir & "\SndVol.exe -r", "", @SW_HIDE)
    $mixerHandle = WinWaitActive("[CLASS:#32770]")
    WinActivate($currentActive)

    $iSlider = 1
    $iButton = 2

    While 1

        $currentButton = ControlGetText("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]")

        If @error Then
            ProcessClose($mixerPid)
            Return 0
        ElseIf $currentButton = "" Then ;this ElseIf prevents infinite loop if no matching $targetTitle
            WinClose($mixerHandle)
            Return 0
        ElseIf StringInStr($currentButton, $localized & $targetTitle, 1) = 1 Then

            If NOT ($targetVolume == "toggle") Then

                $sliderHandle = ControlGetHandle("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]")

                If IsInt($targetVolume) Then
                    $setVolume = -($targetVolume-100)
                Else
                    $setVolume = _GUICtrlSlider_GetPos($sliderHandle)
                EndIf

                If $setVolume < 100 Then
                    _GUICtrlSlider_SetPos($sliderHandle, $setVolume+1)
                    ControlSend("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]", "{UP}")
                Else
                    _GUICtrlSlider_SetPos($sliderHandle, $setVolume-1)
                    ControlSend("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]", "{DOWN}")
                EndIf

            EndIf

            If $targetVolume == "toggle" OR $targetVolume == "mute" Then ControlCommand("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]", "SendCommandID", 305)

            WinClose($mixerHandle)
            Return 1

        EndIf

        $iSlider += 1
        $iButton += 2

    WEnd

EndFunc
Edited by tcurran

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0