Audio input enable/disable bind

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
sam_663
Posts: 1
Joined: 17 Jun 2018, 22:37

Audio input enable/disable bind

17 Jun 2018, 22:51

im slowly dying from switching inputs for over a year now and ive decided to do something about it.

so, i have two microphones and to use one i have to disable the other before i enable the one i have to use so can anyone help me make a script to enable/disable each one of them? If you could please keep me from dying my slow painful death that would be awesome.
User avatar
DyaTactic
Posts: 221
Joined: 04 Apr 2017, 05:52

Re: Audio input enable/disable bind

18 Jun 2018, 16:17

I found this script that proves it is possible. (https://autohotkey.com/boards/viewtopic ... 2&start=40)
Now I need a few names of your system so you can use the scirpt:
- The name of the device listed in the sound settigns window
- The name of the other device
- The title of the sound settings window


The script:
It is desinged to disable and re-enable one sound device after logon in order to fix a bug with a microfone.

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance, force		; Don't worry about annoying messages.
#Persistent
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

return

WM_WTSSESSION_CHANGE(wParam, lParam, Msg, hWnd){
	static init:=(DllCall( "Wtsapi32.dll\WTSRegisterSessionNotification", UInt, A_ScriptHwnd, UInt, 1) && OnMessage(0x02B1, "WM_WTSSESSION_CHANGE"))
	If (wParam=0x5 || wParam=0x8){ ;Logon or unlock
		device:="Microphone" ; Change to your device
		sounds:=new C_Sounds()	; Sounds window
		sounds.activateRecording()	; Activate Recording Tab
		sleep, 100
		myMenu:=sounds.openMenu(device)	; Open menu of device
		myMenu.ClickMenuItem(2)    ; disable
		myMenu:=sounds.openMenu(device)
		myMenu.ClickMenuItem(1)    ; enable
		sounds.Close()
	} 
}

class C_Sounds	
{
	static winTitle:="Geluid" ; Change to you locale.
	__New() {
		if(!this.hwnd:=WinExist(WinTitle))
			this.hwnd:=this.Open()
		if(!this.hwnd)
			MsgBox, 16, , % A_ThisFunc "`tFailed to open Sounds" 	
		this.hwnd:="ahk_id" this.hwnd
	}
	; Open
	Open() {		
		Run, %ComSpec% /C control mmsys.cpl sounds,, hide
		WinWait, % this.winTitle,, 3
		return WinExist(this.WinTitle)
	}
	; Close
	Close() {
		WinClose, % this.hwnd
	}
 
	; =============================== LISTVIEW =============================
	; Open Context Menu
	openMenu(Name="") {
		if(this.rightClickListItem(Name)) {
			WinWait, % C_StandardMenu.WinTitle,, 3
			if(!ErrorLevel)
				return new C_StandardMenu()
		} 
		MsgBox, 16, , % A_ThisFunc "`tFailed to open menu for " Name	
		return false
	}
 
	RightClickListItem(ByRef Name) {
		if(r:=this.getListItemRow(Name)) {
		controlget, lvHwnd, hwnd,, SysListView321, % this.hwnd
			if(!lvHwnd)
				MsgBox, 16, , % A_ThisFunc "`tFailed to get listview SysListView321 handle"
			LV_rightClickRow(lvHwnd, r)
		}
		return r		
	}
 
	; Get List item row
	getListItemRow(ByRef Name) {
		ControlGet, list, list,, SysListView321, % this.hwnd
		Loop, Parse, list, `n
			if(instr(A_LoopField, Name)) {
				Name:=substr(A_LoopField, 1, instr(A_LoopField, "`t")-1)
				return A_Index
			}
		MsgBox, 16, , % A_ThisFunc "`tFailed to find listview item " Name
		return 0
	}
 
	; ============= TABS =================
	activatePlayback() {
		return this.activateTab(1)
	}
	activateRecording() {
		return this.activateTab(2)
	}
	activateSounds() {
		return this.activateTab(3)
	}
	activateCommunications() {
		return this.activateTab(4)
	}
	activateTab(n) {
		if(tab:=n-this.getTab()) {
			if(tab > 0)
				control, TabRight, % tab, SysTabControl321, % this.hwnd
			else
				control, TabLeft, % tab*-1, SysTabControl321, % this.hwnd
		}
		return !ErrorLevel
	}
	getTab() {
		controlget, tab, tab,, SysTabControl321, % this.hwnd
		return tab
	}
}
 
