Need help identifying the volume tray icon for TrayIcon.ahk Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
MiM
Posts: 61
Joined: 20 Apr 2021, 04:31

Need help identifying the volume tray icon for TrayIcon.ahk

Post by MiM » 10 Aug 2022, 19:39

It's process is explorer.exe so that won't work.
I've tried using VA.ahk to get the default sound device name and using that target it through it's tooltip but it's wonky and might not work for everyone.
Any ideas?

User avatar
mikeyww
Posts: 26883
Joined: 09 Sep 2014, 18:38

Re: Need help identifying the volume tray icon for TrayIcon.ahk

Post by mikeyww » 10 Aug 2022, 19:46

Code: Select all

/* Sound ---------------------------------------------------------------------------------------
This AutoHotkey script reports the name of the default speaker, and the speaker's volume level.
Cheaters' technique
https://www.nirsoft.net/utils/sound_volume_view.html
------------------------------------------------------------------------------------------------
*/
Gui, Speaker:New, +AlwaysOnTop, Speaker
Gui, Font, s12
Gui, Color, FFFF9E
Gui, Add, Text, w250 Center, % (speaker := speaker()).1
Gui, Add, Progress, wp h30 cBlue Border, % speaker.2
Gui, Add, Text, wp Center, % speaker.2 "%"
Gui, Show, x100 y100

Esc::
SpeakerGuiClose:
ExitApp

speaker() {
 Static out := A_ScriptDir "\sounds.csv"
 RunWait, d:\utils\soundVolumeView\SoundVolumeView.exe /scomma "%out%"
 Loop, Read, %out%                                                         ; Process each line
  Loop, Parse, A_LoopReadLine, CSV                                         ; Process each column
   Switch A_Index {                                                        ; Column number
    Case DEVICENAME := 4: speaker := A_LoopField
    Case DEFAULT    := 5: If (A_LoopField != "Render")
                           Break                                           ; Skip rest of current line
    Case CHANNELS   := 9: Return [speaker, Round(RegExReplace(A_LoopField, "%.+"))]
   }
}

User avatar
MiM
Posts: 61
Joined: 20 Apr 2021, 04:31

Re: Need help identifying the volume tray icon for TrayIcon.ahk

Post by MiM » 10 Aug 2022, 19:52

