Page 1 of 3

Is there a way to put an icon outside the hidden tray icons by default?

Posted: 11 Nov 2018, 04:17
by TheBeginner
Running a compiled script creates a tray icon, what I'm trying to do is put the icon outside the "hidden tray icons" area by default using AHK
Putting it outside by default, is that possible?

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 11 Nov 2018, 05:16
by Sweetins
Sure is possible. Just drag the said script's tray icon from the system stray pop-up and put it on the task bar. The next time you run the script, the tray icon stays on the task bar and not in the system tray pop-up pane.

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 11 Nov 2018, 07:04
by TheBeginner
Thanks for the reply, the thing is I'm looking to do it with a script, I don't want to go around the office dragging icons to the tray
I'm looking for a way to set it up to be external by default

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 11 Nov 2018, 12:46
by gwarble
There is a way, but its largely undocumented and wouldn't be trivial to implement

google iTrayNotify

and please share the class you write for it

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 15 Nov 2018, 04:46
by TheBeginner
Thanks Gwarble, but it's over my skill level. I'm going to drop it for the time being.

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 17 Nov 2018, 14:59
by gwarble
Yeah i unfortunately came to the same conclusion... but its on my list to attempt someday

until that time comes, or someone else writes a class for it, on my shop computers i use the registry edit to always show all icons... not elegant. I'd like that option from within EitherMouse but that will have to wait for a real iTrayNotify implementation

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 03 Mar 2019, 01:34
by jeeswg
- I have an attempt here, which isn't working. Tested on Windows 7.
- It's possible that tweaking it will make it work.
- Based on this link, it's possible that it will/won't work depending on the OS, and whether you run as admin or not.
winapi - ITrayNotify interface not working when Windows 7 process is elevated ("Class not registered") - Stack Overflow
https://stackoverflow.com/questions/36824485/itraynotify-interface-not-working-when-windows-7-process-is-elevated-class-not

Code: Select all

;see ITaskbarList example here:
;DllCall() - Syntax & Usage | AutoHotkey
;https://autohotkey.com/docs/commands/DllCall.htm

;NOTIFYITEM
;https://www.geoffchappell.com/studies/windows/shell/explorer/interfaces/notifyitem.htm
;typedef struct tagNOTIFYITEM {
;    PWSTR pszExeName;
;    PWSTR pszTip;
;    HICON hIcon;
;    HWND hWnd;
;    DWORD dwPreference;
;    UINT uID;
;    GUID guidItem;
;} NOTIFYITEM;

;NOTIFYITEM
;https://www.geoffchappell.com/studies/windows/shell/explorer/interfaces/notifyitem.htm
;0x00 hide when inactive
;0x01 always hide
;0x02 always show

q:: ;test ITrayNotify SetPreference
CLSID_TrayNotify := "{25DEAD04-1EAC-4911-9E3A-AD0A4AB560FD}"
IID_ITrayNotify := "{FB852B2C-6BAD-4605-9551-F15F87830935}"
pTN := ComObjCreate(CLSID_TrayNotify, IID_ITrayNotify)
vPath := A_AhkPath
VarSetCapacity(NOTIFYITEM, A_PtrSize=8?56:40, 0)
NumPut(&vPath, &NOTIFYITEM, 0, "Ptr") ;pszExeName
NumPut(2, &NOTIFYITEM, A_PtrSize=8?32:16, "UInt") ;dwPreference
DllCall(NumGet(NumGet(pTN+0)+4*A_PtrSize), Ptr,pTN, Ptr,&NOTIFYITEM) ;SetPreference
ObjRelease(pTN)
return

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 03 Mar 2019, 16:10
by teadrinker
On Windows 7 it works like this:

Code: Select all

;see ITaskbarList example here:
;DllCall() - Syntax & Usage | AutoHotkey
;https://autohotkey.com/docs/commands/DllCall.htm

;NOTIFYITEM
;https://www.geoffchappell.com/studies/windows/shell/explorer/interfaces/notifyitem.htm
;typedef struct tagNOTIFYITEM {
;    PWSTR pszExeName;
;    PWSTR pszTip;
;    HICON hIcon;
;    HWND hWnd;
;    DWORD dwPreference;
;    UINT uID;
;    GUID guidItem;
;} NOTIFYITEM;

;NOTIFYITEM
;https://www.geoffchappell.com/studies/windows/shell/explorer/interfaces/notifyitem.htm
;0x00 hide when inactive
;0x01 always hide
;0x02 always show

t := 1
q:: ;test ITrayNotify SetPreference
CLSID_TrayNotify := "{25DEAD04-1EAC-4911-9E3A-AD0A4AB560FD}"
IID_ITrayNotify := "{FB852B2C-6BAD-4605-9551-F15F87830935}"
pTN := ComObjCreate(CLSID_TrayNotify, IID_ITrayNotify)

