Advertisement
Guest User

TrayIcon library

a guest
Oct 6th, 2019
838
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; ----------------------------------------------------------------------------------------------------------------------
  2. ; Name ..........: TrayIcon library
  3. ; Description ...: Provide some useful functions to deal with Tray icons.
  4. ; AHK Version ...: AHK_L 1.1.22.02 x32/64 Unicode
  5. ; Original Author: Sean (http://goo.gl/dh0xIX) (http://www.autohotkey.com/forum/viewtopic.php?t=17314)
  6. ; Update Author .: Cyruz (http://ciroprincipe.info) (http://ahkscript.org/boards/viewtopic.php?f=6&t=1229)
  7. ; Mod Authors ...: Fanatic Guru, RiseUp
  8. ; License .......: WTFPL - http://www.wtfpl.net/txt/copying/
  9. ; Version Date...: 2017 - 11 - 24
  10. ; Note ..........: Many people have updated Sean's original work including me but Cyruz's version seemed the most straight
  11. ; ...............: forward update for 64 bit so I adapted it with some of the features from my Fanatic Guru version.
  12. ; Update 20160120: Went through all the data types in the DLL and NumGet and matched them up to MSDN which fixed IDcmd.
  13. ; Update 20160308: Fix for Windows 10 NotifyIconOverflowWindow
  14. ; Update 20171124: (RiseUp) Added extra Shell_TrayWnd to account for odd numbering (N) in ToolbarWindow32N
  15. ; ----------------------------------------------------------------------------------------------------------------------
  16.  
  17. ; ----------------------------------------------------------------------------------------------------------------------
  18. ; Function ......: TrayIcon_GetInfo
  19. ; Description ...: Get a series of useful information about tray icons.
  20. ; Parameters ....: sExeName  - The exe for which we are searching the tray icon data. Leave it empty to receive data for
  21. ; ...............:             all tray icons.
  22. ; Return ........: oTrayIcon_GetInfo - An array of objects containing tray icons data. Any entry is structured like this:
  23. ; ...............:             oTrayIcon_GetInfo[A_Index].idx     - 0 based tray icon index.
  24. ; ...............:             oTrayIcon_GetInfo[A_Index].IDcmd   - Command identifier associated with the button.
  25. ; ...............:             oTrayIcon_GetInfo[A_Index].pID     - Process ID.
  26. ; ...............:             oTrayIcon_GetInfo[A_Index].uID     - Application defined identifier for the icon.
  27. ; ...............:             oTrayIcon_GetInfo[A_Index].msgID   - Application defined callback message.
  28. ; ...............:             oTrayIcon_GetInfo[A_Index].hIcon   - Handle to the tray icon.
  29. ; ...............:             oTrayIcon_GetInfo[A_Index].hWnd    - Window handle.
  30. ; ...............:             oTrayIcon_GetInfo[A_Index].Class   - Window class.
  31. ; ...............:             oTrayIcon_GetInfo[A_Index].Process - Process executable.
  32. ; ...............:             oTrayIcon_GetInfo[A_Index].Tray    - Tray Type (Shell_TrayWnd or NotifyIconOverflowWindow).
  33. ; ...............:             oTrayIcon_GetInfo[A_Index].tooltip - Tray icon tooltip.
  34. ; Info ..........: TB_BUTTONCOUNT message - http://goo.gl/DVxpsg
  35. ; ...............: TB_GETBUTTON message   - http://goo.gl/2oiOsl
  36. ; ...............: TBBUTTON structure     - http://goo.gl/EIE21Z
  37. ; ----------------------------------------------------------------------------------------------------------------------
  38.  
  39. TrayIcon_GetInfo(sExeName := "")
  40. {
  41.     DetectHiddenWindows, % (Setting_A_DetectHiddenWindows := A_DetectHiddenWindows) ? "On" :
  42.     oTrayIcon_GetInfo := {}
  43.     For key, sTray in ["NotifyIconOverflowWindow", "Shell_TrayWnd", "Shell_TrayWnd"]
  44.     {
  45.         idxTB := TrayIcon_GetTrayBar()
  46.         WinGet, pidTaskbar, PID, ahk_class %sTray%
  47.        
  48.         hProc := DllCall("OpenProcess", UInt, 0x38, Int, 0, UInt, pidTaskbar)
  49.         pRB   := DllCall("VirtualAllocEx", Ptr, hProc, Ptr, 0, UPtr, 20, UInt, 0x1000, UInt, 0x4)
  50.  
  51.         if (SubStr(A_OSVersion,1,2)=10)
  52.             SendMessage, 0x418, 0, 0, ToolbarWindow32%key%, ahk_class %sTray%   ; TB_BUTTONCOUNT
  53.         else   
  54.             SendMessage, 0x418, 0, 0, ToolbarWindow32%idxTB%, ahk_class %sTray%   ; TB_BUTTONCOUNT
  55.        
  56.         szBtn := VarSetCapacity(btn, (A_Is64bitOS ? 32 : 20), 0)
  57.         szNfo := VarSetCapacity(nfo, (A_Is64bitOS ? 32 : 24), 0)
  58.         szTip := VarSetCapacity(tip, 128 * 2, 0)
  59.        
  60.         Loop, %ErrorLevel%
  61.         {
  62.             if (SubStr(A_OSVersion,1,2)=10)
  63.                 SendMessage, 0x417, A_Index - 1, pRB, ToolbarWindow32%key%, ahk_class %sTray%   ; TB_GETBUTTON
  64.             else
  65.                 SendMessage, 0x417, A_Index - 1, pRB, ToolbarWindow32%idxTB%, ahk_class %sTray%   ; TB_GETBUTTON
  66.             DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pRB, Ptr, &btn, UPtr, szBtn, UPtr, 0)
  67.  
  68.             iBitmap := NumGet(btn, 0, "Int")
  69.             IDcmd   := NumGet(btn, 4, "Int")
  70.             statyle := NumGet(btn, 8)
  71.             dwData  := NumGet(btn, (A_Is64bitOS ? 16 : 12))
  72.             iString := NumGet(btn, (A_Is64bitOS ? 24 : 16), "Ptr")
  73.  
  74.             DllCall("ReadProcessMemory", Ptr, hProc, Ptr, dwData, Ptr, &nfo, UPtr, szNfo, UPtr, 0)
  75.  
  76.             hWnd  := NumGet(nfo, 0, "Ptr")
  77.             uID   := NumGet(nfo, (A_Is64bitOS ? 8 : 4), "UInt")
  78.             msgID := NumGet(nfo, (A_Is64bitOS ? 12 : 8))
  79.             hIcon := NumGet(nfo, (A_Is64bitOS ? 24 : 20), "Ptr")
  80.  
  81.             WinGet, pID, PID, ahk_id %hWnd%
  82.             WinGet, sProcess, ProcessName, ahk_id %hWnd%
  83.             WinGetClass, sClass, ahk_id %hWnd%
  84.  
  85.             If !sExeName || (sExeName = sProcess) || (sExeName = pID)
  86.             {
  87.                 DllCall("ReadProcessMemory", Ptr, hProc, Ptr, iString, Ptr, &tip, UPtr, szTip, UPtr, 0)
  88.                 Index := (oTrayIcon_GetInfo.MaxIndex()>0 ? oTrayIcon_GetInfo.MaxIndex()+1 : 1)
  89.                 oTrayIcon_GetInfo[Index,"idx"]     := A_Index - 1
  90.                 oTrayIcon_GetInfo[Index,"IDcmd"]   := IDcmd
  91.                 oTrayIcon_GetInfo[Index,"pID"]     := pID
  92.                 oTrayIcon_GetInfo[Index,"uID"]     := uID
  93.                 oTrayIcon_GetInfo[Index,"msgID"]   := msgID
  94.                 oTrayIcon_GetInfo[Index,"hIcon"]   := hIcon
  95.                 oTrayIcon_GetInfo[Index,"hWnd"]    := hWnd
  96.                 oTrayIcon_GetInfo[Index,"Class"]   := sClass
  97.                 oTrayIcon_GetInfo[Index,"Process"] := sProcess
  98.                 oTrayIcon_GetInfo[Index,"Tooltip"] := StrGet(&tip, "UTF-16")
  99.                 oTrayIcon_GetInfo[Index,"Tray"]    := sTray
  100.             }
  101.         }
  102.         DllCall("VirtualFreeEx", Ptr, hProc, Ptr, pProc, UPtr, 0, Uint, 0x8000)
  103.         DllCall("CloseHandle", Ptr, hProc)
  104.     }
  105.     DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
  106.     Return oTrayIcon_GetInfo
  107. }
  108.  
  109. ; ----------------------------------------------------------------------------------------------------------------------
  110. ; Function .....: TrayIcon_Hide
  111. ; Description ..: Hide or unhide a tray icon.
  112. ; Parameters ...: IDcmd - Command identifier associated with the button.
  113. ; ..............: bHide - True for hide, False for unhide.
  114. ; ..............: sTray - 1 or Shell_TrayWnd || 0 or NotifyIconOverflowWindow.
  115. ; Info .........: TB_HIDEBUTTON message - http://goo.gl/oelsAa
  116. ; ----------------------------------------------------------------------------------------------------------------------
  117. TrayIcon_Hide(IDcmd, sTray := "Shell_TrayWnd", bHide:=True)
  118. {
  119.     (sTray == 0 ? sTray := "NotifyIconOverflowWindow" : sTray == 1 ? sTray := "Shell_TrayWnd" : )
  120.     DetectHiddenWindows, % (Setting_A_DetectHiddenWindows := A_DetectHiddenWindows) ? "On" :
  121.     idxTB := TrayIcon_GetTrayBar()
  122.     SendMessage, 0x404, IDcmd, bHide, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_HIDEBUTTON
  123.     SendMessage, 0x1A, 0, 0, , ahk_class %sTray%
  124.     DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
  125. }
  126.  
  127. ; ----------------------------------------------------------------------------------------------------------------------
  128. ; Function .....: TrayIcon_Delete
  129. ; Description ..: Delete a tray icon.
  130. ; Parameters ...: idx - 0 based tray icon index.
  131. ; ..............: sTray - 1 or Shell_TrayWnd || 0 or NotifyIconOverflowWindow.
  132. ; Info .........: TB_DELETEBUTTON message - http://goo.gl/L0pY4R
  133. ; ----------------------------------------------------------------------------------------------------------------------
  134. TrayIcon_Delete(idx, sTray := "Shell_TrayWnd")
  135. {
  136.     (sTray == 0 ? sTray := "NotifyIconOverflowWindow" : sTray == 1 ? sTray := "Shell_TrayWnd" : )
  137.     DetectHiddenWindows, % (Setting_A_DetectHiddenWindows := A_DetectHiddenWindows) ? "On" :
  138.     idxTB := TrayIcon_GetTrayBar()
  139.     SendMessage, 0x416, idx, 0, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_DELETEBUTTON
  140.     SendMessage, 0x1A, 0, 0, , ahk_class %sTray%
  141.     DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
  142. }
  143.  
  144. ; ----------------------------------------------------------------------------------------------------------------------
  145. ; Function .....: TrayIcon_Remove
  146. ; Description ..: Remove a tray icon.
  147. ; Parameters ...: hWnd, uID.
  148. ; ----------------------------------------------------------------------------------------------------------------------
  149. TrayIcon_Remove(hWnd, uID)
  150. {
  151.         NumPut(VarSetCapacity(NID,(A_IsUnicode ? 2 : 1) * 384 + A_PtrSize * 5 + 40,0), NID)
  152.         NumPut(hWnd , NID, (A_PtrSize == 4 ? 4 : 8 ))
  153.         NumPut(uID  , NID, (A_PtrSize == 4 ? 8  : 16 ))
  154.         Return DllCall("shell32\Shell_NotifyIcon", "Uint", 0x2, "Uint", &NID)
  155. }
  156.  
  157. ; ----------------------------------------------------------------------------------------------------------------------
  158. ; Function .....: TrayIcon_Move
  159. ; Description ..: Move a tray icon.
  160. ; Parameters ...: idxOld - 0 based index of the tray icon to move.
  161. ; ..............: idxNew - 0 based index where to move the tray icon.
  162. ; ..............: sTray - 1 or Shell_TrayWnd || 0 or NotifyIconOverflowWindow.
  163. ; Info .........: TB_MOVEBUTTON message - http://goo.gl/1F6wPw
  164. ; ----------------------------------------------------------------------------------------------------------------------
  165. TrayIcon_Move(idxOld, idxNew, sTray := "Shell_TrayWnd")
  166. {
  167.     (sTray == 0 ? sTray := "NotifyIconOverflowWindow" : sTray == 1 ? sTray := "Shell_TrayWnd" : )
  168.     DetectHiddenWindows, % (Setting_A_DetectHiddenWindows := A_DetectHiddenWindows) ? "On" :
  169.     idxTB := TrayIcon_GetTrayBar()
  170.     SendMessage, 0x452, idxOld, idxNew, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_MOVEBUTTON
  171.     DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
  172. }
  173.  
  174. ; ----------------------------------------------------------------------------------------------------------------------
  175. ; Function .....: TrayIcon_GetTrayBar
  176. ; Description ..: Get the tray icon handle.
  177. ; ----------------------------------------------------------------------------------------------------------------------
  178. TrayIcon_GetTrayBar()
  179. {
  180.     DetectHiddenWindows, % (Setting_A_DetectHiddenWindows := A_DetectHiddenWindows) ? "On" :
  181.     WinGet, ControlList, ControlList, ahk_class Shell_TrayWnd
  182.     RegExMatch(ControlList, "(?<=ToolbarWindow32)\d+(?!.*ToolbarWindow32)", nTB)
  183.     Loop, %nTB%
  184.     {
  185.         ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class Shell_TrayWnd
  186.         hParent := DllCall( "GetParent", Ptr, hWnd )
  187.         WinGetClass, sClass, ahk_id %hParent%
  188.         If (sClass <> "SysPager")
  189.             Continue
  190.         idxTB := A_Index
  191.         Break
  192.     }
  193.     DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
  194.     Return  idxTB
  195. }
  196.  
  197. ; ----------------------------------------------------------------------------------------------------------------------
  198. ; Function .....: TrayIcon_GetHotItem
  199. ; Description ..: Get the index of tray's hot item.
  200. ; Info .........: TB_GETHOTITEM message - http://goo.gl/g70qO2
  201. ; ----------------------------------------------------------------------------------------------------------------------
  202. TrayIcon_GetHotItem()
  203. {
  204.     idxTB := TrayIcon_GetTrayBar()
  205.     SendMessage, 0x447, 0, 0, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd ; TB_GETHOTITEM
  206.     Return ErrorLevel << 32 >> 32
  207. }
  208.  
  209. ; ----------------------------------------------------------------------------------------------------------------------
  210. ; Function .....: TrayIcon_Button
  211. ; Description ..: Simulate mouse button click on a tray icon.
  212. ; Parameters ...: sExeName - Executable Process Name of tray icon.
  213. ; ..............: sButton  - Mouse button to simulate (L, M, R).
  214. ; ..............: bDouble  - True to double click, false to single click.
  215. ; ..............: index    - Index of tray icon to click if more than one match.
  216. ; ----------------------------------------------------------------------------------------------------------------------
  217. TrayIcon_Button(sExeName, sButton := "L", bDouble := false, index := 1)
  218. {
  219.     DetectHiddenWindows, % (Setting_A_DetectHiddenWindows := A_DetectHiddenWindows) ? "On" :
  220.     WM_MOUSEMOVE      = 0x0200
  221.     WM_LBUTTONDOWN    = 0x0201
  222.     WM_LBUTTONUP      = 0x0202
  223.     WM_LBUTTONDBLCLK = 0x0203
  224.     WM_RBUTTONDOWN    = 0x0204
  225.     WM_RBUTTONUP      = 0x0205
  226.     WM_RBUTTONDBLCLK = 0x0206
  227.     WM_MBUTTONDOWN    = 0x0207
  228.     WM_MBUTTONUP      = 0x0208
  229.     WM_MBUTTONDBLCLK = 0x0209
  230.     sButton := "WM_" sButton "BUTTON"
  231.     oIcons := {}
  232.     oIcons := TrayIcon_GetInfo(sExeName)
  233.     msgID  := oIcons[index].msgID
  234.     uID    := oIcons[index].uID
  235.     hWnd   := oIcons[index].hWnd
  236.     if bDouble
  237.         PostMessage, msgID, uID, %sButton%DBLCLK, , ahk_id %hWnd%
  238.     else
  239.     {
  240.         PostMessage, msgID, uID, %sButton%DOWN, , ahk_id %hWnd%
  241.         PostMessage, msgID, uID, %sButton%UP, , ahk_id %hWnd%
  242.     }
  243.     DetectHiddenWindows, %Setting_A_DetectHiddenWindows%
  244.     return
  245. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement