AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Consolidating tray icons
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
ezuk



Joined: 04 Jun 2005
Posts: 128

PostPosted: Fri Aug 24, 2007 7:07 pm    Post subject: Consolidating tray icons Reply with quote

Hello,

I routinely use 3-4 AHK scripts, and thus my systray is cluttered with AHK icons.

I don't want to copy all scripts into one big script file -- sometimes I want to shut them down selectively, or debug them, etc.

Instead, I want one AHK icon, with a context menu entry (sub-menu) for each running script.

How can I do this?
Back to top
View user's profile Send private message
engunneer



Joined: 30 Aug 2005
Posts: 6856
Location: Pacific Northwest, US

PostPosted: Fri Aug 24, 2007 8:00 pm    Post subject: Reply with quote

do they all need icons? I almost always turn off the icon entirely.
_________________
Unless otherwise noted, all code is untested.
Common Answers: 1.(Loops, Viruses, etc.) 2. Search 3.RTFM
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Fri Aug 24, 2007 10:29 pm    Post subject: Re: Consolidating tray icons Reply with quote

engunneer wrote:
do they all need icons? I almost always turn off the icon entirely.


That is what ezuk wants.. Turn off Icon for all scripts and at the same time have a single tray icon to control any script.

ezuk wrote:
I want one AHK icon, with a context menu entry (sub-menu) for each running script.


Granted! Very Happy

Code:
; Master TrayIcon to control all running instances of AutoHotkey

; Master TrayIcon to control all running instances of AutoHotkey

#Persistent
Menu, Tray, Icon, User32.DLL, 4
DetectHiddenWindows, On
SelfID := WinExist( A_ScriptFullPath " ahk_class AutoHotkey")
Menu, Tray, NoStandard
WinGet, AList, List, ahk_class AutoHotkey

Loop %AList% {
               ID := AList%A_Index%
               IfEqual, ID, %SelfID%, Continue
 
               WinGetTitle, ATitle, ahk_id %ID%
               StringSplit, ATitle, ATitle, -
               SplitPath, ATitle1, Name
               StringUpper, Name, Name

               Menu,%Name%,Add, %A_Index%:Reload , MenuChoice
               Menu,%Name%,Add, %A_Index%:Edit   , MenuChoice
               Menu,%Name%,Add, %A_Index%:Pause  , MenuChoice
               Menu,%Name%,Add, %A_Index%:Suspend, MenuChoice
               Menu,%Name%,Add, %A_Index%:Exit   , MenuChoice
               Menu, Tray, Add, %Name%, :%Name%
             }

Menu, Tray, Add
Menu, Tray, Add, Quick Reload, Reload
Menu, Tray, Add
Menu, Tray, Default, Quick Reload
Menu, Tray, Click, 1
Menu, Tray, Standard

Return

MenuChoice:
  StringSplit, F,A_ThisMenuItem, :
  IfEqual,F2,Reload , PostMessage,0x111,65400,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Edit   , PostMessage,0x111,65401,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Pause  , PostMessage,0x111,65403,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Suspend, PostMessage,0x111,65404,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Exit   , PostMessage,0x111,65405,0,,% "ahk_id" AList%F1%
Return

Reload:
  Reload


It does need some refinement .. Still I did not imagine this would be so easy Surprised
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1373

PostPosted: Fri Aug 24, 2007 10:46 pm    Post subject: Reply with quote

Very clever Skan Smile

I was wondering if there was a way to hide a tray icon of any program(non ahk). On win2000 there is no hide tray icon option, and xp sometimes shows them back. i cant think of any way of doing it. any thoughts?
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Fri Aug 24, 2007 10:49 pm    Post subject: Reply with quote

tic wrote:
I was wondering if there was a way to hide a tray icon of any program(non ahk).


Extract Informations about TrayIcons by Sean Smile
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1373

PostPosted: Fri Aug 24, 2007 11:41 pm    Post subject: Reply with quote

