KaFu

SSD - Set Sound Device [Updated 2016-Aug-30]

39 posts in this topic

#1 ·  Posted (edited)

SSD - Set Sound Device

160830_SSD_v3.jpg

Current Version: v3 (2016-Aug-30)

Windows XP allows you to output sound to more than one audio device... Vista and newer Windows versions do not. To overcome this "Failure by Design", (IMHO somehow related to DRM, preventing user to make digital copies of analog sources), I have coded SSD - Set Sound Device.

SSD enables you to change the default Sound Device by shortcut or command line.

It works fine on my Win10 64bit machine. If you find bugs please let me know.

The source and executable can be downloaded from my site: http://www.funk.eu

Kudos to Ascend4nt and NerdFencer for parts of the code, and Yashied for his most excellent WinAPIEx UDF.

Enjoy ;)...

Edited by KaFu
1 person likes this

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

As an aside note, applets are (should be) accessible to us thru DllCall function.

DllCall($sApplet, "long", "CPlApplet", "hwnd", $hGUI, "dword", $CPL_STARTWPARMSW, "lparam", 0, "wstr", "0")
;       ^^Applet           ^^Function          ^^Parent        ^^Message to send           ^^Dialog    ^^Tab number (or name)

For example:

Global Const $CPL_STARTWPARMSW = 10
Global $hGUI = GUICreate("Test")
GUISetState()
DllCall("mmsys.cpl", "long", "CPlApplet", "hwnd", $hGUI, "dword", $CPL_STARTWPARMSW, "lparam", 0, "wstr", "0")
While 1
    If GUIGetMsg() = -3 Then Exit
WEnd

But in your case that doesn't play since you automate that window. Nevertheless you can do something like this (to keep things in the house):

Global $hGUI = GUICreate("Test")
GUISetState()
Global $iPid = Run('"' & @AutoItExe & '" /AutoIt3ExecuteLine  "DllCall(''mmsys.cpl'', ''long'', ''CPlApplet'', ''hwnd'', ''0'', ''dword'', ''10'',''lparam'', ''0'', ''wstr'', ''0'')"')
While 1
    If GUIGetMsg() = -3 Then Exit
WEnd

...or even cooler, make another thread.

There is also Shell.Application ControlPanelItem method available for that. Only it takes just one parameter meaning you can't select tab other than default for that applet.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

This should work there too:

Global Const $CPL_DBLCLK = 5 
DllCall("mmsys.cpl", "long", "CPlApplet", "hwnd", $hGUI, "dword", $CPL_DBLCLK, "lparam", 0, "lparam", 0)


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Updated to Version 1.1. Hell, this happens if you disable UAC :x, never noticed that #AutoIt3Wrapper_Res_requestedExecutionLevel=highestAvailable will always prompt a UAC request, changed to #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker which works just as fine (without the UAC prompt crap).

Share this post


Link to post
Share on other sites

Strange how this useful app didn't show up on Google search. I found many other half baked attempts to automate this control so I thank you for this as I will put it to good use.

Share this post


Link to post
Share on other sites

I would like for feature request, just one bottom that generates all the soundcards as shortcut instead of having to select them all and then make shortcuts one by one :graduated:.

Exellecnt tool Thumbs up!.

Btw i noticed sometimes when using the program im having a hard time selecting other things at my taskbar. I have to use the function built into windows "Show desktop" twice before everything is running again smooth.

Share this post


Link to post
Share on other sites

I'm currently working on this on again, so your request came to the right time and has already been added :graduated:.

Additionally I've added the possibility to perform the switch on a secondary (hidden) desktop. This feature is somewhat experimental at the moment and some testing and feedback would be nice.

I'm not sure what might be the problem with the taskbar. I've reviewed the source for possible flaws but couldn't find any connection to the desktop or taskbar. Maybe someone else figures out what's going wrong ;).

Heres to source of the most recent Beta for testing:

SSD - SetSoundDevice_v1107.zip

Share this post


Link to post
Share on other sites

Great app I've been using it for a lot of time.

Feature Request: set device by name and not number since I reconnect devices all the time!

Share this post


Link to post
Share on other sites

Thanks for the feedback :graduated:! Hmmm, that would require the application to be complied in line with the OS, reading the content of the sound panel listview on a 64bit OS requires a 64bit program and on a 32bit OS it requires a 32bit program. I've done that with a wrapper in an older release of SSD, maybe I have to re-implement the wrapper to read the listview again, I'll take it to the list and we'll see ;)...

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

