 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
ezuk
Joined: 04 Jun 2005 Posts: 128
|
Posted: Fri Aug 24, 2007 7:07 pm Post subject: Consolidating tray icons |
|
|
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 |
|
 |
engunneer
Joined: 30 Aug 2005 Posts: 6856 Location: Pacific Northwest, US
|
Posted: Fri Aug 24, 2007 8:00 pm Post subject: |
|
|
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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 6223
|
Posted: Fri Aug 24, 2007 10:29 pm Post subject: Re: Consolidating tray icons |
|
|
| 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!
| 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  |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1373
|
Posted: Fri Aug 24, 2007 10:46 pm Post subject: |
|
|
Very clever Skan
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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 6223
|
Posted: Fri Aug 24, 2007 10:49 pm Post subject: |
|
|
| 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  |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1373
|
Posted: Fri Aug 24, 2007 11:41 pm Post subject: |
|
|
Thank you very much Skan (and Sean of course )
| 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 |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Sat Aug 25, 2007 5:35 am Post subject: |
|
|
| 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 |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1373
|
Posted: Sat Aug 25, 2007 3:11 pm Post subject: |
|
|
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 |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Sun Aug 26, 2007 12:04 am Post subject: |
|
|
Lucky you - I already wrote a function for that.
| 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)) |
 |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1373
|
Posted: Sun Aug 26, 2007 2:54 am Post subject: |
|
|
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 but hope you can help me just a bit more... |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Sun Aug 26, 2007 5:48 am Post subject: |
|
|
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 |
|
 |
ezuk
Joined: 04 Jun 2005 Posts: 128
|
Posted: Sun Aug 26, 2007 10:37 pm Post subject: Re: Consolidating tray icons |
|
|
| 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  |
Sweet!
It works well. Can you make it hide the existing AHK icons when I run it? |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 6223
|
Posted: Thu Aug 30, 2007 10:12 am Post subject: Re: Consolidating tray icons |
|
|
| 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 ? 
Last edited by SKAN on Wed Apr 16, 2008 9:35 am; edited 1 time in total |
|
| Back to top |
|
 |
DougA Guest
|
Posted: Wed Apr 16, 2008 8:27 am Post subject: |
|
|
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
|
Posted: Wed Apr 16, 2008 8:49 am Post subject: |
|
|
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 |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|