if hIcon := ExtractIcon(A_AhkPath, 2, 16)
hAssociatedGui1 := AddTrayIcon(hIcon) ; первая дополнительная иконка
if hIcon := ExtractIcon("Shell32.dll", 44, 16)
hAssociatedGui2 := AddTrayIcon(hIcon) ; вторая дополнительная иконка
OnExit, Exit
; если нужно меню для иконок
OnMessage(0x404, "AHK_NOTIFYICON")
Menu, MyTrayMenu, Add, Завершение работы, CloseApp
Return
CloseApp:
ExitApp
Exit:
RemoveTrayIcon(hAssociatedGui1), RemoveTrayIcon(hAssociatedGui2)
ExitApp
ExtractIcon(sFile, IconNumber, IconSize)
{
coding := A_IsUnicode ? "W" : "A"
SplitPath, sFile,,, ext
(ext = "ico" && IconNumber := 0)
if PrivateExtractIcons := DllCall("GetProcAddress"
, Ptr, DllCall("LoadLibrary", Str, "User32", Ptr)
, AStr, "PrivateExtractIcons" . coding, Ptr)
{
Result := DllCall(PrivateExtractIcons, Str, sFile, Int, IconNumber-1
, Int, IconSize, Int, IconSize, PtrP, hIcon, UIntP, 0, UInt, 1, UInt, 0)
if !Result
MsgBox, 16,, % "Не удалось извлечь иконку.`nОшибка " A_LastError
else if (Result = 0xFFFFFFFF || Result = -1)
MsgBox, 16,, Файл "%sFile%" не найден!
}
else
{
if !DllCall("Shell32\ExtractIconEx" . coding, Str, sFile, Int, IconNumber-1, PtrP, hIconLarge, PtrP, hIconSmall, UInt, 1)
{
MsgBox, 16,, % "Не удалось извлечь иконку.`nОшибка " A_LastError
return
}
SysGet, SmallIconSize, % SM_CXSMICON := 49
if (IconSize <= SmallIconSize)
DllCall("DestroyIcon", Ptr, hIconLarge), hIcon := hIconSmall
else
DllCall("DestroyIcon", Ptr, hIconSmall), hIcon := hIconLarge
hIcon := DllCall("CopyImage", Ptr, hIcon, UInt, IMAGE_ICON := 1
, Int, IconSize, Int, IconSize, UInt, LR_COPYRETURNORG := 0x4|LR_COPYDELETEORG := 0x8, Ptr)
}
Return hIcon
}
AddTrayIcon(hIcon)
{
static NIF_MESSAGE := 1, NIF_ICON := 2, GuiNumber := 99
VarSetCapacity(NOTIFYICONDATA, size := A_PtrSize = 8 ? 848 : A_IsUnicode? 828 : 444, 0)
NumPut(size, NOTIFYICONDATA, "UInt")
Gui, % GuiNumber-- ": +hwndhGui"
NumPut(hGui, NOTIFYICONDATA, A_PtrSize)
NumPut(uID := 0x404, NOTIFYICONDATA, 2*A_PtrSize, "UInt")
NumPut(NIF_MESSAGE|NIF_ICON, NOTIFYICONDATA, 2*A_PtrSize + 4, "UInt")
NumPut(nMsg := 0x404, NOTIFYICONDATA, 2*A_PtrSize + 8, "UInt")
NumPut(hIcon, NOTIFYICONDATA, 3*A_PtrSize+8)
DllCall("shell32\Shell_NotifyIcon", UInt, NIM_ADD := 0, Ptr, &NOTIFYICONDATA)
DllCall("DestroyIcon", Ptr, hIcon)
Return hGui
}
RemoveTrayIcon(hWnd, uID=0x404)
{
VarSetCapacity(NOTIFYICONDATA, size := A_PtrSize = 8 ? 848 : A_IsUnicode? 828 : 444, 0)
NumPut(size, NOTIFYICONDATA, "UInt")
NumPut(hWnd, NOTIFYICONDATA, A_PtrSize)
NumPut(uID, NOTIFYICONDATA, 2*A_PtrSize, "UInt")
DllCall("shell32\Shell_NotifyIcon", "UInt", NIM_DELETE := 2, Ptr, &NOTIFYICONDATA)
Return
}
AHK_NOTIFYICON(wp, lp, msg, hwnd) ; wp — uID, lp — Message
{
global hAssociatedGui1, hAssociatedGui2
static WM_RBUTTONUP := 0x205
if (lp = WM_RBUTTONUP && (hwnd = hAssociatedGui1 || hwnd = hAssociatedGui2))
Menu, MyTrayMenu, Show
}