class C_StandardMenu
{
	static winTitle:="ahk_class #32768"
	__New() {
		WinGet, cTitle, id, % this.winTitle
		if(!cTitle)
			return false
		SendMessage, 0x01E1, , , , % this.title:="ahk_id" cTitle  ;Retrieve menu handle from window
		this.hMenu:=ErrorLevel
		this.getCount() ; initialize count
	}
 
; Click Menu item with text "Text" in it.
	ClickText(Text) {
		return (p:=this.getItemPos(Text)) ? this.ClickMenuItem(p) : false
	}
 
	ClickMenuItem(pos) {
		if(pos < 1 || pos > this.count) {
			MsgBox, 16, C_StandardMenu Error, Invalid position %pos%
			return false
		}
		VarSetCapacity(Rect, 16, 0)
		if(!Dllcall("user32.dll\GetMenuItemRect", "UInt", substr(this.title, 7), "UInt", this.hMenu, "UInt", pos-1, "Ptr", &Rect )) {
			MsgBox, 16, C_StandardMenu Error, Failed to click item at pos %pos% `n ErrorLevel: %ErrorLevel% `n Last Error: %A_LastError%
			return false
		}
		POINT := (NumGet(Rect, 0, "Short")) | (NumGet(Rect, 4, "Short")) << 16
		PostMessage, 0x0201, 0, POINT, , % this.title ; WM_LBUTTONDOWN
		PostMessage, 0x0202, 0, POINT, , % this.title ; WM_LBUTTONUP
		return true
	}
	; ===================================================================
	; ======================== GETTERS ==================================
	; ===================================================================
	; Get Item count
	getCount() {
		Return this.Count:=DllCall("GetMenuItemCount",UInt, this.hMenu)
	}
	; Get Selected
	getSelected() { 
		Loop, % this.Count
		{
			(t:=new this.C_MenuItemInfo(A_Index)).GetContextMenuState(this.hMenu)
			if(t.isSelected())
				return A_Index
		}
	}
 
	getItemPos(Text) {
		Loop, % this.Count
			if(instr((new this.C_MenuItemInfo(A_Index)).GetContextMenuText(this.hMenu), Text))
				return A_Index
	}
 
	getText(pos) {
		return (new this.C_MenuItemInfo(pos)).GetContextMenuText(this.hMenu)
	}
 
	getChecked(pos) {
		(t:=new this.C_MenuItemInfo(pos)).GetContextMenuState()
		return t.isChecked()
	}
 
	getEnabled(pos) {
		(t:=new this.C_MenuItemInfo(pos)).GetContextMenuState()
		return t.IsEnabled()
	}
 
	getDefault() {
		Loop, % this.Count
		{
			(t:=new this.C_MenuItemInfo(A_Index)).GetContextMenuState(this.hMenu)
			if(t.isDefault())
				return A_Index
		}	
	}
 
	; C_MenuItemInfo
	class C_MenuItemInfo
	{
		static cbSize := 48
		__New(pos){	
			if pos is not number 
			{
				MsgBox, 16, MenuItemInfo Error, % "Position " pos " is invalid." 
				return false
			} else if (pos < 1) {
				MsgBox, 16, MenuItemInfo Error, % "Position " pos " is invalid." 
				return false
			}
			this.pos:=pos 
		}
		isChecked() {
			return this.info & 0x8
		}
		IsEnabled() {
			return (!(this.info & 0x3))
		}
		isSelected() {
			return this.info & 0x80
		}
		isDefault() {
			return this.info & 0x1000
		}
 
