Created
July 3, 2017 05:07
-
-
Save tmplinshi/83c52a9dffe65c105803d026ca1a07da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ---------------------------------------------------------------------------------------------------------------------- | |
; Name ..........: TrayIcon library | |
; Description ...: Provide some useful functions to deal with Tray icons. | |
; AHK Version ...: AHK_L 1.1.13.01 x32/64 Unicode | |
; Original Author: Sean (http://goo.gl/dh0xIX) (http://www.autohotkey.com/forum/viewtopic.php?t=17314) | |
; Update Author .: Cyruz (http://ciroprincipe.info) (http://ahkscript.org/boards/viewtopic.php?f=6&t=1229) | |
; Mod Author ....: Fanatic Guru | |
; License .......: WTFPL - http://www.wtfpl.net/txt/copying/ | |
; Version Date...: 2014 - 01 - 16 | |
; Note ..........: Many people have updated Sean's original work including me but Cyruz's version seemed the most straight | |
; ...............: forward update for 64 bit so I adapted it with some of the features from my Fanatic Guru version. | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function ......: TrayIcon_GetInfo | |
; Description ...: Get a series of useful information about tray icons. | |
; Parameters ....: sExeName - The exe for which we are searching the tray icon data. Leave it empty to receive data for | |
; ...............: all tray icons. | |
; Return ........: oTrayIcon_GetInfo - An array of objects containing tray icons data. Any entry is structured like this: | |
; ...............: oTrayIcon_GetInfo[A_Index].idx - 0 based tray icon index. | |
; ...............: oTrayIcon_GetInfo[A_Index].cmdID - Command identifier associated with the button. | |
; ...............: oTrayIcon_GetInfo[A_Index].pID - Process ID. | |
; ...............: oTrayIcon_GetInfo[A_Index].uID - Application defined identifier for the icon. | |
; ...............: oTrayIcon_GetInfo[A_Index].msgID - Application defined callback message. | |
; ...............: oTrayIcon_GetInfo[A_Index].hIcon - Handle to the tray icon. | |
; ...............: oTrayIcon_GetInfo[A_Index].hWnd - Window handle. | |
; ...............: oTrayIcon_GetInfo[A_Index].Class - Window class. | |
; ...............: oTrayIcon_GetInfo[A_Index].Process - Process executable. | |
; ...............: oTrayIcon_GetInfo[A_Index].Tray - Tray Type (Shell_TrayWnd or NotifyIconOverflowWindow). | |
; ...............: oTrayIcon_GetInfo[A_Index].tooltip - Tray icon tooltip. | |
; Info ..........: TB_BUTTONCOUNT message - http://goo.gl/DVxpsg | |
; ...............: TB_GETBUTTON message - http://goo.gl/2oiOsl | |
; ...............: TBBUTTON structure - http://goo.gl/EIE21Z | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_GetInfo(sExeName := "") | |
{ | |
Setting_A_DetectHiddenWindows := A_DetectHiddenWindows | |
DetectHiddenWindows, On | |
oTrayIcon_GetInfo := {} | |
For key, sTray in ["Shell_TrayWnd","NotifyIconOverflowWindow"] | |
{ | |
idxTB := TrayIcon_GetTrayBar() | |
WinGet, pidTaskbar, PID, ahk_class %sTray% | |
hProc := DllCall("OpenProcess", UInt, 0x38, Int, 0, UInt, pidTaskbar) | |
pRB := DllCall("VirtualAllocEx", Ptr, hProc, Ptr, 0, UInt, 20, UInt, 0x1000, UInt, 0x4) | |
SendMessage, 0x418, 0, 0, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_BUTTONCOUNT | |
szBtn := VarSetCapacity(btn, (A_Is64bitOS ? 32 : 24)) | |
szNfo := VarSetCapacity(nfo, (A_Is64bitOS ? 32 : 24)) | |
szTip := VarSetCapacity(tip, 128 * 2) | |
Loop, %ErrorLevel% | |
{ | |
SendMessage, 0x417, A_Index - 1, pRB, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_GETBUTTON | |
DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pRB, Ptr, &btn, UInt, szBtn, UInt, 0) | |
iBitmap := NumGet(btn, 0) | |
cmdID := NumGet(btn, 4) | |
statyle := NumGet(btn, 8) | |
dwData := NumGet(btn, (A_Is64bitOS ? 16 : 12)) | |
iString := NumGet(btn, (A_Is64bitOS ? 24 : 16)) | |
DllCall("ReadProcessMemory", Ptr, hProc, Ptr, dwData, Ptr, &nfo, UInt, szNfo, UInt, 0) | |
hWnd := NumGet(nfo, 0) | |
uID := NumGet(nfo, (A_Is64bitOS ? 8 : 4)) | |
msgID := NumGet(nfo, (A_Is64bitOS ? 12 : 8)) | |
hIcon := NumGet(nfo, (A_Is64bitOS ? 24 : 20)) | |
WinGet, pID, PID, ahk_id %hWnd% | |
WinGet, sProcess, ProcessName, ahk_id %hWnd% | |
WinGetClass, sClass, ahk_id %hWnd% | |
If !sExeName || (sExeName = sProcess) || (sExeName = pID) | |
{ | |
DllCall("ReadProcessMemory", Ptr, hProc, Ptr, iString, Ptr, &tip, UInt, szTip, UInt, 0) | |
Index := (oTrayIcon_GetInfo.MaxIndex()>0 ? oTrayIcon_GetInfo.MaxIndex()+1 : 1) | |
oTrayIcon_GetInfo[Index,"idx"] := A_Index - 1 | |
oTrayIcon_GetInfo[Index,"cmdID"] := cmdID | |
oTrayIcon_GetInfo[Index,"pID"] := pID | |
oTrayIcon_GetInfo[Index,"uID"] := uID | |
oTrayIcon_GetInfo[Index,"msgID"] := msgID | |
oTrayIcon_GetInfo[Index,"hIcon"] := hIcon | |
oTrayIcon_GetInfo[Index,"hWnd"] := hWnd | |
oTrayIcon_GetInfo[Index,"Class"] := sClass | |
oTrayIcon_GetInfo[Index,"Process"] := sProcess | |
oTrayIcon_GetInfo[Index,"Tooltip"] := StrGet(&tip, "UTF-16") | |
oTrayIcon_GetInfo[Index,"Tray"] := sTray | |
} | |
} | |
DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pProc, "Uint", 0, "Uint", 0x8000) | |
DllCall("CloseHandle", "Uint", hProc) | |
} | |
DetectHiddenWindows, %Setting_A_DetectHiddenWindows% | |
Return oTrayIcon_GetInfo | |
} | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function .....: TrayIcon_Hide | |
; Description ..: Hide or unhide a tray icon. | |
; Parameters ...: cmdID - Command identifier associated with the button. | |
; ..............: bHide - True for hide, False for unhide. | |
; ..............: sTray - 1 or Shell_TrayWnd || 0 or NotifyIconOverflowWindow. | |
; Info .........: TB_HIDEBUTTON message - http://goo.gl/oelsAa | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_Hide(cmdID, sTray := "Shell_TrayWnd", bHide:=True) | |
{ | |
(sTray == 0 ? sTray := "NotifyIconOverflowWindow" : sTray == 1 ? sTray := "Shell_TrayWnd" : ) | |
Setting_A_DetectHiddenWindows := A_DetectHiddenWindows | |
DetectHiddenWindows, On | |
idxTB := TrayIcon_GetTrayBar() | |
SendMessage, 0x404, cmdID, bHide, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_HIDEBUTTON | |
SendMessage, 0x1A, 0, 0, , ahk_class %sTray% | |
DetectHiddenWindows, %Setting_A_DetectHiddenWindows% | |
} | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function .....: TrayIcon_Delete | |
; Description ..: Delete a tray icon. | |
; Parameters ...: idx - 0 based tray icon index. | |
; ..............: sTray - 1 or Shell_TrayWnd || 0 or NotifyIconOverflowWindow. | |
; Info .........: TB_DELETEBUTTON message - http://goo.gl/L0pY4R | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_Delete(idx, sTray := "Shell_TrayWnd") | |
{ | |
(sTray == 0 ? sTray := "NotifyIconOverflowWindow" : sTray == 1 ? sTray := "Shell_TrayWnd" : ) | |
Setting_A_DetectHiddenWindows := A_DetectHiddenWindows | |
DetectHiddenWindows, On | |
idxTB := TrayIcon_GetTrayBar() | |
SendMessage, 0x416, idx, 0, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_DELETEBUTTON | |
SendMessage, 0x1A, 0, 0, , ahk_class %sTray% | |
DetectHiddenWindows, %Setting_A_DetectHiddenWindows% | |
} | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function .....: TrayIcon_Remove | |
; Description ..: Remove a tray icon. | |
; Parameters ...: hWnd, uID. | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_Remove(hWnd, uID) | |
{ | |
NumPut(VarSetCapacity(NID,(A_IsUnicode ? 2 : 1) * 384 + A_PtrSize * 5 + 40,0), NID) | |
NumPut(hWnd , NID, (A_PtrSize == 4 ? 4 : 8 )) | |
NumPut(uID , NID, (A_PtrSize == 4 ? 8 : 16 )) | |
Return DllCall("shell32\Shell_NotifyIcon", "Uint", 0x2, "Uint", &NID) | |
} | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function .....: TrayIcon_Move | |
; Description ..: Move a tray icon. | |
; Parameters ...: idxOld - 0 based index of the tray icon to move. | |
; ..............: idxNew - 0 based index where to move the tray icon. | |
; ..............: sTray - 1 or Shell_TrayWnd || 0 or NotifyIconOverflowWindow. | |
; Info .........: TB_MOVEBUTTON message - http://goo.gl/1F6wPw | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_Move(idxOld, idxNew, sTray := "Shell_TrayWnd") | |
{ | |
(sTray == 0 ? sTray := "NotifyIconOverflowWindow" : sTray == 1 ? sTray := "Shell_TrayWnd" : ) | |
Setting_A_DetectHiddenWindows := A_DetectHiddenWindows | |
DetectHiddenWindows, On | |
idxTB := TrayIcon_GetTrayBar() | |
SendMessage, 0x452, idxOld, idxNew, ToolbarWindow32%idxTB%, ahk_class %sTray% ; TB_MOVEBUTTON | |
DetectHiddenWindows, %Setting_A_DetectHiddenWindows% | |
} | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function .....: TrayIcon_GetTrayBar | |
; Description ..: Get the tray icon handle. | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_GetTrayBar() | |
{ | |
Setting_A_DetectHiddenWindows := A_DetectHiddenWindows | |
DetectHiddenWindows, On | |
WinGet, ControlList, ControlList, ahk_class Shell_TrayWnd | |
RegExMatch(ControlList, "(?<=ToolbarWindow32)\d+(?!.*ToolbarWindow32)", nTB) | |
Loop, %nTB% | |
{ | |
ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class Shell_TrayWnd | |
hParent := DllCall( "GetParent", Ptr, hWnd ) | |
WinGetClass, sClass, ahk_id %hParent% | |
If (sClass <> "SysPager") | |
Continue | |
idxTB := A_Index | |
Break | |
} | |
DetectHiddenWindows, %Setting_A_DetectHiddenWindows% | |
Return idxTB | |
} | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function .....: TrayIcon_GetHotItem | |
; Description ..: Get the index of tray's hot item. | |
; Info .........: TB_GETHOTITEM message - http://goo.gl/g70qO2 | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_GetHotItem() | |
{ | |
idxTB := TrayIcon_GetTrayBar() | |
SendMessage, 0x447, 0, 0, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd ; TB_GETHOTITEM | |
Return ErrorLevel << 32 >> 32 | |
} | |
; ---------------------------------------------------------------------------------------------------------------------- | |
; Function .....: TrayIcon_Button | |
; Description ..: Simulate mouse button click on a tray icon. | |
; Parameters ...: sExeName - Executable Process Name of tray icon. | |
; ..............: sButton - Mouse button to simulate (L, M, R). | |
; ..............: bDouble - True to double click, false to single click. | |
; ..............: index - Index of tray icon to click if more than one match. | |
; ---------------------------------------------------------------------------------------------------------------------- | |
TrayIcon_Button(sExeName, sButton := "L", bDouble := false, index := 1) | |
{ | |
Setting_A_DetectHiddenWindows := A_DetectHiddenWindows | |
DetectHiddenWindows, On | |
WM_MOUSEMOVE = 0x0200 | |
WM_LBUTTONDOWN = 0x0201 | |
WM_LBUTTONUP = 0x0202 | |
WM_LBUTTONDBLCLK = 0x0203 | |
WM_RBUTTONDOWN = 0x0204 | |
WM_RBUTTONUP = 0x0205 | |
WM_RBUTTONDBLCLK = 0x0206 | |
WM_MBUTTONDOWN = 0x0207 | |
WM_MBUTTONUP = 0x0208 | |
WM_MBUTTONDBLCLK = 0x0209 | |
sButton := "WM_" sButton "BUTTON" | |
oIcons := {} | |
oIcons := TrayIcon_GetInfo(sExeName) | |
msgID := oIcons[index].msgID | |
uID := oIcons[index].uID | |
hWnd := oIcons[index].hWnd | |
if bDouble | |
PostMessage, msgID, uID, %sButton%DBLCLK, , ahk_id %hWnd% | |
else | |
{ | |
PostMessage, msgID, uID, %sButton%DOWN, , ahk_id %hWnd% | |
PostMessage, msgID, uID, %sButton%UP, , ahk_id %hWnd% | |
} | |
DetectHiddenWindows, %Setting_A_DetectHiddenWindows% | |
return | |
} |
@tmplinshi I'm new to autohotkey, would you mind to give me an example of how to use TrayIcon_GetInfo(sExeName := "")
to find out the cmdID? And after I find that, do I just modify the cmdID in this code TrayIcon_Hide(cmdID, sTray := "Shell_TrayWnd", bHide:=True)
? Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The latest version and original topic is available on the AutoHotkey forums.