用法可以参考v1版本,站内有相关文章:【操作托盘图标】TrayIcon
刚入V2,转换v1代码可能有所疏漏,欢迎指正。
;----------------------------------------------------------------------------------------------------------------------
; 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 ........: oTrayInfo - An array of objects containing tray icons data. Any entry is structured like this:
; ...............: oTrayInfo[A_Index].idx - 0 based tray icon index.
; ...............: oTrayInfo[A_Index].idcmd - Command identifier associated with the button.
; ...............: oTrayInfo[A_Index].pid - Process ID.
; ...............: oTrayInfo[A_Index].uid - Application defined identifier for the icon.
; ...............: oTrayInfo[A_Index].msgid - Application defined callback message.
; ...............: oTrayInfo[A_Index].hicon - Handle to the tray icon.
; ...............: oTrayInfo[A_Index].hwnd - Window handle.
; ...............: oTrayInfo[A_Index].class - Window class.
; ...............: oTrayInfo[A_Index].process - Process executable.
; ...............: oTrayInfo[A_Index].tray - Tray Type (Shell_TrayWnd or NotifyIconOverflowWindow).
; ...............: oTrayInfo[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
; ----------------------------------------------------------------------------------------------------------------------
; Converted to v2 by ruchuby in 2023.1.1
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_GetInfo(sExeName := "")
{
d := A_DetectHiddenWindows
DetectHiddenWindows(true)
oTrayInfo := []
For key, sTray in ["Shell_TrayWnd", "NotifyIconOverflowWindow"]
{
idxTB := TrayIcon_GetTrayBar(sTray)
pidTaskbar := WinGetPID("ahk_class " sTray)
hProc := DllCall("OpenProcess", "UInt", 0x38, "Int", 0, "UInt", pidTaskbar)
pRB := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "UPtr", 20, "UInt", 0x1000, "UInt", 0x04)
btn := Buffer((A_Is64bitOS ? 32 : 20), 0)
nfo := Buffer((A_Is64bitOS ? 32 : 24), 0)
tip := Buffer(128 * 2, 0)
; TB_BUTTONCOUNT = 0x0418
res := SendMessage(0x0418, 0, 0, "ToolbarWindow32" idxTB, "ahk_class " sTray)
Loop res
{
; TB_GETBUTTON 0x0417
SendMessage(0x0417, A_Index - 1, pRB, "ToolbarWindow32" idxTB, "ahk_class " sTray)
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", pRB, "Ptr", btn.Ptr, "UPtr", btn.Size, "UPtr", 0)
iBitmap := NumGet(btn, 0, "Int")
idCmd := NumGet(btn, 4, "Int")
fsState := NumGet(btn, 8, "UChar")
fsStyle := NumGet(btn, 9, "UChar")
dwData := NumGet(btn, (A_Is64bitOS ? 16 : 12), "UPtr")
iString := NumGet(btn, (A_Is64bitOS ? 24 : 16), "Ptr")
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", dwData, "Ptr", nfo.Ptr, "UPtr", nfo.Size, "UPtr", 0)
hWnd := NumGet(nfo, 0, "Ptr")
uId := NumGet(nfo, (A_Is64bitOS ? 8 : 4), "UInt")
msgId := NumGet(nfo, (A_Is64bitOS ? 12 : 8), "UPtr")
hIcon := NumGet(nfo, (A_Is64bitOS ? 24 : 20), "Ptr")
nPid := WinGetPID("ahk_id " hWnd)
try sProcess := WinGetProcessName("ahk_id " hWnd)
sClass := WinGetClass("ahk_id " hWnd)
If (!sExeName || sExeName == sProcess || sExeName == nPid)
{
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", iString, "Ptr", tip.Ptr, "UPtr", tip.Size, "UPtr", 0)
oTrayInfo.Push(Map("idx", A_Index - 1
, "idcmd", idCmd
, "pid", nPid
, "uid", uId
, "msgid", msgId
, "hicon", hIcon
, "hwnd", hWnd
, "class", sClass
, "process", sProcess
, "tooltip", StrGet(tip, "UTF-16")
, "tray", sTray))
}
}
DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", pRB, "UPtr", 0, "UInt", 0x8000)
DllCall("CloseHandle", "Ptr", hProc)
}
DetectHiddenWindows(d)
Return oTrayInfo
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TrayIcon_Hide
; Description ..: Hide or unhide a tray icon.
; Parameters ...: idCmd - Command identifier associated with the button.
; ..............: sTray - Place where to find the icon ("Shell_TrayWnd" or "NotifyIconOverflowWindow").
; ..............: bHide - True for hide, false for unhide.
; Info .........: TB_HIDEBUTTON message - http://goo.gl/oelsAa
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_Hide(idCmd, sTray := "Shell_TrayWnd", bHide := true)
{
d := A_DetectHiddenWindows
DetectHiddenWindows(true)
idxTB := TrayIcon_GetTrayBar()
SendMessage(0x0404, idCmd, bHide, "ToolbarWindow32" idxTB, "ahk_class " sTray) ; TB_HIDEBUTTON
SendMessage(0x001A, 0, 0, , "ahk_class " sTray)
DetectHiddenWindows(d)
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TrayIcon_Delete
; Description ..: Delete a tray icon.
; Parameters ...: idx - 0 based tray icon index.
; ..............: sTray - Place where to find the icon ("Shell_TrayWnd" or "NotifyIconOverflowWindow").
; Info .........: TB_DELETEBUTTON message - http://goo.gl/L0pY4R
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_Delete(idx, sTray := "Shell_TrayWnd")
{
d := A_DetectHiddenWindows
DetectHiddenWindows(true)
idxTB := TrayIcon_GetTrayBar()
SendMessage(0x0416, idx, 0, "ToolbarWindow32" idxTB, "ahk_class " sTray) ; TB_DELETEBUTTON = 0x0416
SendMessage(0x001A, 0, 0, , "ahk_class " sTray)
DetectHiddenWindows(d)
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TrayIcon_Remove
; Description ..: Remove a Tray icon. It should be more reliable than TrayIcon_Delete.
; Parameters ...: hWnd - Window handle.
; ..............: uId - Application defined identifier for the icon.
; Info .........: NOTIFYICONDATA structure - https://goo.gl/1Xuw5r
; ..............: Shell_NotifyIcon function - https://goo.gl/tTSSBM
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_Remove(hWnd, uId)
{
NID := Buffer((2 * 384 + A_PtrSize * 5 + 40), 0)
NumPut("UInt", NID.Size, NID.Ptr, 0)
NumPut("UInt", hWnd, NID.Ptr, A_PtrSize)
NumPut("UInt", uId, NID.Ptr, A_PtrSize * 2)
Return DllCall("Shell32.dll\Shell_NotifyIcon", "UInt", 0x2, "UInt", NID.Ptr)
}
; ----------------------------------------------------------------------------------------------------------------------
; 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 - Place where to find the icon ("Shell_TrayWnd" or "NotifyIconOverflowWindow").
; Info .........: TB_MOVEBUTTON message - http://goo.gl/1F6wPw
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_Move(idxOld, idxNew, sTray := "Shell_TrayWnd")
{
d := A_DetectHiddenWindows
DetectHiddenWindows(true)
idxTB := TrayIcon_GetTrayBar()
SendMessage(0x452, idxOld, idxNew, "ToolbarWindow32 " idxTB, "ahk_class " sTray) ; TB_MOVEBUTTON = 0x452
DetectHiddenWindows(d)
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TrayIcon_Set
; Description ..: Modify icon with the given index for the given window.
; Parameters ...: hWnd - Window handle.
; ..............: uId - Application defined identifier for the icon.
; ..............: hIcon - Handle to the tray icon.
; ..............: hIconSmall - Handle to the small icon, for window menubar. Optional.
; ..............: hIconBig - Handle to the big icon, for taskbar. Optional.
; Return .......: true on success, false on failure.
; Info .........: NOTIFYICONDATA structure - https://goo.gl/1Xuw5r
; ..............: Shell_NotifyIcon function - https://goo.gl/tTSSBM
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_Set(hWnd, uId, hIcon, hIconSmall := 0, hIconBig := 0)
{
d := A_DetectHiddenWindows
DetectHiddenWindows(true)
; WM_SETICON = 0x0080
If (hIconSmall)
SendMessage(0x0080, 0, hIconSmall, , "ahk_id " hWnd)
If (hIconBig)
SendMessage(0x0080, 1, hIconBig, , "ahk_id " hWnd)
DetectHiddenWindows(d)
NID := Buffer(2 * 384 + A_PtrSize * 5 + 40, 0)
NumPut("UInt", NID.Size, NID.Ptr, 0)
NumPut("UInt", hWnd, NID.Ptr, (A_PtrSize == 4) ? 4 : 8)
NumPut("UInt", uId, NID.Ptr, (A_PtrSize == 4) ? 8 : 16)
NumPut("UInt", 2, NID.Ptr, (A_PtrSize == 4) ? 12 : 20)
NumPut("UInt", hIcon, NID.Ptr, (A_PtrSize == 4) ? 20 : 32)
; NIM_MODIFY := 0x1
Return DllCall("Shell32.dll\Shell_NotifyIcon", "UInt", 0x1, "Ptr", NID.Ptr)
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TrayIcon_GetTrayBar
; Description ..: Get the tray icon handle.
; Parameters ...: sTray - Traybar to retrieve.
; Return .......: Tray icon handle.
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_GetTrayBar(sTray := "Shell_TrayWnd")
{
d := A_DetectHiddenWindows
DetectHiddenWindows(true)
loopTimes := 0
for v in WinGetControls("ahk_class " sTray)
if InStr(v, "ToolbarWindow32")
loopTimes++
Loop loopTimes
{
hWnd := ControlGetHwnd("ToolbarWindow32" A_Index, "ahk_class " sTray)
hParent := DllCall("GetParent", "Ptr", hWnd)
sClass := WinGetClass("ahk_id " hParent)
If !(sClass == "SysPager" || sClass == "NotifyIconOverflowWindow")
Continue
idxTB := A_Index
Break
}
DetectHiddenWindows(d)
Return idxTB
}
; ----------------------------------------------------------------------------------------------------------------------
; Function .....: TrayIcon_GetHotItem
; Description ..: Get the index of tray's hot item.
; Return .......: Index of tray's hot item.
; Info .........: TB_GETHOTITEM message - http://goo.gl/g70qO2
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_GetHotItem()
{
idxTB := TrayIcon_GetTrayBar()
res := SendMessage(0x0447, 0, 0, "ToolbarWindow32" idxTB, "ahk_class Shell_TrayWnd") ; TB_GETHOTITEM = 0x0447
Return res << 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.
; ..............: nIdx - Index of tray icon to click if more than one match.
; ----------------------------------------------------------------------------------------------------------------------
TrayIcon_Button(sExeName, sButton := "L", bDouble := false, nIdx := 1)
{
d := A_DetectHiddenWindows
DetectHiddenWindows(true)
msgMap := Map(
'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 := TrayIcon_GetInfo(sExeName)
If (bDouble)
PostMessage(oIcons[nIdx]["msgid"], oIcons[nIdx]["uid"], msgMap[sButton "DBLCLK"], , "ahk_id " oIcons[nIdx]["hwnd"])
Else
{
PostMessage(oIcons[nIdx]["msgid"], oIcons[nIdx]["uid"], msgMap[sButton "DOWN"], , "ahk_id " oIcons[nIdx]["hwnd"])
PostMessage(oIcons[nIdx]["msgid"], oIcons[nIdx]["uid"], msgMap[sButton "UP"], , "ahk_id " oIcons[nIdx]["hwnd"])
}
DetectHiddenWindows(d)
Return
}