Hi Folks,
I wrote a script that allows volume changing and muting/unmuting via its system tray icon and hotkeys. The script reflects the volume and mute/unmute changes via its tray tip and tray icon. However, if the volume or mute status is changed in another way, such as the standard speaker icon in the system tray or some other app, my script doesn't know that, so its tray tip and tray icon will not reflect the current status.
I was thinking that there might be an OnMessage for it, but I didn't see anything in the List of Windows Messages about audio/sound/volume.
I could Sleep or SetTimer to check it periodically, but I'd rather not do that. There must be a notification mechanism in Windows, because the standard speaker icon in the system tray instantly reflects the volume level and mute status when my script changes them. Anyone know how an AutoHotkey script can get those volume and mute notifications? Thanks much, Joe
Can an AutoHotkey script be notified of volume changing and muting/unmuting?
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
This looks like a path to pursue: IAudioEndpointVolumeCallback interface
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Thanks for the link, boiler...the OnNotify method looks promising...if I can figure out how to translate it into AHK.
if anyone reading this thread has already done that, I'll be very grateful for the code. Regards, Joe
![Smile :)](./images/smilies/icon_e_smile.gif)
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
VA.ahk wraps IAudioEndpointVolume and the interfaces required to get it. You would need to use IAudioEndpointVolume::RegisterControlChangeNotify (VA_IAudioEndpointVolume_RegisterControlChangeNotify) to register a callback interface. The callback interface is not something you wrap; you must implement it by building the vtable and filling it with callback function pointers at the appropriate positions. You should refer to the SDK headers for ordering (keyword: IAudioEndpointVolumeCallbackVtbl), since the documentation sorts alphabetically.
Note that some native COM notifications call the callback interface from a worker thread; i.e. not AutoHotkey's main thread. This would make the script unstable. Judging by comments in Using IMMNotificationClient in a more safe manner and given that it is a related API, IAudioEndpointVolume's notifications are probably like that, and will not be safe to catch without some intermediary, like machine code (calling SendMessage to notify the script) or a DLL.
Otherwise, for one example of implementing an interface, see class ActiveScriptSite (which implements two interfaces in one object, so is not the best example). Creating COM Object Event Handler has an example and some explanation (but keep in mind the bug noted at the end of the topic). There are probably more examples.
Note that some native COM notifications call the callback interface from a worker thread; i.e. not AutoHotkey's main thread. This would make the script unstable. Judging by comments in Using IMMNotificationClient in a more safe manner and given that it is a related API, IAudioEndpointVolume's notifications are probably like that, and will not be safe to catch without some intermediary, like machine code (calling SendMessage to notify the script) or a DLL.
Otherwise, for one example of implementing an interface, see class ActiveScriptSite (which implements two interfaces in one object, so is not the best example). Creating COM Object Event Handler has an example and some explanation (but keep in mind the bug noted at the end of the topic). There are probably more examples.
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Thanks, lexikos. I haven't read all 13 pages at the VA.ahk thread yet, so the answer might be in there, but do you know off the top of your head if it works as-is in W7/8.1/10, or would it need changes?
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Re latest Windows versions: I haven't used these specific endpoints, but I just used VA.ahk successfully (for much simpler tasks) a few days ago on Win 10 with latest AHK (both 64 bit).
(But I probably won't be of much help for this topic here
, sorry )
(But I probably won't be of much help for this topic here
![Wink ;)](./images/smilies/icon_e_wink.gif)
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Thanks, gregster, good to know that least some aspects of VA.ahk worked for you on W10. Regards, Joe
-
- Posts: 4331
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Tried to implement, it seems to work:
Code: Select all
; #Include VA.ahk
SetBatchLines, -1
Gui, +AlwaysOnTop
Gui, Font, s16
Gui, Add, Text, y13, Volume:
Gui, Add, Text, xp y+5 wp right, Muted:
Gui, Add, Text, x+3 y13 left, 100
Gui, Add, Text, xp y+5, 0
GuiControl,, Static3, % Round( VA_GetMasterVolume() )
GuiControl,, Static4, % VA_GetMasterMute()
Gui, Show
IAudioEndpointVolume := VA_GetAudioEndpointVolume("playback")
IAudioEndpointVolumeCallback := IAudioEndpointVolumeCallback_Create(IAudioEndpointVolume)
VA_IAudioEndpointVolume_RegisterControlChangeNotify(IAudioEndpointVolume, IAudioEndpointVolumeCallback)
OnExit( Func("Clear").Bind(IAudioEndpointVolume, IAudioEndpointVolumeCallback) )
Return
SetInfo(info) {
GuiControl,, Static3, % Round( info[2]*100 )
GuiControl,, Static4, % info[1]
}
Clear(IAudioEndpointVolume, IAudioEndpointVolumeCallback) {
VA_IAudioEndpointVolume_UnregisterControlChangeNotify(IAudioEndpointVolume, IAudioEndpointVolumeCallback)
ObjRelease(IAudioEndpointVolume)
}
GuiClose() {
ExitApp
}
IAudioEndpointVolumeCallback_Create(aev) {
static VTBL := [ RegisterCallback("IAudioEndpointVolumeCallback_QueryInterface")
, RegisterCallback("IAudioEndpointVolumeCallback_AddRef")
, RegisterCallback("IAudioEndpointVolumeCallback_Release")
, RegisterCallback("IAudioEndpointVolumeCallback_OnNotify", "F") ]
, heapSize := A_PtrSize*10
, heapOffset := A_PtrSize*9
, flags := (HEAP_GENERATE_EXCEPTIONS := 0x4) | (HEAP_NO_SERIALIZE := 0x1)
, HEAP_ZERO_MEMORY := 0x8
hHeap := DllCall("HeapCreate", "UInt", flags, "Ptr", 0, "Ptr", 0, "Ptr")
addr := IAudioEndpointVolumeCallback := DllCall("HeapAlloc", "Ptr", hHeap, "UInt", HEAP_ZERO_MEMORY, "Ptr", heapSize, "Ptr")
addr := NumPut(addr + A_PtrSize, addr + 0)
for k, v in VTBL
addr := NumPut(v, addr + 0)
NumPut(hHeap, IAudioEndpointVolumeCallback + heapOffset)
Return IAudioEndpointVolumeCallback
}
IAudioEndpointVolumeCallback_QueryInterface(this, riid, ppvObject) {
Return 0 ; S_OK
}
IAudioEndpointVolumeCallback_AddRef(this) {
static refOffset := A_PtrSize*8
NumPut(refCount := NumGet(this + refOffset, "UInt") + 1, this + refOffset, "UInt")
Return refCount
}
IAudioEndpointVolumeCallback_Release(this) {
static refOffset := A_PtrSize*8
, heapOffset := A_PtrSize*9
NumPut(refCount := NumGet(this + refOffset, "UInt") - 1, this + refOffset, "UInt")
if (refCount = 0) {
hHeap := NumGet(this + heapOffset)
DllCall("HeapDestroy", "Ptr", hHeap)
}
Return refCount
}
IAudioEndpointVolumeCallback_OnNotify(this, pNotify) {
static info := [], timer := Func("SetInfo").Bind(info)
Critical
info[1] := NumGet(pNotify + 16, "UInt")
info[2] := NumGet(pNotify + 20, "Float")
SetTimer, % timer, -10
Return 0
}
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Hi teadrinker,
Spectacular! I tested it on W7/64-bit, W8.1/64-bit, W10/32-bit, and W10/64-bit. Worked perfectly on all systems! I can't thank you enough for this...fantastic! Regards, Joe
Spectacular! I tested it on W7/64-bit, W8.1/64-bit, W10/32-bit, and W10/64-bit. Worked perfectly on all systems! I can't thank you enough for this...fantastic! Regards, Joe
-
- Posts: 4331
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Haha! Just tested on Windows 10, sometimes it stucks. ![Laughing :lol:](./images/smilies/icon_lol.gif)
![Laughing :lol:](./images/smilies/icon_lol.gif)
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Hi teadrinker,
Hasn't failed here yet, but I tested it only briefly on all systems. I plan to integrate it into a horizontal-volume-slider script that I wrote for physically-impaired users...base script is here:
https://www.autohotkey.com/boards/viewtopic.php?p=235750#p235750
Once I get your code integrated into mine, I'll be able to test it more thoroughly. Will let you know if it sticks any during real usage. Thanks again! Regards, Joe
Hasn't failed here yet, but I tested it only briefly on all systems. I plan to integrate it into a horizontal-volume-slider script that I wrote for physically-impaired users...base script is here:
https://www.autohotkey.com/boards/viewtopic.php?p=235750#p235750
Once I get your code integrated into mine, I'll be able to test it more thoroughly. Will let you know if it sticks any during real usage. Thanks again! Regards, Joe
-
- Posts: 4331
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
For me it works without freezes on Win 7 and 10 with AutoHotkey.dll like this:
Code: Select all
Gui, +AlwaysOnTop
Gui, Font, s16
Gui, Add, Text, y13, Volume:
Gui, Add, Text, xp y+5 wp right, Muted:
Gui, Add, Text, x+3 y13 left, 100
Gui, Add, Text, xp y+5, 0
GuiControl,, Static3, % Round( VA_GetMasterVolume() )
GuiControl,, Static4, % VA_GetMasterMute()
Gui, Show
; specify the path to AutoHotkey.dll
dllpath := A_ScriptDir . "\AutoHotkeyDll\" . (A_PtrSize = 8 ? "x64w" : "Win32w") . "\AutoHotkey.dll"
if !FileExist(dllpath) {
MsgBox, AutoHotkey.dll not found
ExitApp
}
if GetModuleBitness(dllpath) != A_PtrSize*8 {
MsgBox, AutoHotkey.dll has incorrect bit depth
ExitApp
}
DllCall("LoadLibrary", "Str", dllpath)
DllCall(dllpath . "\ahktextdll", "Str", GetScript(), "Str", "", "CDecl")
OnMessage(0x4A, "WM_COPYDATA_READ")
Return
GuiClose() {
ExitApp
}
SetInfo(data) {
info := StrSplit(data[1], "|")
GuiControl,, Static3, % Round( info[2]*100 )
GuiControl,, Static4, % info[1]
}
WM_COPYDATA_READ(wp, lp) {
static info := [], timer := Func("SetInfo").Bind(info)
info[1] := StrGet(NumGet(lp + A_PtrSize*2), "UTF-16")
SetTimer, % timer, -10
Return true
}
GetModuleBitness(filePath) {
static MZ := 0x5A4D, type := {0x8664: 64, 0x14C: 32}
if !oFile := FileOpen(filePath, "r", "cp0")
throw Exception("Can't open file")
Loop 1 {
if !(oFile.ReadUShort() = MZ || res := 0)
break
oFile.Pos := 0x3C
PEoffset := oFile.ReadUInt()
oFile.Pos := PEoffset + 4
PE := oFile.ReadUShort()
res := type[PE]
}
oFile.Close()
Return res
}
GetScript() {
script =
(
#NoTrayIcon
#Persistent
SetBatchLines, -1
Critical
IAudioEndpointVolume := VA_GetAudioEndpointVolume("playback")
IAudioEndpointVolumeCallback := IAudioEndpointVolumeCallback_Create(IAudioEndpointVolume)
VA_IAudioEndpointVolume_RegisterControlChangeNotify(IAudioEndpointVolume, IAudioEndpointVolumeCallback)
OnExit( Func("Clear").Bind(IAudioEndpointVolume, IAudioEndpointVolumeCallback) )
Return
Clear(IAudioEndpointVolume, IAudioEndpointVolumeCallback) {
VA_IAudioEndpointVolume_UnregisterControlChangeNotify(IAudioEndpointVolume, IAudioEndpointVolumeCallback)
ObjRelease(IAudioEndpointVolume)
}
IAudioEndpointVolumeCallback_Create(aev) {
static VTBL := [ "QueryInterface"
, "AddRef"
, "Release"
, "OnNotify" ]
, heapSize := A_PtrSize*10
, heapOffset := A_PtrSize*9
, flags := (HEAP_GENERATE_EXCEPTIONS := 0x4) | (HEAP_NO_SERIALIZE := 0x1)
, HEAP_ZERO_MEMORY := 0x8
hHeap := DllCall("HeapCreate", "UInt", flags, "Ptr", 0, "Ptr", 0, "Ptr")
addr := IAudioEndpointVolumeCallback := DllCall("HeapAlloc", "Ptr", hHeap, "UInt", HEAP_ZERO_MEMORY, "Ptr", heapSize, "Ptr")
addr := NumPut(addr + A_PtrSize, addr + 0)
for k, v in VTBL
addr := NumPut( RegisterCallback("IAudioEndpointVolumeCallback_" . v, "F"), addr + 0 )
NumPut(hHeap, IAudioEndpointVolumeCallback + heapOffset)
Return IAudioEndpointVolumeCallback
}
IAudioEndpointVolumeCallback_QueryInterface(this, riid, ppvObject) {
Return 0 ; S_OK
}
IAudioEndpointVolumeCallback_AddRef(this) {
static refOffset := A_PtrSize*8
NumPut(refCount := NumGet(this + refOffset, "UInt") + 1, this + refOffset, "UInt")
Return refCount
}
IAudioEndpointVolumeCallback_Release(this) {
static refOffset := A_PtrSize*8
, heapOffset := A_PtrSize*9
NumPut(refCount := NumGet(this + refOffset, "UInt") - 1, this + refOffset, "UInt")
if (refCount = 0) {
hHeap := NumGet(this + heapOffset)
DllCall("HeapDestroy", "Ptr", hHeap)
}
Return refCount
}
IAudioEndpointVolumeCallback_OnNotify(this, pNotify) {
SendString( NumGet(pNotify + 16, "UInt") . "|" . NumGet(pNotify + 20, "Float"), %A_ScriptHwnd% )
Return 0
}
SendString(string, hWnd) {
VarSetCapacity(message, size := StrPut(string, "UTF-16")*2, 0)
StrPut(string, &message, "UTF-16")
VarSetCapacity(COPYDATASTRUCT, A_PtrSize*3)
NumPut(size, COPYDATASTRUCT, A_PtrSize, "UInt")
NumPut(&message, COPYDATASTRUCT, A_PtrSize*2)
DllCall("SendMessage", "Ptr", hWnd, "UInt", WM_COPYDATA := 0x4A, "Ptr", 0, "Ptr", ©DATASTRUCT)
}
)
Return script
}
Last edited by teadrinker on 04 Dec 2019, 23:35, edited 3 times in total.
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Hi teadrinker,
I prefer to use a script that does not need AutoHotkey.dll. Any chance of getting the prior script to work without freezing? Thanks, Joe
I prefer to use a script that does not need AutoHotkey.dll. Any chance of getting the prior script to work without freezing? Thanks, Joe
-
- Posts: 4331
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
The problem is that IAudioEndpointVolumeCallback works in another thread. If this thread intersects with the script's main thread, this may cause crash or freeze. You could using another script instead of AutoHotkey.dll according to the same principle.
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Thanks for explaining that. I integrated your previous code (not the AutoHotkey.dll version) into my horizontal-volume-slider script and I see what you mean about crashes and freezes...I've gotten both, although infrequently. I'd like to experiment your AutoHotkey.dll version...where can I get the AutoHotkey.dll that you use?teadrinker wrote:If this thread intersects with the script's main thread, this may cause crash or freeze.
I'd like to experiment with that, too, but I don't understand exactly what you mean. Please explain a little more. Thanks very much!teadrinker wrote:You could using another script instead of AutoHotkey.dll according to the same principle.
Regards, Joe
-
- Posts: 4331
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
You could get it (or them for different bitness) from here.JoeWinograd wrote: ↑where can I get the AutoHotkey.dll that you use?
I meant this:JoeWinograd wrote: ↑I don't understand exactly what you mean. Please explain a little more.
Code: Select all
Gui, +AlwaysOnTop
Gui, Font, s16
Gui, Add, Text, y13, Volume:
Gui, Add, Text, xp y+5 wp right, Muted:
Gui, Add, Text, x+3 y13 left, 100
Gui, Add, Text, xp y+5, 0
GuiControl,, Static3, % Round( VA_GetMasterVolume() )
GuiControl,, Static4, % VA_GetMasterMute()
Gui, Show
PID := ExecScript( GetScript() )
OnExit( Func("CloseChildScript").Bind(PID) )
OnMessage(0x4A, "WM_COPYDATA_READ")
Return
CloseChildScript(PID) {
static WM_COMMAND := 0x111, ID_FILE_TERMINATESCRIPT := 65405
DetectHiddenWindows, On
PostMessage, WM_COMMAND, ID_FILE_TERMINATESCRIPT,,, ahk_pid %PID%
}
GuiClose() {
ExitApp
}
SetInfo(data) {
info := StrSplit(data[1], "|")
GuiControl,, Static3, % Round( info[2]*100 )
GuiControl,, Static4, % info[1]
}
WM_COPYDATA_READ(wp, lp) {
static info := [], timer := Func("SetInfo").Bind(info)
info[1] := StrGet(NumGet(lp + A_PtrSize*2), "UTF-16")
SetTimer, % timer, -10
Return true
}
ExecScript(script, exePath := "") {
(!exePath && exePath := A_AhkPath)
shell := ComObjCreate("WScript.Shell")
exec := shell.Exec(exePath . " *")
exec.StdIn.Write(script)
exec.StdIn.Close()
return exec.ProcessID
}
GetScript() {
script =
(
#NoTrayIcon
#Persistent
SetBatchLines, -1
Critical
IAudioEndpointVolume := VA_GetAudioEndpointVolume("playback")
IAudioEndpointVolumeCallback := IAudioEndpointVolumeCallback_Create(IAudioEndpointVolume)
VA_IAudioEndpointVolume_RegisterControlChangeNotify(IAudioEndpointVolume, IAudioEndpointVolumeCallback)
OnExit( Func("Clear").Bind(IAudioEndpointVolume, IAudioEndpointVolumeCallback) )
Return
Clear(IAudioEndpointVolume, IAudioEndpointVolumeCallback) {
VA_IAudioEndpointVolume_UnregisterControlChangeNotify(IAudioEndpointVolume, IAudioEndpointVolumeCallback)
ObjRelease(IAudioEndpointVolumeCallback)
ObjRelease(IAudioEndpointVolume)
}
IAudioEndpointVolumeCallback_Create(aev) {
static VTBL := [ "QueryInterface"
, "AddRef"
, "Release"
, "OnNotify" ]
, heapSize := A_PtrSize*10
, heapOffset := A_PtrSize*9
, flags := (HEAP_GENERATE_EXCEPTIONS := 0x4) | (HEAP_NO_SERIALIZE := 0x1)
, HEAP_ZERO_MEMORY := 0x8
hHeap := DllCall("HeapCreate", "UInt", flags, "Ptr", 0, "Ptr", 0, "Ptr")
addr := IAudioEndpointVolumeCallback := DllCall("HeapAlloc", "Ptr", hHeap, "UInt", HEAP_ZERO_MEMORY, "Ptr", heapSize, "Ptr")
addr := NumPut(addr + A_PtrSize, addr + 0)
for k, v in VTBL
addr := NumPut( RegisterCallback("IAudioEndpointVolumeCallback_" . v, "F"), addr + 0 )
NumPut(hHeap, IAudioEndpointVolumeCallback + heapOffset)
Return IAudioEndpointVolumeCallback
}
IAudioEndpointVolumeCallback_QueryInterface(this, riid, ppvObject) {
Return 0 ; S_OK
}
IAudioEndpointVolumeCallback_AddRef(this) {
static refOffset := A_PtrSize*8
NumPut(refCount := NumGet(this + refOffset, "UInt") + 1, this + refOffset, "UInt")
Return refCount
}
IAudioEndpointVolumeCallback_Release(this) {
static refOffset := A_PtrSize*8
, heapOffset := A_PtrSize*9
NumPut(refCount := NumGet(this + refOffset, "UInt") - 1, this + refOffset, "UInt")
if (refCount = 0) {
hHeap := NumGet(this + heapOffset)
DllCall("HeapDestroy", "Ptr", hHeap)
}
Return refCount
}
IAudioEndpointVolumeCallback_OnNotify(this, pNotify) {
SendString( NumGet(pNotify + 16, "UInt") . "|" . NumGet(pNotify + 20, "Float"), %A_ScriptHwnd% )
Return 0
}
SendString(string, hWnd) {
VarSetCapacity(message, size := StrPut(string, "UTF-16")*2, 0)
StrPut(string, &message, "UTF-16")
VarSetCapacity(COPYDATASTRUCT, A_PtrSize*3)
NumPut(size, COPYDATASTRUCT, A_PtrSize, "UInt")
NumPut(&message, COPYDATASTRUCT, A_PtrSize*2)
DllCall("SendMessage", "Ptr", hWnd, "UInt", WM_COPYDATA := 0x4A, "Ptr", 0, "Ptr", ©DATASTRUCT)
}
)
Return script
}
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
I'm getting "Call to nonexistent function" for IAudioEndpointVolume := VA_GetAudioEndpointVolume("playback") even though the #Include VA.ahk file is there (and it works fine in the prior script). I even tried removing the #Include and putting the code in the script...same result. Here's the error dialog:
Note that it says the error is on line 6, although the call is on line 56 in your script. Thanks for any insight on this. Regards, Joe
Note that it says the error is on line 6, although the call is on line 56 in your script. Thanks for any insight on this. Regards, Joe
-
- Posts: 4331
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Add #Include VA.ahk into child script's code.
Code: Select all
script =
(
#Include VA.ahk
#NoTrayIcon
#Persistent
SetBatchLines, -1
...
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Ah, thanks for that...a quick test shows that it solves the nonexistent-function-call problem. Will test it thoroughly during the weekend on W7 and W10, and let you know how it goes. Thanks very much for your help. Regards, Joe
- JoeWinograd
- Posts: 2200
- Joined: 10 Feb 2014, 20:00
- Location: U.S. Central Time Zone
Re: Can an AutoHotkey script be notified of volume changing and muting/unmuting?
Hi teadrinker,
Sorry for the delay in getting back to you. I tried it on W7 and am getting more frequent crashes with it than with your first code, although the crashes occur only when my horizontal slider is on the screen while the volume is changed elsewhere, such as via the system tray speaker icon. Other than that, it works very well. My tray icon, a green (unmuted) or red (muted) music note and my tray tip (with the volume level) change immediately when the mute or volume are changed elsewhere. Thanks for your code! Regards, Joe
Sorry for the delay in getting back to you. I tried it on W7 and am getting more frequent crashes with it than with your first code, although the crashes occur only when my horizontal slider is on the screen while the volume is changed elsewhere, such as via the system tray speaker icon. Other than that, it works very well. My tray icon, a green (unmuted) or red (muted) music note and my tray tip (with the volume level) change immediately when the mute or volume are changed elsewhere. Thanks for your code! Regards, Joe