Without external software (:

User avatar
MiM
Posts: 61
Joined: 20 Apr 2021, 04:31

Re: Need help identifying the volume tray icon for TrayIcon.ahk

Post by MiM » 10 Aug 2022, 21:54

I was thinking about regexing all the possible tooltips:
RemoteNetworkDevice
Speakers
LineLevel
Headphones
Microphone
Headset
Handset
UnknownDigitalPassthrough
SPDIF
HDMI
UnknownFormFactor
(taken from microsoft docs)
so if tooltip contains for example "Headphones" and ends with either a percent sign or "Muted", then it's the right tray icon.
But again, that's so wonky..

User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: Need help identifying the volume tray icon for TrayIcon.ahk

Post by JoeWinograd » 11 Aug 2022, 03:36

MiM wrote:all the possible tooltips
Problem is, that list does not have all the possible tooltips. For example, here's a tooltip from a Dell computer that a client of mine has:

dell speakers tooltip.png
dell speakers tooltip.png (5.77 KiB) Viewed 449 times

Regards, Joe

User avatar
MiM
Posts: 61
Joined: 20 Apr 2021, 04:31

Re: Need help identifying the volume tray icon for TrayIcon.ahk  Topic is solved

Post by MiM » 11 Aug 2022, 14:04

Welp this will do

Code: Select all

#SingleInstance, Force
SetBatchLines, -1
Return

F1::
ShowTrayVolume(A_ScreenWidth, A_ScreenHeight)
Return

ShowTrayVolume(x = 0, y = 0) {
  ;----------------------------------------------------------------;
  ;                   Big thanks to TrayIcon.ahk                   ;
  ;     https://www.autohotkey.com/boards/viewtopic.php?t=1229     ;
  ;----------------------------------------------------------------;
  ;                     !!!Important notes!!!                      ;
  ; • x,y only works for Windows < 10                              ;
  ; • x,y is the center of the window, not the top left corner     ;
  ; • rapidly changing the position is wonky, be sure to add sleep ;
  ; • window adjusts it's position if coords aren't in client area ;
  ;  (so A_ScreenWidth, A_ScreenHeight is the bottom right corner) ;
  ;----------------------------------------------------------------;
  Static VolumeTrayIcon, TI := {}, OSCheck := A_OSVersion >= "10." && A_OSVersion < "W"
  DetectHiddenWindows, % (Setting_A_DetectHiddenWindows:=A_DetectHiddenWindows)?"On":
  if !VolumeTrayIcon && OSCheck {
    For key, sTray in ["Shell_TrayWnd", "NotifyIconOverflowWindow"] {
      WinGet,ControlList,ControlList,ahk_class %sTray%
      RegExMatch(ControlList,"(?<=ToolbarWindow32)\d+(?!.*ToolbarWindow32)",nTB)
      Loop, %nTB% {
        ControlGet,hWnd,hWnd,,ToolbarWindow32%A_Index%,ahk_class %sTray%
        WinGetClass,sClass,% "ahk_id " DllCall("GetParent",Ptr,hWnd)
        if !(sClass = "SysPager" or sClass = "NotifyIconOverflowWindow")
          Continue
        idxTB:=A_Index
        Break
      }
      WinGet,pidTaskbar,PID,ahk_class %sTray%
      hProc:=DllCall("OpenProcess",UInt,0x38,Int,0,UInt,pidTaskbar)
      pRB:=DllCall("VirtualAllocEx",Ptr,hProc,Ptr,0,UPtr,20,UInt,0x1000,UInt,0x4)
      SendMessage,0x418,0,0,ToolbarWindow32%idxTB%,ahk_class %sTray%
      szBtn:=VarSetCapacity(btn,(A_Is64bitOS?32:20),0)
      szNfo:=VarSetCapacity(nfo,(A_Is64bitOS?32:24),0)
      szTip:=VarSetCapacity(tip,128*2,0)
      Loop, %ErrorLevel% {
        SendMessage,0x417,A_Index-1,pRB,ToolbarWindow32%idxTB%,ahk_class %sTray%
        DllCall("ReadProcessMemory",Ptr,hProc,Ptr,pRB,Ptr,&btn,UPtr,szBtn,UPtr,0)
        dwData:=NumGet(btn,(A_Is64bitOS?16:12))
        iString:=NumGet(btn,(A_Is64bitOS?24:16),"Ptr")
        DllCall("ReadProcessMemory",Ptr,hProc,Ptr,dwData,Ptr,&nfo, UPtr,szNfo,UPtr,0)
        hWnd:=NumGet(nfo,0,"Ptr"),msgID:=NumGet(nfo,(A_Is64bitOS?12:8))
        WinGet,pID,PID,ahk_id %hWnd%
        WinGet,sProcess,ProcessName,ahk_id %hWnd%
        WinGet,sStyle,Style,ahk_id %hWnd%
        Index:=(TI.MaxIndex()>0?TI.MaxIndex()+1:1)
        DllCall("ReadProcessMemory",Ptr,hProc,Ptr,iString,Ptr,&tip,UPtr,szTip,UPtr, 0)
        TI[Index,"msgID"]:=msgID,TI[Index,"hWnd"]:=hWnd,TI[Index,"Process"]:=sProcess
        TI[Index,"Style"]:=sStyle,TI[Index,"Tooltip"]:=StrGet(&tip, "UTF-16")
      }
      DllCall("VirtualFreeEx",Ptr,hProc,Ptr,pRB,UPtr,0,Uint,0x8000)
      DllCall("CloseHandle",Ptr,hProc)
    }
    Loop, % TI.MaxIndex()
      if (TI[A_Index].Style = "0x84000000") && (TI[A_Index].Process = "explorer.exe")
      && ((SubStr(TI[A_Index].tooltip, 0) = "%") || (SubStr(TI[A_Index].tooltip, -4) = "muted")) {
        VolumeTrayIcon:={"msgID":TI[A_Index].msgID,"Hwnd":"ahk_id " TI[A_Index].hWnd}
        Break
      }
  }
  if (OSCheck)
    PostMessage, VolumeTrayIcon.msgID,, 1024,, % VolumeTrayIcon.Hwnd
  else
    Run, % A_WinDir "\System32\SndVol.exe -f " (x&0xFFFF)|((y&0xFFFF)<<16)
  DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
}
Specifically,

Code: Select all

if (TI[A_Index].Style = "0x84000000") && (TI[A_Index].Process = "explorer.exe")
&& ((SubStr(TI[A_Index].tooltip, 0) = "%") || (SubStr(TI[A_Index].tooltip, -4) = "muted")) {
  VolumeTrayIcon:={"msgID":TI[A_Index].msgID,"Hwnd":"ahk_id " TI[A_Index].hWnd}
  Break
}
if the style is 0x84000000
if the process name is explorer.exe
(some other tray icons can be the same but whatever, this is mainly for narrowing down the volume icon)
and finally, if the tooltip ends with either "%" or "muted".

Tested on Win7, Win8.1, Win10, Win11 (Virtual Machines)

Post Reply

Return to “Ask for Help (v1)”