VarSetCapacity(NOTIFYITEM, A_PtrSize*4 + 8 + 16, 0)
NumPut(A_ScriptHwnd, NOTIFYITEM, A_PtrSize*3)

NumPut((t := !t) + 1, NOTIFYITEM, A_PtrSize*4, "UInt") ;dwPreference

NumPut(0x404, NOTIFYITEM, A_PtrSize*4 + 4, "UInt")
DllCall(NumGet(NumGet(pTN+0)+4*A_PtrSize), Ptr,pTN, Ptr,&NOTIFYITEM) ;SetPreference
ObjRelease(pTN)
return
On Windows 10 this code produces the error "Interface is not supported".

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 03 Mar 2019, 16:42
by jeeswg
- Cheers teadrinker, here's a fixed version of my script above. It worked in Windows 7, when the script was non-admin. [EDIT: It failed on Windows 7, when the script was admin, reporting '0x80040154 - Class not registered'.]
- What's changed is that I've added hWnd and uID to NOTIFYITEM, but removed pszExeName.

Code: Select all

vToggle := 0

q:: ;test ITrayNotify SetPreference
vToggle := !vToggle
CLSID_TrayNotify := "{25DEAD04-1EAC-4911-9E3A-AD0A4AB560FD}"
IID_ITrayNotify := "{FB852B2C-6BAD-4605-9551-F15F87830935}"
pTN := ComObjCreate(CLSID_TrayNotify, IID_ITrayNotify)
VarSetCapacity(NOTIFYITEM, A_PtrSize=8?56:40, 0)
NumPut(A_ScriptHwnd, &NOTIFYITEM, A_PtrSize=8?24:12, "Ptr") ;hWnd
NumPut(vToggle+1, &NOTIFYITEM, A_PtrSize=8?32:16, "UInt") ;dwPreference
NumPut(0x404, &NOTIFYITEM, A_PtrSize=8?36:20, "UInt") ;uID
DllCall(NumGet(NumGet(pTN+0)+4*A_PtrSize), Ptr,pTN, Ptr,&NOTIFYITEM) ;SetPreference
ObjRelease(pTN)
return
- To get tray icon info (e.g. hWnd, uID), see my oTrayInfo example, here:
GUIs via DllCall: text functions (get/set internal/external control text) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=40514
- Or use this script:
[LIB] TrayIcon - Sean's TrayIcon for Unicode and 64 bit - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=1229

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 03 Mar 2019, 16:55
by teadrinker
Cheers, It's the same as mine. :)

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 03 Mar 2019, 17:09
by jeeswg
- Some links:
ITrayNotify
https://www.geoffchappell.com/studies/windows/shell/explorer/interfaces/itraynotify/index.htm
NOTIFYITEM
https://www.geoffchappell.com/studies/windows/shell/explorer/interfaces/notifyitem.htm
winapi - ITrayNotify interface not working when Windows 7 process is elevated ("Class not registered") - Stack Overflow
https://stackoverflow.com/questions/36824485/itraynotify-interface-not-working-when-windows-7-process-is-elevated-class-not
Undocumented API ITrayNotify. · GitHub
https://gist.github.com/ysc3839/25e8ed113c4e975b6781c9759ed4ee87
TrayNotify C# (CSharp) Code Examples - HotExamples
https://csharp.hotexamples.com/examples/-/TrayNotify/-/php-traynotify-class-examples.html

- @teadrinker: Did you find a good source saying which parameters were needed for NOTIFYITEM?
- I was going to reread through the links above, but hadn't had the chance yet.
- And btw, there might be some code in one of the links that will make it work on Windows 10, e.g. I saw a reference to ITrayNotifyWin8. Cheers.

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 03 Mar 2019, 17:27
by teadrinker
jeeswg wrote: - @teadrinker: Did you find a good source saying which parameters were needed for NOTIFYITEM?
I used Shell_NotifyIcon with NOTIFYICONDATA before, it's a bit similar.
jeeswg wrote: there might be some code in one of the links that will make it work on Windows 10, e.g. I saw a reference to ITrayNotifyWin8.
Tried ITrayNotifyWin8, this interface does nothing on my Windows 10.

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 03 Apr 2019, 14:30
by jeeswg
- Since it can make a difference whether a script is run as admin or not.
- E.g. on Windows 7 it, counterintuitively, *fails* when run as admin, but *succeeds* when run as non-admin.
- Here is a way to launch an admin script from a non-admin script, and a non-admin script from an admin script.
Reloading: Admin to Non-Admin - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=7752

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 18 Apr 2019, 11:49
by gwarble
jeeswg & teadrinker: many thanks! now to understand it and test it

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 30 Jun 2020, 14:22
by gwarble
I thought I just saw a post asking about doing this but couldn't find it again... So many thanks to jeeswg and teadrinker the above code works for me in Windows 7

