Advertisement
Vince42

TrayIcon.ahk

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