One more thing that would be really helpfull is an ssd for recording devices.

Perform the same things that ssd does now but on the recording tab of the sound panel with a parameter.

I need this because I swap between my desktop and my projector-htpc with xbox gamepad and headset and I'd like to instachange between recording from xbox controller headset or from mic on my PC

Edited by Vrokolos

Share this post


Link to post
Share on other sites

Hi, it's usefull tool, I was looking for it long time (google didn't help).

Just one small issue: GUI doesn't display correctly on my 120dpi desktop.

Share this post


Link to post
Share on other sites

Hi there,

I have a feature request, or just help will work too, my autoit skills are VERY rusty.

My problem:

I have a HTPC hooked up to my tv via hdmi

When I switch out to cable and then(after awhile) back to htpc the sound device has disabled itself due to some sort of keep alive detection that a year of googling has left me wanting to solve.

So, when this happens I have to right click on the sound icon and bring up the window, windows then automatically re-enables the hdmi default sound device and I close the window, back in business.

This is extremely irritating as I have to get my ass up out of my chair and perform this ritual.

To make it a little easier I have put in the following script...

Opt("TrayIconHide", 1)
HotKeySet("{F10}", "refreshIt")
While 1
    Sleep(300)
WEnd
Func refreshIt()
    Run("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0")
    WinWait("Sound", "Select a playback")
sleep(2000)
    WinClose("Sound", "Select a playback") 
EndFunc

This is not related to windows sleeping as I have that all set to "Never".

What would be great is if I can detect that the hdmi device is disabled and re-enable it without having to do it manually. thoughts?

Share this post


Link to post
Share on other sites

What would be great is if I can detect that the hdmi device is disabled and re-enable it without having to do it manually. thoughts?

You could use parts of the SSD script to read out the listview of the sound window and detect the state, but for this task SSD opens the sound window anyway, so there is no difference in using your script for refreshing or using SSD which will do the job anyway by just reading out the states.


Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Anyway i wanted to share a little mod.

I wanted to add a commandline param to switch between given Device numbers:

Format:
 SSD.exe sw{DeviceNumber1}|{DeviceNumber2}|{DeviceNumber3} ...

Example:
 SSD.exe sw1|3

Have Fun ;)

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=ssd_logo.ico
#AutoIt3Wrapper_Outfile=SSDsw.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Comment=© SSD - SetSoundDevice on Win7 by KaFu. All rights reserved. http://www.funk.eu
#AutoIt3Wrapper_Res_Description=SetSoundDevice on Vista & Win7
#AutoIt3Wrapper_Res_Fileversion=1.1.0.1
#AutoIt3Wrapper_Res_LegalCopyright=Creative Commons License "by-nc-sa 3.0", this program is freeware under Creative Commons License "by-nc-sa 3.0" (http://creativecommons.org/licenses/by-nc-sa/3.0/us/)
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
://////=__=
://////=__=
://////=__=
://////=__=
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#cs
    ######################################

    SSD - SetSoundDevice on Win7
    Script Version: 1.1.0.0
    KaFu 2010
    15 Jan 2011

    AutoIt Version: 3.3.6.1

    ######################################
#ce

#region ;----- Includes -----

_EnforceSingleInstance('3681182c-6d24-4558-b089-1fedb289d81c') ; any 'unique' string; created with http://www.guidgen.com/Index.aspx

#include <Winapi.au3>
#include <_EnumChildWindows.au3>
#include <_GetPlatformCompatabillity.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>
#include <Misc.au3>

Global $sGUITitle = "SSD - SetSoundDevice on Win7 - v1.1"

If $i_PlatformCompatabillity < $Macro_Sys2008 Then
    MsgBox(16 + 262144, $sGUITitle & " - Info", "SSD works on Win7 (maybe Vista, but untested) only.")
    Exit
EndIf

#cs
If @AutoItX64 = 0 Then
    $sGUITitle &= " - 32bit"
Else
    $sGUITitle &= " - 64bit"
EndIf
#ce

Global $hWnd_Sound, $iPID_Sound, $timer_timeout, $iDeviceNo = 0

If $CmdLine[0] > 0 Then
    $iDeviceNo = $CmdLine[1]
EndIf

;~ $iDeviceNo = "sw1|3"

$timer_timeout = TimerInit()
While ProcessExists("rundll32.exe")
    ProcessClose("rundll32.exe")
    If TimerDiff($timer_timeout) > 5000 Then _Exit_Error()
    Sleep(250)