Thank you very much Skan (and Sean of course Smile )

Code:
HideTrayIcon(9, True)

HideTrayIcon(idn, bHide = True)
{
   idxTB := GetTrayBar()
   SendMessage, 0x404, idn, bHide, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_HIDEBUTTON
   SendMessage, 0x1A, 0, 0, , ahk_class Shell_TrayWnd
}

GetTrayBar()
{
   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", "Uint", hWnd)
      WinGetClass, sClass, ahk_id %hParent%
      If (sClass <> "SysPager")
         Continue
      idxTB := A_Index
         Break
   }

   Return idxTB
}


this works beautifully to hide the 9th idn in the tray for example, but how could you retrieve then whether an icon is hidden or shown? So say you wanted to do this if it was shown or show it if it was hidden.
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Sat Aug 25, 2007 5:35 am    Post subject: Reply with quote

tic wrote:
this works beautifully to hide the 9th idn in the tray for example, but how could you retrieve then whether an icon is hidden or shown?
Sean's TrayIcons function retrieves most of the info associated with each tray icon. Specifically, you want Statyle, which is a combination of fsState, fsStyle and a few reserved bytes. (Statyle & 0xFF) will give you fsState; (fsState & 0x8) (or Statyle & 0x8) will tell you if the icon is hidden (8) or visible (0). Valid state flags are (from the Windows SDK - CommCtrl.h):
Code:
#define TBSTATE_CHECKED         0x01
#define TBSTATE_PRESSED         0x02
#define TBSTATE_ENABLED         0x04
#define TBSTATE_HIDDEN          0x08
#define TBSTATE_INDETERMINATE   0x10
#define TBSTATE_WRAP            0x20
#define TBSTATE_ELLIPSES        0x40
#define TBSTATE_MARKED          0x80
The TrayIcons() function isn't really designed to retrieve a specific value, but it shouldn't be too difficult to write an IsTrayIconHidden() function from what's there. (Hmm, GetTrayIconState() might be more useful...)

Edit:
Code:
GetTrayIconState(idn)
{
    idxTB := GetTrayBar()
    SendMessage, 0x412, idn,, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd  ; TB_GETSTATE
    return ErrorLevel
}
Turned out to be much simpler than I thought. :) Examples:
Code:
; == Example 1
state := GetTrayIconState(idn)
hidden := state & 0x08   ; TBSTATE_HIDDEN
enabled := state & 0x04  ; TBSTATE_ENABLED