		GetContextMenuState(hMenu) {
		  VarSetCapacity(MenuItemInfo, 60, 0)   ;We need to allocate a struct 60
		  NumPut(this.cbSize, MenuItemInfo, 0)   ;Set Size of Struct to the first member
		  NumPut(1, MenuItemInfo, 4)   ;Get only Flags from dllcall GetMenuItemInfo MIIM_TYPE = 1
		  DllCall("user32.dll\GetMenuItemInfo",UInt, hMenu, Uint, this.pos-1, uint, 1, "int", &MenuItemInfo)
		  if (ErrorLevel || A_LastError) {
			MsgBox, 16, C_StandardMenu Error, Error getting Menu Item Info. `nErrorLevel: %ErrorLevel% `nLast Error: %A_LastError%
			return -1
		}
		  return this.info:= NumGet(MenuItemInfo, 12)  ; fState
		}
 
		GetContextMenuText(hMenu) {
		  VarSetCapacity(MenuItemInfo, 200, 0)
		   NumPut(this.cbSize, MenuItemInfo, 0)  ;Set Size of Struct (48) to the first member
		  NumPut(64, MenuItemInfo, 4)   ;Retrieve string MIIM_STRING = 0x40 = 64 (/ MIIM_TYPE = 0x10 = 16)
		  if(DllCall("user32.dll\GetMenuItemInfo",UInt, hMenu, Uint, this.pos-1, uint, 1, "int", &MenuItemInfo) = 0 
			|| ErrorLevel || A_LastError || (GetMenuItemInfoRes := NumGet(MenuItemInfo, 40)) = 0) ;Get size of string from struct
			 return -1
		  GetMenuItemInfoRes += 2
		  VarSetCapacity(PopupText, GetMenuItemInfoRes, 0)  ;Set capacity of string that will be filled by windows
		  NumPut(GetMenuItemInfoRes, MenuItemInfo, 40, 4)    ;Set Size plus 0 terminator + security ;-)
		  NumPut(&PopupText, MenuItemInfo, 36, 4)
		  return (DllCall("user32.dll\GetMenuItemInfo",UInt, hMenu, Uint, this.pos-1, uint, 1, "int", &MenuItemInfo) = 0		
			|| ErrorLevel || A_LastError) ? -1 : this.Text:=PopupText
		}
	}
}
; Thanks to just me!
LV_RightClickRow(HLV, Row) {
   ; HLV : ListView's HWND, Row : 1-based row number
   HPROC := 0
   MyPID := DllCall("GetCurrentProcessId", "UInt")
   WinGet, LVPID, PID, ahk_id %HLV%
   If !(LVPID)
      Return False
   VarSetCapacity(RECT, 16, 0)
   If (LVPID <> MyPID) {
      If !(HPROC := DllCall("OpenProcess", "UInt", 0x0438, "Int", False, "UInt", LVPID, "Ptr"))
         Return False
      If !(Addr := DllCall("VirtualAllocEx", "Ptr", HPROC, "Ptr", 0, "UPtr", 16, "UInt", 0x1000, "UInt", 4, "UPtr"))
         Return (DllCall("CloseHandle", "Ptr", HPROC) & 0) ; False
   }
   Else
      Addr := &RECT
   SendMessage, 0x1013, % (Row - 1), 1, , ahk_id %HLV% ; LVM_ENSUREVISIBLE
   SendMessage, 0x100E, % (Row - 1), %Addr%, , ahk_id %HLV% ; LVM_GETITEMRECT
   If (HPROC) {
      DllCall("ReadProcessMemory", "Ptr", HPROC, "Ptr", Addr, "Ptr", &RECT, "UPtr", 16, "Ptr", 0)
      DllCall("VirtualFreeEx", "Ptr", HPROC, "Ptr", Addr, "UPtr", 0, "UInt", 0x8000)
      DllCall("CloseHandle", "Ptr", HPROC)
   }
   x:=NumGet(RECT, 0, "Short"), y:=NumGet(RECT, 4, "Short")
   controlclick, , % "ahk_id" HLV,, Right,, x%x% y%y%  
Return True
} 

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Anput, mikeyww and 224 guests