WEnd

$iPID_Sound = Run("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0")

$timer_timeout = TimerInit()
While Not IsHWnd($hWnd_Sound)
    $hWnd_Sound = _Detect_Sound_dialog_hWnd($iPID_Sound)
    If TimerDiff($timer_timeout) > 5000 Or Not ProcessExists($iPID_Sound) Then
        _Exit()
    EndIf
WEnd

$aEnumList = _EnumChildWindows($hWnd_Sound, 0, 0, "SysListView32")
If $aEnumList[0][0] = 1 Then
    If StringLeft($iDeviceNo,2) = "sw" And WinExists($hWnd_Sound) Then

        $aSw = StringSplit(StringTrimLeft($iDeviceNo,2),"|",3)
        If @error = 0 And UBound($aSw) > 1 Then

            $iListviewSize = ControlListView($aEnumList[1][0], "", 0, "GetItemCount")
            If Not ($iListviewSize > 0) Then
                MsgBox(16 + 262144, $sGUITitle & " - Error", "No rows found in SysListView32 control of the 'Sound' control panel dialog.")
                _Exit()
            EndIf
            For $i = 0 To $iListviewSize - 1
                If StringInStr(ControlListView($aEnumList[1][0], "", 0, "GetText", $i, 2), "Standard") Then
                    $i+= 1
                    If $i > UBound($aSw) - 1 Then $i = 0
                    ControlSend($hWnd_Sound, "", "", "{DOWN " & $aSw[$i] & "}")
                    ControlClick($hWnd_Sound, "", "Button2")
                    ControlClick($hWnd_Sound, "", "Button4")
                EndIf
            Next

        else
            MsgBox(16 + 262144, $sGUITitle & " - Error", "Switch command string badly formatted: "&$iDeviceNo&@CRLF&"Format: sw{DeviceNumber1}|{DeviceNumber1}"& @CRLF& "Example: SSD.exe sw1|3" )
        EndIf

    ElseIf $iDeviceNo = 0 Then
        $iListviewSize = ControlListView($aEnumList[1][0], "", 0, "GetItemCount")
        If Not $iListviewSize > 0 Then
            MsgBox(16 + 262144, $sGUITitle & " - Error", "No rows found in SysListView32 control of the 'Sound' control panel dialog.")
            _Exit()
        EndIf
        Dim $aSoundDevices[$iListviewSize]
        For $i = 0 To $iListviewSize - 1
            For $y = 0 To 2
                $aSoundDevices[$i] &= ControlListView($aEnumList[1][0], "", 0, "GetText", $i, $y)
                If $y < 2 Then $aSoundDevices[$i] &= ", "
            Next
            ConsoleWrite($aSoundDevices[$i] & @CRLF)
        Next

        GUICreate($sGUITitle, 400, 180)
        GUISetBkColor(0xffffff)

        GUICtrlCreateIcon(@ScriptName, 0, 6, 4, 32, 32)
        GUICtrlCreateLabel("SSD - SetSoundDevice on Win7", 45, 9, 380, 20)
        GUICtrlSetFont(-1, 14, 800, 0, "Arial", 6)

        $c_label_Hyperlink_FunkEu = GUICtrlCreateLabel("http://www.funk.eu", 285, 29, 98, 17)
        GUICtrlSetColor($c_label_Hyperlink_FunkEu, 0xA7A6AA)
        GUICtrlSetFont($c_label_Hyperlink_FunkEu, 8.5, 400, 4, "Arial")
        GUICtrlSetColor($c_label_Hyperlink_FunkEu, 0x518CB8)
        GUICtrlSetCursor($c_label_Hyperlink_FunkEu, 0)

        GUICtrlCreateLabel("SSD enables you to change the default Sound Device for Vista && Win7 via the commandline. To call SSD from the commandline, the syntax is 'SSD.exe #' (where # is the number of the Sound Device to select from the list,'Select Default' dropdown box must be enabled to make device selectable). Select Sound Device # to set as default:", 10, 10 + 40, 372, 70)
        GUICtrlSetFont(-1, 8.5, 400, 0, "Arial")
        $c_combo_devices = GUICtrlCreateCombo("", 10, 82 + 43, 380, 20, $CBS_DROPDOWNLIST)
        For $i = 0 To UBound($aSoundDevices) - 1
            GUICtrlSetData($c_combo_devices, $aSoundDevices[$i])
        Next
        For $i = 0 To UBound($aSoundDevices) - 1
            If StringInStr($aSoundDevices[$i], "Standard") Then GUICtrlSetData($c_combo_devices, $aSoundDevices[$i])
        Next

        $c_checkbox_create_shortcut = GUICtrlCreateCheckbox("Create shortcut in program directory", 10, 113 + 40, 190)
        GUICtrlSetFont(-1, 8.5, 400, 0, "Arial")
        GUICtrlSetState(-1, $GUI_CHECKED)

        $c_button_start = GUICtrlCreateButton("Change Default Sound Device", 212, 114 + 40, 180, 20)
        GUICtrlSetFont(-1, 8.5, 400, 0, "Arial")

        $h_DLL_User32 = DllOpen("User32.dll")
        OnAutoItExitRegister("_OnAutoitExitSSD")

        GUIRegisterMsg($WM_COMMAND, "My_WM_COMMAND")
        GUISetState(@SW_SHOW)

        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    GUIDelete()
                    _Exit()
                Case $c_button_start
                    ExitLoop
            EndSwitch
            If Not WinExists($hWnd_Sound) Then _Exit()
        WEnd
        For $i = 0 To UBound($aSoundDevices) - 1
            If GUICtrlRead($c_combo_devices) = $aSoundDevices[$i] Then
                $iDeviceNo = $i + 1
                If GUICtrlRead($c_checkbox_create_shortcut) = $GUI_CHECKED Then
                    FileCreateShortcut(@ScriptDir & "" & @ScriptName, @ScriptDir & "SSD - #" & $iDeviceNo & " " & StringLeft($aSoundDevices[$i], StringInStr($aSoundDevices[$i], ", ") - 1) & ".lnk", @ScriptDir, $iDeviceNo, "SSD commandline shortcut", @ScriptDir & "" & @ScriptName, "", "0", @SW_MINIMIZE)
                EndIf
            EndIf
        Next
        GUIDelete()
    ElseIf $iDeviceNo > 0 And WinExists($hWnd_Sound) Then
        ControlSend($hWnd_Sound, "", "", "{DOWN " & $iDeviceNo & "}")
        ControlClick($hWnd_Sound, "", "Button2")
        ControlClick($hWnd_Sound, "", "Button4")
    EndIf
