1

Тема: AHK: Двойная иконка в трее.

Посмотрите, пожалуста, скриншот.
Обычно, когда запускаешь скрипт, в трее появляется соответствующая иконка.
(показал курсором на скриншоте).
Вопрос: Как сделать что бы при запуске одного скрипта в трее появилось сразу две (и более) иконки.
Повторяю, скрипт должен быть один, т.е. в диспетчере задач должен висеть один процесс.

2

Re: AHK: Двойная иконка в трее.

Например, так:

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
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder