I have no idea how to do it D:.
Whenever I come out of sleep, my microphone does not work until I reinitialize it, and its killing me inside from doing it for over a year. Any suggestions on a script to automate this process for me?
Thank you!
Disable, then re enable a microphone after coming out of sleep Topic is solved
-
- Posts: 319
- Joined: 23 Jan 2016, 23:03
Re: Disable, then re enable a microphone after coming out of sleep
For starters:
Then you will need to have the script ran when it comes out of sleep, probably with task scheduler.
Code: Select all
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetTitleMatchMode, 2 ; partial titles
if not A_IsAdmin
{
Run, *RunAs "%A_ScriptFullPath%"
ExitApp
}
Run, devmgmt.msc
WinWait, Device Manager
Device=Microphone
ControlSend, SysTreeView321, {tab}Audio{Right}%Device%{Enter}
WinWait, % Device
Control, TabRight,, SysTabControl321
send, !e!o ; Enable ok
WinClose % Device
WinClose, Device Manager
Then you will need to have the script ran when it comes out of sleep, probably with task scheduler.
Re: Disable, then re enable a microphone after coming out of sleep
Thanks for the reply!
I tried it out, and it did not work at first. I changed microhone in the script to Corsair Vegeance 1500 Headset, which makes the script execute correctly. However, it does not seem to disable my headset whatsoever... For example, the audio stream is not interrupted while watching a youtube video, and my microphone does not seem to work.
The way I disable/enable it is through the windows Sound. The one with Playback/Recording/Sounds/Communication -- Maybe this is the correct avenue of approach? I say this because device manager doesn't list the microphone seperately, just the headset and isn't work as current.
Thanks again for the script and the view Wizardzedd!
I tried it out, and it did not work at first. I changed microhone in the script to Corsair Vegeance 1500 Headset, which makes the script execute correctly. However, it does not seem to disable my headset whatsoever... For example, the audio stream is not interrupted while watching a youtube video, and my microphone does not seem to work.
The way I disable/enable it is through the windows Sound. The one with Playback/Recording/Sounds/Communication -- Maybe this is the correct avenue of approach? I say this because device manager doesn't list the microphone seperately, just the headset and isn't work as current.
Thanks again for the script and the view Wizardzedd!
-
- Posts: 319
- Joined: 23 Jan 2016, 23:03
Re: Disable, then re enable a microphone after coming out of sleep
I went big mode lol, although I was surprised that I didn't find a simpler way to click a listview item. Anyway here you are:
Code: Select all
device:="Microphone" ; change to your device
sounds:=new C_Sounds() ; Sounds window
sounds.activateRecording() ; Activate Recording Tab
properties:=sounds.openProperties(device) ; Open properties of device
currentSetting:=properties.choice ; retrieve current setting
properties.setChoice(instr(currentSetting, "enable") ? "disable" : "enable") ; toggle setting
properties.Close() ; close properties
sounds.Close() ; close sounds
return
esc::ExitApp
class C_Sounds
{
static winTitle:="Sound"
__New() {
if(!this.hwnd:=WinExist(WinTitle))
this.hwnd:=this.Open()
this.hwnd:="ahk_id" this.hwnd
}
; Open
Open() {
Run, %ComSpec% /C control mmsys.cpl sounds
WinWait, % this.winTitle,, 3
return WinExist(this.WinTitle)
}
; Close
Close() {
WinClose, % this.hwnd
}
; =============================== LISTVIEW =============================
; Open Properties
openProperties(Name) {
if(this.selectListItem(Name)) {
send !p
return new C_PropertiesWindow()
}
return false
}
; Select ListView Item
selectListItem(Name) {
ControlGet, list, list,, SysListView321, % this.hwnd
Loop, Parse, list, `n
if(instr(A_LoopField, Name)) {
LVSel(this.hwnd, A_Index-1)
return true
}
return false
}
; ============= 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_PropertiesWindow
{
static WinTitle:="Properties"
static classNN:="ComboBox1"
__New() {
SetTitleMatchMode, 2
WinWait, % this.WinTitle, , 1
if(ErrorLevel)
return false
this.hwnd:="ahk_id" winExist(this.WinTitle)
controlget, choice, choice, , % this.classNN, % this.hwnd
this.choice:=choice
}
setChoice(choice) {
if(instr(choice, this.choice))
return true
controlget, list, list, , % this.classNN, % this.hwnd
Loop, Parse, list, `n
if(instr(A_LoopField, choice))
i:=A_Index, this.choice:=A_LoopField, break
control, choose, %i%, % this.classNN, % this.hwnd
return !ErrorLevel
}
Close(save=true) {
if(save)
ControlClick, Button6, % this.hwnd,,, 2
else
WinClose, % this.hwnd
}
}
LVSel(WinTitle, r=0)
{
VarSetCapacity(LVITEM, 20, 0) ;to receive LVITEM
; LVIS_FOCUSED:=1 LVIS_SELECTED:=2
NumPut(1 | 2, LVITEM, 12) ; state
NumPut(1 | 2, LVITEM, 16) ; stateMask
RemoteBuf_Open(hLVITEM, WinExist(WinTitle), 20) ; MASTER_ID = the ahk_id of the process owning the SysListView32 control
RemoteBuf_Write(hLVITEM, LVITEM,20)
SendMessage, 0x102B,r,RemoteBuf_Get(hLVITEM), SysListView321,%WinTitle% ; LVM_SETITEMSTATE:=0x102B
RemoteBuf_Close(hLVITEM)
}
;
; Title: Remote Buffer
; *Read and write process memory*
;
/*-------------------------------------------------------------------------------
Function: Open
Open remote buffer
Parameters:
H - Reference to variable to receive remote buffer handle
hwnd - HWND of the window that belongs to the process
size - Size of the buffer
Returns:
Error message on failure
*/
RemoteBuf_Open(ByRef H, hwnd, size) {
static MEM_COMMIT=0x1000, PAGE_READWRITE=4
WinGet, pid, PID, ahk_id %hwnd%
hProc := DllCall( "OpenProcess", "uint", 0x38, "int", 0, "uint", pid) ;0x38 = PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE
IfEqual, hProc,0, return A_ThisFunc "> Unable to open process (" A_LastError ")"
bufAdr := DllCall( "VirtualAllocEx", "uint", hProc, "uint", 0, "uint", size, "uint", MEM_COMMIT, "uint", PAGE_READWRITE)
IfEqual, bufAdr,0, return A_ThisFunc "> Unable to allocate memory (" A_LastError ")"
; Buffer handle structure:
; @0: hProc
; @4: size
; @8: bufAdr
VarSetCapacity(H, 12, 0 )
NumPut( hProc, H, 0)
NumPut( size, H, 4)
NumPut( bufAdr, H, 8)
}
/*----------------------------------------------------
Function: Close
Close the remote buffer
Parameters:
H - Remote buffer handle
*/
RemoteBuf_Close(ByRef H) {
static MEM_RELEASE = 0x8000
handle := NumGet(H, 0)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
adr := NumGet(H, 8)
r := DllCall( "VirtualFreeEx", "uint", handle, "uint", adr, "uint", 0, "uint", MEM_RELEASE)
ifEqual, r, 0, return A_ThisFunc "> Unable to free memory (" A_LastError ")"
DllCall( "CloseHandle", "uint", handle )
VarSetCapacity(H, 0 )
}
/*----------------------------------------------------
Function: Read
Read from the remote buffer into local buffer
Parameters:
H - Remote buffer handle
pLocal - Reference to the local buffer
pSize - Size of the local buffer
pOffset - Optional reading offset, by default 0
Returns:
TRUE on success or FALSE on failure. ErrorMessage on bad remote buffer handle
*/
RemoteBuf_Read(ByRef H, ByRef pLocal, pSize, pOffset = 0){
handle := NumGet( H, 0), size:= NumGet( H, 4), adr := NumGet( H, 8)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
IfGreaterOrEqual, offset, %size%, return A_ThisFunc "> Offset is bigger then size"
VarSetCapacity( pLocal, pSize )
return DllCall( "ReadProcessMemory", "uint", handle, "uint", adr + pOffset, "uint", &pLocal, "uint", size, "uint", 0 ), VarSetCapacity(pLocal, -1)
}
/*----------------------------------------------------
Function: Write
Write local buffer into remote buffer
Parameters:
H - Remote buffer handle
pLocal - Reference to the local buffer
pSize - Size of the local buffer
pOffset - Optional writting offset, by default 0
Returns:
TRUE on success or FALSE on failure. ErrorMessage on bad remote buffer handle
*/
RemoteBuf_Write(Byref H, byref pLocal, pSize, pOffset=0) {
handle:= NumGet( H, 0), size := NumGet( H, 4), adr := NumGet( H, 8)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
IfGreaterOrEqual, offset, %size%, return A_ThisFunc "> Offset is bigger then size"
return DllCall( "WriteProcessMemory", "uint", handle,"uint", adr + pOffset,"uint", &pLocal,"uint", pSize, "uint", 0 )
}
/*----------------------------------------------------
Function: Get
Get address or size of the remote buffer
Parameters:
H - Remote buffer handle
pQ - Query parameter: set to "adr" to get address (default), to "size" to get the size or to "handle" to get Windows API handle of the remote buffer.
Returns:
Address or size of the remote buffer
*/
RemoteBuf_Get(ByRef H, pQ="adr") {
return pQ = "adr" ? NumGet(H, 8) : pQ = "size" ? NumGet(H, 4) : NumGet(H)
}
Re: Disable, then re enable a microphone after coming out of sleep
Wow! that is ridiculous what you wrote.
I would have been really lost if I tried to make it myself, haha...
However, one issue. Its failing once it opens the microphone tab, even with the correct name(Microphone is correct, double checked.) It doesn't open up the properties of microphone, and just closes after a short delay. It does not reset it either, I double checked just in case it was extremely fast. Sorry to be such a pain!
Again, thanks a bunch!
I would have been really lost if I tried to make it myself, haha...
However, one issue. Its failing once it opens the microphone tab, even with the correct name(Microphone is correct, double checked.) It doesn't open up the properties of microphone, and just closes after a short delay. It does not reset it either, I double checked just in case it was extremely fast. Sorry to be such a pain!
Again, thanks a bunch!
-
- Posts: 319
- Joined: 23 Jan 2016, 23:03
Re: Disable, then re enable a microphone after coming out of sleep
ok I added more code, and changed to listview double click to open the properties window. Try this out (oh and make sure you show disabled devices):
Code: Select all
#SingleInstance, force
device:="Microphone" ; change to your device
sounds:=new C_Sounds() ; Sounds window
sounds.activateRecording() ; Activate Recording Tab
properties:=sounds.openProperties(device) ; Open properties of device
while(!IsObject(properties) && !Abort) {
MsgBox, 18, Property Object Error, Failed to open properties window.
IfMsgBox, Abort
Abort:=true
}
if(!Abort) {
currentSetting:=properties.choice ; retrieve current setting
properties.setChoice(instr(currentSetting, "enable") ? "disable" : "enable") ; toggle setting
;~ MsgBox, % "current setting is " properties.choice
properties.Close() ; close properties
}
sounds.Close() ; close sounds
return
esc::ExitApp
class C_Sounds
{
static winTitle:="Sound"
__New() {
if(!this.hwnd:=WinExist(WinTitle))
this.hwnd:=this.Open()
this.hwnd:="ahk_id" this.hwnd
}
; Open
Open() {
Run, %ComSpec% /C control mmsys.cpl sounds
WinWait, % this.winTitle,, 3
return WinExist(this.WinTitle)
}
; Close
Close() {
WinClose, % this.hwnd
}
; =============================== LISTVIEW =============================
; Open Properties
openProperties(Name="") {
if(Name="") {
ControlClick, Button3, % this.hwnd,, , 1
return new C_PropertiesWindow()
} else if(this.doubleClickListItem(Name)) {
return new C_PropertiesWindow()
}
return false
}
; Select ListView Item
selectListItem(Name) {
if(r:=this.getListItemRow(Name))
LVSel(this.hwnd, r)
return r
}
doubleClickListItem(Name) {
if(r:=this.getListItemRow(Name)) {
controlget, lvHwnd, hwnd,, SysListView321, % this.hwnd
LV_DoubleClickRow(lvHwnd, r)
}
return r
}
; Get List item row
getListItemRow(Name) {
ControlGet, list, list,, SysListView321, % this.hwnd
Loop, Parse, list, `n
if(instr(A_LoopField, Name))
return A_Index
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_PropertiesWindow
{
static WinTitle:="Properties"
static classNN:="ComboBox1"
__New() {
SetTitleMatchMode, 2
WinWait, % this.WinTitle, , 1
;~ logM("Found win?" ErrorLevel)
if(ErrorLevel)
return false
this.hwnd:="ahk_id" winExist(this.WinTitle)
controlget, choice, choice, , % this.classNN, % this.hwnd
this.choice:=choice
}
setChoice(choice) {
if(instr(choice, this.choice))
return true
controlget, list, list, , % this.classNN, % this.hwnd
;~ logM(list)
Loop, Parse, list, `n
if(instr(A_LoopField, choice))
i:=A_Index, this.choice:=A_LoopField, break
;~ logM("choosing " i)
control, choose, %i%, % this.classNN, % this.hwnd
return !ErrorLevel
}
Close(save=true) {
if(save) {
ControlClick, Button6, % this.hwnd,,, 1
WinWaitClose, % this.hwnd,, 1
if(ErrorLevel) {
ControlClick, Button6, % this.hwnd,,, 1
WinWaitClose, % this.hwnd,, 1
}
return !ErrorLevel
}
else
WinClose, % this.hwnd
return true
}
}
; Thanks to just me!
LV_DoubleClickRow(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)
}
POINT := NumGet(RECT, 0, "Short") | (NumGet(RECT, 4, "Short") << 16)
PostMessage, 0x0201, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
PostMessage, 0x0202, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONUP
PostMessage, 0x0203, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDBLCLK
PostMessage, 0x0202, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONUP
Return True
}
LVSel(WinTitle, r=0)
{
--r
VarSetCapacity(LVITEM, 20, 0) ;to receive LVITEM
; LVIS_FOCUSED:=1 LVIS_SELECTED:=2
NumPut(1 | 2, LVITEM, 12) ; state
NumPut(1 | 2, LVITEM, 16) ; stateMask
RemoteBuf_Open(hLVITEM, WinTitle, 20) ; MASTER_ID = the ahk_id of the process owning the SysListView32 control
RemoteBuf_Write(hLVITEM, LVITEM,20)
SendMessage, 0x102B,r,RemoteBuf_Get(hLVITEM), SysListView321,%WinTitle% ; LVM_SETITEMSTATE:=0x102B
RemoteBuf_Close(hLVITEM)
}
;
; Title: Remote Buffer
; *Read and write process memory*
;
/*-------------------------------------------------------------------------------
Function: Open
Open remote buffer
Parameters:
H - Reference to variable to receive remote buffer handle
hwnd - HWND of the window that belongs to the process
size - Size of the buffer
Returns:
Error message on failure
*/
RemoteBuf_Open(ByRef H, WinTitle, size) {
static MEM_COMMIT=0x1000, PAGE_READWRITE=4
WinGet, pid, PID, %WinTitle%
hProc := DllCall( "OpenProcess", "uint", 0x38, "int", 0, "uint", pid) ;0x38 = PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE
IfEqual, hProc,0, return A_ThisFunc "> Unable to open process (" A_LastError ")"
bufAdr := DllCall( "VirtualAllocEx", "uint", hProc, "uint", 0, "uint", size, "uint", MEM_COMMIT, "uint", PAGE_READWRITE)
IfEqual, bufAdr,0, return A_ThisFunc "> Unable to allocate memory (" A_LastError ")"
; Buffer handle structure:
; @0: hProc
; @4: size
; @8: bufAdr
VarSetCapacity(H, 12, 0 )
NumPut( hProc, H, 0)
NumPut( size, H, 4)
NumPut( bufAdr, H, 8)
}
/*----------------------------------------------------
Function: Close
Close the remote buffer
Parameters:
H - Remote buffer handle
*/
RemoteBuf_Close(ByRef H) {
handle := NumGet(H, 0)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
adr := NumGet(H, 8)
r := DllCall( "VirtualFreeEx", "uint", handle, "uint", adr, "uint", 0, "uint", 0x8000) ; MEM_RELEASE
ifEqual, r, 0, return A_ThisFunc "> Unable to free memory (" A_LastError ")"
DllCall( "CloseHandle", "uint", handle )
VarSetCapacity(H, 0 )
}
/*----------------------------------------------------
Function: Read
Read from the remote buffer into local buffer
Parameters:
H - Remote buffer handle
pLocal - Reference to the local buffer
pSize - Size of the local buffer
pOffset - Optional reading offset, by default 0
Returns:
TRUE on success or FALSE on failure. ErrorMessage on bad remote buffer handle
*/
RemoteBuf_Read(ByRef H, ByRef pLocal, pSize, pOffset = 0){
handle := NumGet( H, 0), size:= NumGet( H, 4), adr := NumGet( H, 8)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
IfGreaterOrEqual, offset, %size%, return A_ThisFunc "> Offset is bigger then size"
VarSetCapacity( pLocal, pSize )
return DllCall( "ReadProcessMemory", "uint", handle, "uint", adr + pOffset, "uint", &pLocal, "uint", size, "uint", 0 ), VarSetCapacity(pLocal, -1)
}
/*----------------------------------------------------
Function: Write
Write local buffer into remote buffer
Parameters:
H - Remote buffer handle
pLocal - Reference to the local buffer
pSize - Size of the local buffer
pOffset - Optional writting offset, by default 0
Returns:
TRUE on success or FALSE on failure. ErrorMessage on bad remote buffer handle
*/
RemoteBuf_Write(Byref H, byref pLocal, pSize, pOffset=0) {
handle:= NumGet( H, 0), size := NumGet( H, 4), adr := NumGet( H, 8)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
IfGreaterOrEqual, offset, %size%, return A_ThisFunc "> Offset is bigger then size"
return DllCall( "WriteProcessMemory", "uint", handle,"uint", adr + pOffset,"uint", &pLocal,"uint", pSize, "uint", 0 )
}
/*----------------------------------------------------
Function: Get
Get address or size of the remote buffer
Parameters:
H - Remote buffer handle
pQ - Query parameter: set to "adr" to get address (default), to "size" to get the size or to "handle" to get Windows API handle of the remote buffer.
Returns:
Address or size of the remote buffer
*/
RemoteBuf_Get(ByRef H, pQ="adr") {
return pQ = "adr" ? NumGet(H, 8) : pQ = "size" ? NumGet(H, 4) : NumGet(H)
}
Re: Disable, then re enable a microphone after coming out of sleep
This is almost there! IT does indeed disable my microphone(most of the time), but does not re enable it afterwards. I tried to modify it like so:
1. Make it disable, then re enable after. However I think its missing a click apply button in between those two events, and I couldn't figure out how yours does it :/. Also, half the time it did not actually finish, it would open the properties of the microphone but then do nothing, aka not switch the source on or off or close the window. I added some sleeps to hopefuly fix that problem, but my fix does not work that well. I'm not sure if the sleeps need to be longer or if something else is wrong. Lastly, I made autohotkey exit unconditionally, I assume you had it end on esc for debugging purposes?
Thanks for all the help Zedd!
Code: Select all
#SingleInstance, force
device:="Microphone" ; change to your device
sounds:=new C_Sounds() ; Sounds window
sounds.activateRecording() ; Activate Recording Tab
properties:=sounds.openProperties(device) ; Open properties of device
while(!IsObject(properties) && !Abort) {
MsgBox, 18, Property Object Error, Failed to open properties window.
IfMsgBox, Abort
Abort:=true
}
if(!Abort) {
currentSetting:=properties.choice ; retrieve current setting
properties.setChoice(instr(currentSetting, "enable") ? "disable" : "enable") ; toggle setting
sleep, 500
properties.setChoice(instr(currentSetting, "disable") ? "disable" : "enable") ; toggle setting
;~ MsgBox, % "current setting is " properties.choice
properties.Close() ; close properties
sleep, 200
}
sounds.Close() ; close sounds
return
ExitApp
Thanks for all the help Zedd!
-
- Posts: 319
- Joined: 23 Jan 2016, 23:03
Re: Disable, then re enable a microphone after coming out of sleep
In your code the currentSetting has not changed. What has changed is the properties.choice. Currently it works perfectly (for me, I could probably remove the abort code as well).
I'm assuming you were attempting enabling and disabling for testing purposes only? If you want to simply enable the setting you could just do:
properties.setChoice("enable")
It shouldn't. I can't imagine why since the only winwaits I have also time out fairly quickly. It should set the choice and hit "Ok" (which both applies the setting and closes the window.) Now there could exist a problem if there is another window with "properties" in the title open... I updated so it should no longer be a problem.Also, half the time it did not actually finish, it would open the properties of the microphone but then do nothing
Indeed I did.I assume you had it end on esc for debugging purposes?
I'm assuming you were attempting enabling and disabling for testing purposes only? If you want to simply enable the setting you could just do:
properties.setChoice("enable")
Code: Select all
;
; AutoHotkey Version: 1.1.23.01
; Language: English
; Platform: Windows 10
; Author: WizardZedd
;
; Script Function:
; Enable Sound device Microphone.
;
#SingleInstance, force
device:="Microphone" ; change to your device
sounds:=new C_Sounds() ; Sounds window
sounds.activateRecording() ; Activate Recording Tab
properties:=sounds.openProperties(device) ; Open properties of device
while(!IsObject(properties:=sounds.openProperties(device)) && !Abort) {
MsgBox, 18, Property Object Error, Failed to open properties window.
IfMsgBox, Abort
Abort:=true
}
if(!Abort) {
properties.setChoice("enable") ; enable
properties.Close() ; close properties
}
sounds.Close()
return
class C_Sounds
{
static winTitle:="Sound"
__New() {
if(!this.hwnd:=WinExist(WinTitle))
this.hwnd:=this.Open()
this.hwnd:="ahk_id" this.hwnd
}
; Open
Open() {
Run, %ComSpec% /C control mmsys.cpl sounds
WinWait, % this.winTitle,, 3
return WinExist(this.WinTitle)
}
; Close
Close() {
WinClose, % this.hwnd
}
; =============================== LISTVIEW =============================
; Open Properties
openProperties(Name="") {
if(Name="") {
ControlClick, Button3, % this.hwnd,, , 1
return new C_PropertiesWindow()
} else if(this.doubleClickListItem(Name)) {
return new C_PropertiesWindow(Name)
}
return false
}
; Select ListView Item
selectListItem(ByRef Name) {
if(r:=this.getListItemRow(Name))
LVSel(this.hwnd, r)
return r
}
doubleClickListItem(ByRef Name) {
if(r:=this.getListItemRow(Name)) {
controlget, lvHwnd, hwnd,, SysListView321, % this.hwnd
LV_DoubleClickRow(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
}
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_PropertiesWindow
{
static WinTitle:="Properties"
static classNN:="ComboBox1"
__New(Name = "") {
SetTitleMatchMode, 2
WinWait, % Name:= (Name = "" ? "" : Name " ") this.WinTitle, , 1
if(ErrorLevel)
return false
this.hwnd:="ahk_id" winExist(Name)
controlget, choice, choice, , % this.classNN, % this.hwnd
this.choice:=choice
}
setChoice(choice) {
if(instr(choice, this.choice))
return true
controlget, list, list, , % this.classNN, % this.hwnd
Loop, Parse, list, `n
if(instr(A_LoopField, choice))
i:=A_Index, this.choice:=A_LoopField, break
control, choose, %i%, % this.classNN, % this.hwnd
return !ErrorLevel
}
Close(save=true) {
if(save) {
ControlClick, Button6, % this.hwnd,,, 1
WinWaitClose, % this.hwnd,, 1
if(ErrorLevel) {
ControlClick, Button6, % this.hwnd,,, 1
WinWaitClose, % this.hwnd,, 1
}
return !ErrorLevel
}
else
WinClose, % this.hwnd
return true
}
}
; Thanks to just me!
LV_DoubleClickRow(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)
}
POINT := NumGet(RECT, 0, "Short") | (NumGet(RECT, 4, "Short") << 16)
PostMessage, 0x0201, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
PostMessage, 0x0202, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONUP
PostMessage, 0x0203, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDBLCLK
PostMessage, 0x0202, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONUP
Return True
}
LVSel(WinTitle, r=0)
{
--r
VarSetCapacity(LVITEM, 20, 0) ;to receive LVITEM
; LVIS_FOCUSED:=1 LVIS_SELECTED:=2
NumPut(1 | 2, LVITEM, 12) ; state
NumPut(1 | 2, LVITEM, 16) ; stateMask
RemoteBuf_Open(hLVITEM, WinTitle, 20) ; MASTER_ID = the ahk_id of the process owning the SysListView32 control
RemoteBuf_Write(hLVITEM, LVITEM,20)
SendMessage, 0x102B,r,RemoteBuf_Get(hLVITEM), SysListView321,%WinTitle% ; LVM_SETITEMSTATE:=0x102B
RemoteBuf_Close(hLVITEM)
}
;
; Title: Remote Buffer
; *Read and write process memory*
;
/*-------------------------------------------------------------------------------
Function: Open
Open remote buffer
Parameters:
H - Reference to variable to receive remote buffer handle
hwnd - HWND of the window that belongs to the process
size - Size of the buffer
Returns:
Error message on failure
*/
RemoteBuf_Open(ByRef H, WinTitle, size) {
static MEM_COMMIT=0x1000, PAGE_READWRITE=4
WinGet, pid, PID, %WinTitle%
hProc := DllCall( "OpenProcess", "uint", 0x38, "int", 0, "uint", pid) ;0x38 = PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE
IfEqual, hProc,0, return A_ThisFunc "> Unable to open process (" A_LastError ")"
bufAdr := DllCall( "VirtualAllocEx", "uint", hProc, "uint", 0, "uint", size, "uint", MEM_COMMIT, "uint", PAGE_READWRITE)
IfEqual, bufAdr,0, return A_ThisFunc "> Unable to allocate memory (" A_LastError ")"
; Buffer handle structure:
; @0: hProc
; @4: size
; @8: bufAdr
VarSetCapacity(H, 12, 0 )
NumPut( hProc, H, 0)
NumPut( size, H, 4)
NumPut( bufAdr, H, 8)
}
/*----------------------------------------------------
Function: Close
Close the remote buffer
Parameters:
H - Remote buffer handle
*/
RemoteBuf_Close(ByRef H) {
handle := NumGet(H, 0)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
adr := NumGet(H, 8)
r := DllCall( "VirtualFreeEx", "uint", handle, "uint", adr, "uint", 0, "uint", 0x8000) ; MEM_RELEASE
ifEqual, r, 0, return A_ThisFunc "> Unable to free memory (" A_LastError ")"
DllCall( "CloseHandle", "uint", handle )
VarSetCapacity(H, 0 )
}
/*----------------------------------------------------
Function: Read
Read from the remote buffer into local buffer
Parameters:
H - Remote buffer handle
pLocal - Reference to the local buffer
pSize - Size of the local buffer
pOffset - Optional reading offset, by default 0
Returns:
TRUE on success or FALSE on failure. ErrorMessage on bad remote buffer handle
*/
RemoteBuf_Read(ByRef H, ByRef pLocal, pSize, pOffset = 0){
handle := NumGet( H, 0), size:= NumGet( H, 4), adr := NumGet( H, 8)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
IfGreaterOrEqual, offset, %size%, return A_ThisFunc "> Offset is bigger then size"
VarSetCapacity( pLocal, pSize )
return DllCall( "ReadProcessMemory", "uint", handle, "uint", adr + pOffset, "uint", &pLocal, "uint", size, "uint", 0 ), VarSetCapacity(pLocal, -1)
}
/*----------------------------------------------------
Function: Write
Write local buffer into remote buffer
Parameters:
H - Remote buffer handle
pLocal - Reference to the local buffer
pSize - Size of the local buffer
pOffset - Optional writting offset, by default 0
Returns:
TRUE on success or FALSE on failure. ErrorMessage on bad remote buffer handle
*/
RemoteBuf_Write(Byref H, byref pLocal, pSize, pOffset=0) {
handle:= NumGet( H, 0), size := NumGet( H, 4), adr := NumGet( H, 8)
IfEqual, handle, 0, return A_ThisFunc "> Invalid remote buffer handle"
IfGreaterOrEqual, offset, %size%, return A_ThisFunc "> Offset is bigger then size"
return DllCall( "WriteProcessMemory", "uint", handle,"uint", adr + pOffset,"uint", &pLocal,"uint", pSize, "uint", 0 )
}
/*----------------------------------------------------
Function: Get
Get address or size of the remote buffer
Parameters:
H - Remote buffer handle
pQ - Query parameter: set to "adr" to get address (default), to "size" to get the size or to "handle" to get Windows API handle of the remote buffer.
Returns:
Address or size of the remote buffer
*/
RemoteBuf_Get(ByRef H, pQ="adr") {
return pQ = "adr" ? NumGet(H, 8) : pQ = "size" ? NumGet(H, 4) : NumGet(H)
}
Re: Disable, then re enable a microphone after coming out of sleep
It needs to disable the device first, then enable it; this is not for testing purposes.
More in depth:
The problem I face is that upon coming out of sleep, my microphone stops working. Its not DISABLED per se, but it just does nothing. It does not capture audio, it does not spit an error or anything, it just stops working. Corsair has no idea why this is(and its past warranty.) so I'm stuck either restarting teamspeak 3, or disabling THEN re enabling the microphone(fixes all the issues, usually.)
As for the closing issue, its still there.
The only thing I can think of is I use an application called Displayfusion that gives me a second taskbar on my 2nd monitor as well as hook into other windows to add move to other monitor buttons. I tried disabling those buttons and everything from running for this... In this case, mmsys.cpl is run by Rundl32.exe. However, this did not fix the issue for me. Do you have any other suggestions? I really rather not get rid of displayfusion, but if I must I can go back to ultramon.
Sorry for the bad explanation before and all the trouble, but I gotta say your code gets more complex/beautiful with each rendition lol
More in depth:
The problem I face is that upon coming out of sleep, my microphone stops working. Its not DISABLED per se, but it just does nothing. It does not capture audio, it does not spit an error or anything, it just stops working. Corsair has no idea why this is(and its past warranty.) so I'm stuck either restarting teamspeak 3, or disabling THEN re enabling the microphone(fixes all the issues, usually.)
As for the closing issue, its still there.
The only thing I can think of is I use an application called Displayfusion that gives me a second taskbar on my 2nd monitor as well as hook into other windows to add move to other monitor buttons. I tried disabling those buttons and everything from running for this... In this case, mmsys.cpl is run by Rundl32.exe. However, this did not fix the issue for me. Do you have any other suggestions? I really rather not get rid of displayfusion, but if I must I can go back to ultramon.
Sorry for the bad explanation before and all the trouble, but I gotta say your code gets more complex/beautiful with each rendition lol
Re: Disable, then re enable a microphone after coming out of sleep
Edit: Forgot to say if its relevant, I'm using Windows 7 64 Bit
-
- Posts: 319
- Joined: 23 Jan 2016, 23:03
Re: Disable, then re enable a microphone after coming out of sleep
I see now, so using the code I wrote before you would basically have to set the property 2 times (couldn't just hit apply since it removes the device when disabled.) I decided to try a different approach that uses the context menu that hopefully will be simpler and work better.
Code: Select all
#SingleInstance, force
device:="Microphone" ; change to your device
sounds:=new C_Sounds() ; Sounds window
sounds.activateRecording() ; Activate Recording Tab
myMenu:=sounds.openMenu(device) ; Open menu of device
myMenu.ClickText("disable")
myMenu:=sounds.openMenu(device)
myMenu.ClickText("enable")
sounds.Close()
return
class C_Sounds
{
static winTitle:="Sound"
__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
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,, 1
if(!ErrorLevel)
return new C_StandardMenu()
}
MsgBox, 16, , % A_ThisFunc "`tFailed to open menu for " Name
return false
}
; Select ListView Item
selectListItem(ByRef Name) {
if(r:=this.getListItemRow(Name))
LVSel(this.hwnd, r)
return r
}
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) {
VarSetCapacity(Rect, 16, 0)
if(!Dllcall("user32.dll\GetMenuItemRect", "UInt", substr(this.title, 7), "UInt", this.hMenu, "UInt", pos-1, "Ptr", &Rect ))
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
pos:=1
pos > 0 ? this.pos:=pos : this.pos:=1
}
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)
return (ErrorLevel || A_LastError) ? -1 : 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)
}
POINT := (x:=NumGet(RECT, 0, "Short")) | ((y:=NumGet(RECT, 4, "Short")) << 16)
sleep, 1000
PostMessage, 0x0201, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
PostMessage, 0x0202, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
send, {AppsKey}
Return True
}
Re: Disable, then re enable a microphone after coming out of sleep
There is an error in line 48, "LVsel(this.hwnd,r)
fatal error.
:O
fatal error.
:O
Re: Disable, then re enable a microphone after coming out of sleep
monorchid wrote:There is an error in line 48, "LVsel(this.hwnd,r)
fatal error.
:O
To be exact, its a call to nonexistant function, mb
-
- Posts: 319
- Joined: 23 Jan 2016, 23:03
Re: Disable, then re enable a microphone after coming out of sleep
oops, thats what happens when you cut out parts of code xD.
Code: Select all
;
; AutoHotkey Version: 1.1.23.01
; Language: English
; Platform: Windows 10
; Author: WizardZedd
;
; Script Function:
;
;
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance, force ; Don't worry about annoying messages.
#Include %a_scriptdir%
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
device:="Microphone" ; change to your device
sounds:=new C_Sounds() ; Sounds window
sounds.activateRecording() ; Activate Recording Tab
myMenu:=sounds.openMenu(device) ; Open menu of device
myMenu.ClickText("disable")
myMenu:=sounds.openMenu(device)
myMenu.ClickText("enable")
sounds.Close()
return
class C_Sounds
{
static winTitle:="Sound"
__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
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,, 1
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) {
VarSetCapacity(Rect, 16, 0)
if(!Dllcall("user32.dll\GetMenuItemRect", "UInt", substr(this.title, 7), "UInt", this.hMenu, "UInt", pos-1, "Ptr", &Rect ))
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
pos:=1
pos > 0 ? this.pos:=pos : this.pos:=1
}
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)
return (ErrorLevel || A_LastError) ? -1 : 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)
}
POINT := (x:=NumGet(RECT, 0, "Short")) | ((y:=NumGet(RECT, 4, "Short")) << 16)
sleep, 1000
PostMessage, 0x0201, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
PostMessage, 0x0202, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
send, {AppsKey}
Return True
}
Re: Disable, then re enable a microphone after coming out of sleep
This time it opens it up as if you right clicked, however it doesn't click enable or disable(nothing happens after this.) if I do it myself, or click out of it, it closes the window as if it were done. Something is going wrong :/.
Is there anything I do can to help? like provide a log or something? If it works on your end it sounds like there is something it just doesn't like about my computer...
I installed autohotkey outside of the normal Program dir, i know some programs don't like that. Is that the problem(my poor SSD must be protected!)
Is there anything I do can to help? like provide a log or something? If it works on your end it sounds like there is something it just doesn't like about my computer...
I installed autohotkey outside of the normal Program dir, i know some programs don't like that. Is that the problem(my poor SSD must be protected!)
-
- Posts: 319
- Joined: 23 Jan 2016, 23:03
Re: Disable, then re enable a microphone after coming out of sleep
Sometimes I wish all systems could be the same lol. The 2 calls in question will be clickMenuItem(pos) and getText(pos). Try running this code with the menu already open, press ctrl-b. What do the 2 message boxes say? .
EDIT: It should say "x is (beginning x position of 2nd menu item) y is (beginning y position of 2nd menu item)". The second should say "Text at position 2 is (whatever's at pos 2)"
EDIT: It should say "x is (beginning x position of 2nd menu item) y is (beginning y position of 2nd menu item)". The second should say "Text at position 2 is (whatever's at pos 2)"
Code: Select all
^b::
myMenu:=new C_StandardMenu()
text:=myMenu.getText(2)
myMenu.ClickMenuItem(2)
MsgBox, % "Text at position 2 is " text
return
class C_Sounds
{
static winTitle:="Sound"
__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
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,, 1
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) {
VarSetCapacity(Rect, 16, 0)
if(!Dllcall("user32.dll\GetMenuItemRect", "UInt", substr(this.title, 7), "UInt", this.hMenu, "UInt", pos-1, "Ptr", &Rect ))
return false
POINT := (x:=NumGet(Rect, 0, "Short")) | (y:=NumGet(Rect, 4, "Short")) << 16
PostMessage, 0x0201, 0, POINT, , % this.title ; WM_LBUTTONDOWN
PostMessage, 0x0202, 0, POINT, , % this.title ; WM_LBUTTONUP
MsgBox, % "x is " x " y is " y
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
pos:=1
pos > 0 ? this.pos:=pos : this.pos:=1
}
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)
return (ErrorLevel || A_LastError) ? -1 : 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)
}
POINT := (x:=NumGet(RECT, 0, "Short")) | ((y:=NumGet(RECT, 4, "Short")) << 16)
sleep, 1000
PostMessage, 0x0201, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
PostMessage, 0x0202, 0, POINT, , ahk_id %HLV% ; WM_LBUTTONDOWN
send, {AppsKey}
Return True
}
Re: Disable, then re enable a microphone after coming out of sleep
x is 353 y is 361
text at position 2 is -1
this seems to poll the mouse location, which is always a little different each time i run it. I assume it has no real bearing on the script besides being semi close?
This is letting windows decide where to open my sound window, and then right clicking microphone and then pressing CTRL+B.
text at position 2 is -1
this seems to poll the mouse location, which is always a little different each time i run it. I assume it has no real bearing on the script besides being semi close?
This is letting windows decide where to open my sound window, and then right clicking microphone and then pressing CTRL+B.
Re: Disable, then re enable a microphone after coming out of sleep
Hi,
Since you are encountering issues with clicking the Sound window and stuff, perhaps you could try to re-enable the device more directly by editing the Windows registry? See:
https://smulpuru.wordpress.com/tag/disable-microphone/
Try to find your mic among the devices here: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio. To do that, just click on the folders with the long names in curly brackets: one of them should have the key DeviceState with a value of 0x00000001. If your mic is enabled, that should be it. To verify that this device is indeed your mic, expand the folder with the long name in brackets, look in the Properties subfolder and somewhere near the end of list of keys one of them should be the exact user friendly name of the mic that you see in the Sound panel.
When your mic gets disabled, does the DeviceState value get changed to something other than 0x00000001? If yes, I think you can just re-give it a value of 1 to automatically re-enable it (using AHK of course!)
Sorry I don't have more time to write a code... Hope this helps!
Since you are encountering issues with clicking the Sound window and stuff, perhaps you could try to re-enable the device more directly by editing the Windows registry? See:
https://smulpuru.wordpress.com/tag/disable-microphone/
Try to find your mic among the devices here: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio. To do that, just click on the folders with the long names in curly brackets: one of them should have the key DeviceState with a value of 0x00000001. If your mic is enabled, that should be it. To verify that this device is indeed your mic, expand the folder with the long name in brackets, look in the Properties subfolder and somewhere near the end of list of keys one of them should be the exact user friendly name of the mic that you see in the Sound panel.
When your mic gets disabled, does the DeviceState value get changed to something other than 0x00000001? If yes, I think you can just re-give it a value of 1 to automatically re-enable it (using AHK of course!)
Sorry I don't have more time to write a code... Hope this helps!
Re: Disable, then re enable a microphone after coming out of sleep
Thanks for the suggestion!lblb wrote:Hi,
Since you are encountering issues with clicking the Sound window and stuff, perhaps you could try to re-enable the device more directly by editing the Windows registry? See:
https://smulpuru.wordpress.com/tag/disable-microphone/
Try to find your mic among the devices here: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio. To do that, just click on the folders with the long names in curly brackets: one of them should have the key DeviceState with a value of 0x00000001. If your mic is enabled, that should be it. To verify that this device is indeed your mic, expand the folder with the long name in brackets, look in the Properties subfolder and somewhere near the end of list of keys one of them should be the exact user friendly name of the mic that you see in the Sound panel.
When your mic gets disabled, does the DeviceState value get changed to something other than 0x00000001? If yes, I think you can just re-give it a value of 1 to automatically re-enable it (using AHK of course!)
Sorry I don't have more time to write a code... Hope this helps!
I tested out this idea, and I am sure I found the right microphone key. It does NOT deactivate according to regedit, and changing it from its off value(when manually deactivated) of 10000001, it will not turn back on. If 10000001 is reapplied, and then the microphone is reactivated via Sound, it works just fine again.
Re: Disable, then re enable a microphone after coming out of sleep
Well, it was worth a try... But to be sure:
When it's enabled, the value is 00000001 and not 10000001. So if it's disabled, the value is 10000001. Then if you double-click on DeviceState and just write 1 for value data, you don't see it as enabled if you relaunch Sound?
When it's enabled, the value is 00000001 and not 10000001. So if it's disabled, the value is 10000001. Then if you double-click on DeviceState and just write 1 for value data, you don't see it as enabled if you relaunch Sound?
Who is online
Users browsing this forum: aitaixy, Anput, dangoscrub, Google [Bot], joedf, Nerafius and 176 guests