Else
    MsgBox(16 + 262144, $sGUITitle & " - Error", "SysListView32 control in 'Sound' control panel dialog not found.")
EndIf

_Exit()

Func _Detect_Sound_dialog_hWnd($iPID)
    Local $hWnds = WinList("[CLASS:#32770;]", "")
    For $i = 1 To $hWnds[0][0]
        If BitAND(WinGetState($hWnds[$i][1], ''), 2) Then
            If WinGetProcess(_WinAPI_GetAncestor($hWnds[$i][1], $GA_ROOTOWNER)) = ProcessExists($iPID) Then
                Return $hWnds[$i][1]
            EndIf
        EndIf
    Next
    Return 0
EndFunc   ;==>_Detect_Sound_dialog_hWnd

Func _EnforceSingleInstance($GUID_Program)
    If $GUID_Program = "" Then Return SetError(1, '', 1)
    If IsHWnd(WinGetHandle($GUID_Program)) Then ProcessClose(WinGetProcess(WinGetHandle($GUID_Program), ""))
    AutoItWinSetTitle($GUID_Program)
    Return WinGetHandle($GUID_Program)
EndFunc   ;==>_EnforceSingleInstance

Func _Exit()
    $timer_timeout = TimerInit()
    While ProcessExists($iPID_Sound)
        ProcessClose($iPID_Sound)
        If TimerDiff($timer_timeout) > 5000 Then
            _Exit_Error()
        EndIf
        Sleep(250)
    WEnd
    Exit
EndFunc   ;==>_Exit

Func _Exit_Error()
    If Not ProcessExists($iPID_Sound) Then
        If ProcessExists("rundll32.exe") Then $iPID_Sound = ProcessExists("rundll32.exe")
    EndIf
    If ProcessExists($iPID_Sound) Then MsgBox(16 + 262144, $sGUITitle & " - Error", "The process rundll32.exe with the PID " & $iPID_Sound & "could not be closed by SSD." & @CRLF & @CRLF & "SSD will exit now, close the process via Taskmanager.")
    Exit
EndFunc   ;==>_Exit_Error

Func _OnAutoitExitSSD()
    DllClose($h_DLL_User32)