now to get it to work with Windows 10, i think it needs a little pointer manipulation based on change of the interface (new uuid but more importantly there is a different exported function list, so I think fixing the pointer offsets is needed if I understand correctly.

Code: Select all

IID_ITrayNotify := "{FB852B2C-6BAD-4605-9551-F15F87830935}" ;win7-
public:
    virtual HRESULT __stdcall RegisterCallback(INotificationCB* callback) = 0;
    virtual HRESULT __stdcall SetPreference(const NOTIFYITEM* notify_item) = 0;
    virtual HRESULT __stdcall EnableAutoTray(BOOL enabled) = 0;
changed to:

Code: Select all

IID_ITrayNotifyWindows8 := "{D133CE13-3537-48BA-93A7-AFCD5D2053B4}" ;win8+
public:
    virtual HRESULT __stdcall RegisterCallback(INotificationCB* callback, unsigned long*) = 0;
    virtual HRESULT __stdcall UnregisterCallback(unsigned long*) = 0;
    virtual HRESULT __stdcall SetPreference(NOTIFYITEM const*) = 0;
    virtual HRESULT __stdcall EnableAutoTray(BOOL) = 0;
    virtual HRESULT __stdcall DoAction(BOOL) = 0;
Seems like VarSetCapacity will need to increase accordingly ( + A_PtrSize*2) and the Numput to dwPreference would have to be offset ( + A_PtrSize) but don't fully understand and can't get it to work... seems close though. Does the extra unsigned long* parameter for the RegisterCallback need extra offsetting?

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 30 Jun 2020, 14:48
by JoeWinograd
gwarble wrote:I thought I just saw a post asking about doing this but couldn't find it again.
Although the thread started in 2013, maybe you're thinking of the three relatively recent posts there beginning with this one:

https://www.autohotkey.com/boards/viewtopic.php?f=6&t=1229&p=330613#p330613

I'd love to find a solution for this! Regards, Joe

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 30 Jun 2020, 15:18
by gwarble
I swear I saw a post this morning where someone linked to that thread and to this thread... i dont know

anyway, I think the smart people here got really close to a solution on Windows 10 above, hopefully bumping it will get a solution

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 30 Jun 2020, 16:01
by teadrinker
Should work like this:

Code: Select all

CLSID_TrayNotify := "{25DEAD04-1EAC-4911-9E3A-AD0A4AB560FD}"
IID_ITrayNotify8 := "{D133CE13-3537-48BA-93A7-AFCD5D2053B4}"
t := 1

q::
   pITrayNotify8 := ComObjCreate(CLSID_TrayNotify, IID_ITrayNotify8)
   VarSetCapacity(NOTIFYITEM, A_PtrSize*4 + 8 + 16, 0)
   NumPut(A_ScriptHwnd, NOTIFYITEM, A_PtrSize*3)
   NumPut((t := !t) + 1, NOTIFYITEM, A_PtrSize*4, "UInt")
   NumPut(0x404, NOTIFYITEM, A_PtrSize*4 + 4, "UInt")
   res := DllCall(NumGet(NumGet(pITrayNotify8+0) + 5*A_PtrSize), "Ptr", pITrayNotify8, "Ptr", &NOTIFYITEM, "UInt") ; SetPreference
   ToolTip % Format("{:#x}", res) ; must be 0
   ObjRelease(pITrayNotify8)
Return
but on my Windows 10 2004 returns an error.

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 30 Jun 2020, 16:04
by JoeWinograd
gwarble wrote:I swear I saw a post this morning where someone linked to that thread and to this thread
I keep a keen eye out for this issue and don't recollect anything from this morning, although it's possible that I missed it...but I just checked all my emails from the group yesterday and today...no dice. Regards, Joe

Re: Is there a way to put an icon outside the hidden tray icons by default?

Posted: 30 Jun 2020, 16:09
by teadrinker
Like this works without errors (for unicode AHK):

Code: Select all

CLSID_TrayNotify := "{25DEAD04-1EAC-4911-9E3A-AD0A4AB560FD}"
IID_ITrayNotify8 := "{D133CE13-3537-48BA-93A7-AFCD5D2053B4}"
t := 1

q::
   pITrayNotify8 := ComObjCreate(CLSID_TrayNotify, IID_ITrayNotify8)
   VarSetCapacity(NOTIFYITEM, A_PtrSize*4 + 8 + 16, 0)
   str := "AutoHotkey.exe"
   NumPut(&str, NOTIFYITEM)
   NumPut(A_ScriptHwnd, NOTIFYITEM, A_PtrSize*3)
   NumPut((t := !t) + 1, NOTIFYITEM, A_PtrSize*4, "UInt")
   NumPut(0x404, NOTIFYITEM, A_PtrSize*4 + 4, "UInt")
   res := DllCall(NumGet(NumGet(pITrayNotify8+0) + 5*A_PtrSize), "Ptr", pITrayNotify8, "Ptr", &NOTIFYITEM, "UInt") ; SetPreference
   ToolTip % Format("{:#x}", res) ; must be 0
   ObjRelease(pITrayNotify8)
Return
but without any effect.