if (hidden and enabled) ; or: if ((GetTrayIconState(idn) & 0x12)=0x12)
    MsgBox, This icon is hidden`, but will probably be shown if you expand the tray area!

if (hidden and !enabled)
    MsgBox, % "This icon probably isn't used by anything at the moment. "
            . "For example, the AVG test center tray icon when no test is in progress."

; == Example 2
HideTrayIcon(idn, !(GetTrayIconState(idn) & 0x8))  ; toggles hide/show
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1373

PostPosted: Sat Aug 25, 2007 3:11 pm    Post subject: Reply with quote

Lexikos that is pure brilliance! it works exactly as id hoped.


Code:
;Resolve some variable to be the idn wanted
idn = 0

state := GetTrayIconState(idn)
hidden := state & 0x08   ; TBSTATE_HIDDEN
enabled := state & 0x04  ; TBSTATE_ENABLED

HideTrayIcon(idn, !(GetTrayIconState(idn) & 0x8))  ; toggles hide/show (I especially liked this resolving to true or false ;) )

Return


GetTrayIconState(idn)
{
    idxTB := GetTrayBar()
    SendMessage, 0x412, idn,, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd  ; TB_GETSTATE
    return ErrorLevel
}

HideTrayIcon(idn, bHide = True)
{
   idxTB := GetTrayBar()
   SendMessage, 0x404, idn, bHide, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_HIDEBUTTON
   SendMessage, 0x1A, 0, 0, , ahk_class Shell_TrayWnd
}

GetTrayBar()
{
   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", "Uint", hWnd)
      WinGetClass, sClass, ahk_id %hParent%
      If (sClass <> "SysPager")
         Continue
      idxTB := A_Index
         Break
   }

   Return idxTB
}


I have another cheeky question, but this one may be a bit ridiculous. I cant think of a way to do this as I dont know how it would find where they are, but could the icons of each tray entry be recovered?

I can see trayicon.ahk retrieves partial information about them, including their process name, but i wouldnt know how to go about finding where their icos are stored.

Thank you! youve been more than helpful!

Edit:

Quote:
Yes, basically using the same Shell_NotifyIcon, but need to provide more informations. The most important one may be hIcon. As a matter of fact, TrayIcons() function can extract hIcon too, so, can add back the deleted tray icons, in principle. However, there is one glitch: hIcon is not always the correct one for some apps, e.g., Process Explorer etc. So, I decided to not implement it.


im trying to look into this now, but am not sure how to get the hIcon
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Sun Aug 26, 2007 12:04 am    Post subject: Reply with quote

Lucky you - I already wrote a function for that. Razz
Code:

; Adapated from Sean's TrayIcons() : http://www.autohotkey.com/forum/topic17314.html
GetTrayIconInfo(sExeName, ByRef hWnd, ByRef uID, ByRef nMsg, ByRef hIcon)
{
    idxTB := GetTrayBar()
    WinGet, pidTaskbar, PID, ahk_class Shell_TrayWnd

    hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
    pRB := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 20, "Uint", 0x1000, "Uint", 0x4)

    VarSetCapacity(btn, 20)
    VarSetCapacity(nfo, 24)

    SendMessage, 0x418, 0, 0, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_BUTTONCOUNT

    IconFound = 0

    Loop, %ErrorLevel%
    {
        SendMessage, 0x417, A_Index - 1, pRB, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_GETBUTTON

        DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pRB, "Uint", &btn, "Uint", 20, "Uint", 0)

        iBitmap   := NumGet(btn, 0)
        idn       := NumGet(btn, 4)
        Statyle   := NumGet(btn, 8)
        dwData    := NumGet(btn, 12)
        iString   := NumGet(btn, 16)

        DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 24, "Uint", 0)

        ptr := &nfo
        hWnd  := NumGet(nfo, 0)
        uID   := NumGet(nfo, 4)
        nMsg  := NumGet(nfo, 8)
        hIcon := NumGet(nfo, 20)

        WinGet, pid, PID,              ahk_id %hWnd%
        WinGet, sProcess, ProcessName, ahk_id %hWnd%
        WinGetClass, sClass,           ahk_id %hWnd%

        If !sExeName || (sExeName = sProcess) || (sExeName = pid)
        {
            IconFound = 1
            break
        }
    }

    DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pRB, "Uint", 0, "Uint", 0x8000)
    DllCall("CloseHandle", "Uint", hProc)

    If !IconFound
        hWnd := uID := nMsg := hIcon := 0

    return IconFound
}
Hwnd, uID and nMsg are used to simulate right-clicking the tray icon (you may want to remove or ignore them.) I use this function to get the icons of running AutoHotkey scripts (by passing it the process ID of each script), which I put in a menu for quick access.

Sean's TrayIcons() actually does get hIcon, but doesn't put it in the output string.

Btw, you don't need
Code:
state := GetTrayIconState(idn)
hidden := state & 0x08   ; TBSTATE_HIDDEN
enabled := state & 0x04  ; TBSTATE_ENABLED
if you're using
Code:
HideTrayIcon(idn, !(GetTrayIconState(idn) & 0x8))
Wink
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1373

PostPosted: Sun Aug 26, 2007 2:54 am    Post subject: Reply with quote

im not gonna say i undederstand all of it, but is very nice, and have tried it out a bit at it looks good, but how could i go about adapting it to not require me to pass it the process ID of the icon I want? Instead I would like to get a list of the current icons in the system tray, by using idn as i had previously.

Youve already given me more help than I expected from anyone Wink but hope you can help me just a bit more...
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Sun Aug 26, 2007 5:48 am    Post subject: Reply with quote

Look for the line that compares the process name/id:
Code:
If !sExeName || (sExeName = sProcess) || (sExeName = pid)
..and change it to:
Code:
If (idn = sExeName)
(You might want to rename sExeName.)
Back to top
View user's profile Send private message
ezuk



Joined: 04 Jun 2005
Posts: 128

PostPosted: Sun Aug 26, 2007 10:37 pm    Post subject: Re: Consolidating tray icons Reply with quote

Skan wrote:
engunneer wrote:
do they all need icons? I almost always turn off the icon entirely.


That is what ezuk wants.. Turn off Icon for all scripts and at the same time have a single tray icon to control any script.

It does need some refinement .. Still I did not imagine this would be so easy Surprised


Sweet!

It works well. Can you make it hide the existing AHK icons when I run it?
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Thu Aug 30, 2007 10:12 am    Post subject: Re: Consolidating tray icons Reply with quote

ezuk wrote:
Can you make it hide the existing AHK icons when I run it?


I want to leave that code simple. Did you experiment with lexiKos' code ? Smile


Last edited by SKAN on Wed Apr 16, 2008 9:35 am; edited 1 time in total
Back to top
View user's profile Send private message
DougA
Guest





PostPosted: Wed Apr 16, 2008 8:27 am    Post subject: Reply with quote

Hello AHK community, I need help with this

I am a total noob at AHK but this script here is a great idea, one tray icon to control all running scripts, but when I try to create this I have trouble

I used the code from this thread
Code:
; Master TrayIcon to control all running instances of AutoHotkey

; Master TrayIcon to control all running instances of AutoHotkey

#Persistent
Menu, Tray, Icon, User32.DLL, 4
DetectHiddenWindows, On
SelfID := WinExist( A_ScriptFullPath " ahk_class AutoHotkey")
Menu, Tray, NoStandard
WinGet, AList, List, ahk_class AutoHotkey

Loop %AList% {
               ID := AList%A_Index%
               IfEqual, ID, %SelfID%, Continue
 
               WinGetTitle, ATitle, ahk_id %ID%
               StringSplit, ATitle, ATitle, -
               SplitPath, ATitle1, Name
               StringUpper, Name, Name

               Menu,%Name%,Add, %A_Index%:Reload , MenuChoice
               Menu,%Name%,Add, %A_Index%:Edit   , MenuChoice
               Menu,%Name%,Add, %A_Index%:Pause  , MenuChoice
               Menu,%Name%,Add, %A_Index%:Suspend, MenuChoice
               Menu,%Name%,Add, %A_Index%:Exit   , MenuChoice
               Menu, Tray, Add, %Name%, :%Name%
             }

Menu, Tray, Add
Menu, Tray, Add, Quick Reload, Reload
Menu, Tray, Add
Menu, Tray, Default, Quick Reload
Menu, Tray, Click, 1
Menu, Tray, Standard

Return

MenuChoice:
  StringSplit, F,A_ThisMenuItem, :
  IfEqual,F2,Reload , PostMessage,0x111,65400,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Edit   , PostMessage,0x111,65401,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Pause  , PostMessage,0x111,65403,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Suspend, PostMessage,0x111,65404,0,,% "ahk_id" AList%F1%
  IfEqual,F2,Exit   , PostMessage,0x111,65405,0,,% "ahk_id" AList%F1%
Return

Reload:
  Reload


but when I run it a get a red x in the systray so I am thinking this did not install correctly, could someone help me?
Back to top
Z Gecko
Guest





PostPosted: Wed Apr 16, 2008 8:49 am    Post subject: Reply with quote

nothing is wrong, itīs just the icon SKAN has chosen.
You are free to change it to something else. Just change this line:
Code:
Menu, Tray, Icon, User32.DLL, 4
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group