EndFunc   ;==>_OnAutoitExitSSD

Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iIDFrom = BitAND($wParam, 0xFFFF) ;LoWord
    Local $iCode = BitShift($wParam, 16) ;HiWord

    Switch $iIDFrom

        Case $c_label_Hyperlink_FunkEu
            GUICtrlSetColor($c_label_Hyperlink_FunkEu, 0xFF0000)
            While _IsPressed("01", $h_DLL_User32)
                Sleep(10)
            WEnd
            GUICtrlSetColor($c_label_Hyperlink_FunkEu, 0x518CB8)
            ShellExecute('http://www.funk.eu/')

    EndSwitch
EndFunc   ;==>MY_WM_COMMAND
Edited by qsek

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

I am looking for a solution for cycling through my output options with a single button on my HTPC remote. (Analog, HDMI, VAC)

Is there a way to modify the source to have a toggle mode? (if 1 then 2, if 2 then 3, if 3 then 1)

something like SSD.exe toggle

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

Really love the idea behind this code but made some tweaks that I hope some may like. My rewrite uses the friendly device name instead of an index value and I've removed all GUI components. It's purely meant for passing in switches. I just create a shortcut with command line similar to this:

"SetSoundDevice.exe "Digital Audio (S/PDIF)" "5.1 Surround"

And it not only sets the default device but it also set the appropriate speaker configuration through the Speaker Setup wizard. This is super important for those of us that flip back and forth between headphones and a surround sound.

Here's a screenshot of my Sound applet in case anyone is wondering.

post-27559-0-43185600-1352018920_thumb.j

My formatting is going haywire when I paste in. Here's the .au3 attached.

SetSoundDevice.au3

Anyway, here's the code:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=ssd_logo.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Winapi.au3>
#include <GuiListBox.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
Global $hWnd_Sound, $iPID_Sound, $timer_timeout
$sDefaultDevice = ""
$sSpeakerConfig = ""
If $CmdLine[0] > 1 Then
$sDefaultDevice = $CmdLine[1]
$sSpeakerConfig = $CmdLine[2]
Else
;No command line parameters
_Exit()
EndIf
;No valid parameters were passed
If StringLen($sDefaultDevice) = 0 Or StringLen($sSpeakerConfig) = 0 Then _Exit()
;Only one instance allowed
If _Singleton("SetSoundDevice", 1) = 0 Then
MsgBox(0, "Warning", "An occurence of the script is already running")
Exit
EndIf
;Open Sound control panel applet
$iPID_Sound = Run("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,0", @SystemDir)
$timer_timeout = TimerInit()
While Not IsHWnd($hWnd_Sound)
$hWnd_Sound = _Detect_Sound_dialog_hWnd($iPID_Sound)
If TimerDiff($timer_timeout) > 10000 Or Not ProcessExists($iPID_Sound) Then ;modified to 10 second timeout
_Exit()
EndIf
WEnd
;Set listview selection
If Set_SysListView32_Selection($sDefaultDevice) Then
;success
If WinExists($hWnd_Sound) Then ControlClick($hWnd_Sound, "", "Button2")
Sleep(200)
Else
;failure
MsgBox(0, "", 'Unable to properly select the Default device, error#:' & @error)
;check @error value for details
_Exit_Error()
EndIf
;Configure the speakers
;Start the speaker setup wizard, click the 'Configure' button
If Set_SysListView32_Selection("Speakers") Then
;success
If WinExists($hWnd_Sound) Then ControlClick($hWnd_Sound, "", "Button1")
Sleep(300)
Else
;failure
MsgBox(0, "", 'Unable to properly select the "Speakers" device, error#:' & @error)
;check @error value for details
_Exit_Error()
EndIf
$hWnd_SpeakerConfig = WinGetHandle("Speaker Setup")
If @error Then _Exit_Error()
;Configure audio channels
If Set_Speaker_Config($hWnd_SpeakerConfig, $sSpeakerConfig) Then
;success
Sleep(200)
If WinExists($hWnd_SpeakerConfig) Then
While 1
If ControlCommand($hWnd_SpeakerConfig, "", "Button2", "IsVisible", "") Then
ControlClick($hWnd_SpeakerConfig, "", "Button2")
ExitLoop
Else
ControlClick($hWnd_SpeakerConfig, "", "Button1")
EndIf
Sleep(200)
WEnd
EndIf
Sleep(500)
Else
;failure
MsgBox(0, "", "Unable to properly select the audio channels, error#:" & @error)
;check @error value for details
EndIf
;Click OK to close Sound applet
If WinExists($hWnd_Sound) Then ControlClick($hWnd_Sound, "", "Button4")
Exit

Func Set_Speaker_Config($hWnd, $sAudioChannels)
Local $iItemCount = 0, $aWindows, $hWnd_ListBox, $sText = ""
;Enumerate the main listview
$aWindows = _WinAPI_EnumWindows(1, $hWnd)
If @error Then Return SetError(1)
For $x = 1 To $aWindows[0][0]
If $aWindows[$x][1] = "ListBox" Then
$hWnd_ListBox = $aWindows[$x][0]
ExitLoop
EndIf
Next
If Not IsHWnd($hWnd_ListBox) Then Return SetError(2)
;Get count of listview items
$iItemCount = _GUICtrlListBox_GetCount($hWnd_ListBox)
If Not $iItemCount > 0 Then Return SetError(3)
;Loop through items, set selection, set as default device
For $x = 0 To $iItemCount-1
$sText = ""
$sText = _GUICtrlListBox_GetText($hWnd_ListBox, $x)
If $sText = $sAudioChannels Then
;~ If _GUICtrlListBox_SetCurSel($hWnd_ListBox, $x) Then ;not working
If _GUICtrlListBox_ClickItem($hWnd_ListBox, $x) Then
;success
Return 1
Else
;failure
Return SetError(@error)
EndIf
EndIf
Next
EndFunc
Func Set_SysListView32_Selection($sSelection_Text)
Local $iItemCount = 0, $aWindows, $hWnd_ListView, $sText = ""
;Enumerate the main listview
$aWindows = _WinAPI_EnumWindows(1, $hWnd_Sound)
If @error Then Return SetError(1)
For $x = 1 To $aWindows[0][0]
If $aWindows[$x][1] = "SysListView32" Then
$hWnd_ListView = $aWindows[$x][0]
ExitLoop
EndIf
Next
If Not IsHWnd($hWnd_ListView) Then Return SetError(2)
;Get count of listview items
$iItemCount = _GUICtrlListView_GetItemCount($hWnd_ListView)
If Not $iItemCount > 0 Then Return SetError(3)
;Loop through items, set selection, set as default device
For $x = 0 To $iItemCount-1
$sText = ""
$sText = _GUICtrlListView_GetItemText($hWnd_ListView, $x)
If $sText = $sSelection_Text Then
If _GUICtrlListView_SetItemSelected($hWnd_ListView, $x) Then
;success
Return 1
Else
;failure
Return SetError(@error)
EndIf
EndIf
Next
EndFunc
Func _Exit()
$timer_timeout = TimerInit()
While ProcessExists($iPID_Sound)
ProcessClose($iPID_Sound)
If TimerDiff($timer_timeout) > 5000 Then
_Exit_Error()
EndIf
Sleep(250)
WEnd
Exit
EndFunc ;==>_Exit
Func _Exit_Error()
If Not ProcessExists($iPID_Sound) Then
If ProcessExists("rundll32.exe") Then $iPID_Sound = ProcessExists("rundll32.exe")
EndIf
If ProcessExists($iPID_Sound) Then MsgBox(16 + 262144, "Error", "The process rundll32.exe with the PID " & $iPID_Sound & "could not be closed by SSD." & @CRLF & @CRLF & "SSD will exit now, close the process via Taskmanager.")
Exit
EndFunc ;==>_Exit_Error
Func _Detect_Sound_dialog_hWnd($iPID)
Local $hWnds = WinList("[CLASS:#32770;]", "")
For $i = 1 To $hWnds[0][0]
If BitAND(WinGetState($hWnds[$i][1], ''), 2) Then
If WinGetProcess(_WinAPI_GetAncestor($hWnds[$i][1], $GA_ROOTOWNER)) = ProcessExists($iPID) Then
Return $hWnds[$i][1]
EndIf
EndIf
Next
Return 0
EndFunc ;==>_Detect_Sound_dialog_hWnd
Edited by Cyri

Share this post


Link to post
Share on other sites

#20 ·  Posted

This is a fantastic utlility, especially since it's written in my favorite scripting language. Thank you!!!

I was curious why you didn't hide the Control Panel when changing the audio device.. then, after I tried to add code to hide it, I realized that it's practically impossible to hide it. :)

I found other posts where other people tried to do the same thing but couldn't completely hide the Windows Control panel gui. If anyone is able to figure out a good way to do this, please let me know.

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