System tray button count

Post a reply


In an effort to prevent automatic submissions, we require that you complete the following challenge.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: System tray button count

Re: System tray button count

Post by JoeWinograd » 13 Jan 2023, 22:57

lexikos wrote:You were already relying on it, by omitting wParam rather than passing the tray icon ID.
True enough.

Re: System tray button count

Post by lexikos » 13 Jan 2023, 22:26

JoeWinograd wrote:
13 Jan 2023, 21:55
Ah, I can use wParam for my own purposes knowing that AutoHotkey ignores it... clever!
You were already relying on it, by omitting wParam rather than passing the tray icon ID.

Re: System tray button count

Post by JoeWinograd » 13 Jan 2023, 21:55

lexikos wrote:Monitor the AHK_NOTIFYICON message to react when the user interacts with the tray icon.
Interesting idea. Looking for lParam=0x200 should do it.
lexikos wrote:no reason to override the default handling
Yes, no reason for the right-click, but I'm using it now for left-click to do Menu,Tray,Show (I had been using SKAN's NotifyTrayClick function with the NotifyTrayClick_202: label).
lexikos wrote:If you want one instance of the script to trigger some custom action in another instance of the same script, there is no need to use AHK_NOTIFYICON.
Got it!
lexikos wrote:When you send the message, wParam has whatever value you give it, or 0 if you omitted it. AutoHotkey ignores wParam, because it has only one tray icon.
Ah, I can use wParam for my own purposes knowing that AutoHotkey ignores it... clever!
lexikos wrote:AutoHotkey has default handling of the message, which will be carried out if you do not return a number.
Understood.

Thanks very much!

Re: System tray button count

Post by lexikos » 13 Jan 2023, 21:22

Is it possible to determine inside the AHK_NOTIFYICON function if it was called due to a physical right-click on the icon or the hotkey sending the message?
Monitor the AHK_NOTIFYICON message to react when the user interacts with the tray icon. Send the message to simulate user interaction with the tray icon. When I first suggested it, I was not expecting you to use OnMessage, because I saw (and still see) no reason to override the default handling.

If you want one instance of the script to trigger some custom action in another instance of the same script, there is no need to use AHK_NOTIFYICON. It doesn't matter that what you are doing is related to the tray icon or tray menu. You can pick any unused or registered message number and send that between instances, or you can use any other method of inter-process communication.

That aside, wParam should always equal AHK_NOTIFYICON (the ID of the tray icon) when the notification comes from the tray. When you send the message, wParam has whatever value you give it, or 0 if you omitted it. AutoHotkey ignores wParam, because it has only one tray icon.
; show context menu on right click - this should actually result in showing menu twice because system should automatically show it
AHK_NOTIFYICON is a custom message, with no system-defined meaning or handling. AutoHotkey has default handling of the message, which will be carried out if you do not return a number.

Re: System tray button count

Post by JoeWinograd » 11 Jan 2023, 21:53

Hi @lexikos,
The test script is working perfectly. I removed the Master instance (no need for it) and made a few cosmetic changes...everything works...left-click on the icon...right-click on the icon...and the hotkey. However, when I integrated the various (working!) components of the test script with my big program, the right and left physical clicks work, but the hotkey does not. The reason seems to be that SendMessage is coming back with FAIL (yes, the big script has the same correct WinTitle as the test script, i.e., ahk_pid %PID%). I thought it would be better to post a new thread with this issue. I'll really appreciate it if you get a chance to look at it and let me know your thoughts. Thanks, Joe

Re: System tray button count

Post by JoeWinograd » 10 Jan 2023, 00:27

lexikos wrote:I suppose you meant ahk_pid, not ahk_id.
Ah, that's it! Thank You, Thank You! One more question: Is it possible to determine inside the AHK_NOTIFYICON function if it was called due to a physical right-click on the icon or the hotkey sending the message?
lexikos wrote:Errors like this are immediately obvious in v2
Good to know for future development, but this particular program is 8,000+ lines, with 118 ErrorLevel!=0 checks (I just counted them), plus almost 1,000 lines from V1 libraries. Converting it to V2 is not on the horizon, so thanks very much for everything that you continue to do for V1. Regards, Joe

Re: System tray button count

Post by lexikos » 09 Jan 2023, 22:53

I suppose you meant ahk_pid, not ahk_id.
Errors like this are immediately obvious in v2, because an error is thrown when you attempt to do things with a window or control that does not exist.

Re: System tray button count

Post by JoeWinograd » 09 Jan 2023, 03:54

lexikos wrote:you can show a script's tray menu by sending it the same notification message that the tray would send: AHK_NOTIFYICON (1028) with lParam = WM_RBUTTONUP (0x205)
Hi lexikos,

After commenting earlier that this works perfectly and is a great solution, I discovered (when I tried to integrate it into my big script) that my testing for it was flawed. So I wrote a test script for only three colors to show the problem I'm having.

The first parameter is Color, which can be Blue, Green, or Red...or Master, which assigns the hotkeys. The second parameter is Debug, which can be 0 or 1.

By running with Debug=1, I determined that:

(1) The hotkeys are firing. For example:

blue hotkey fires.png
blue hotkey fires.png (3.4 KiB) Viewed 5983 times

(2) The GetColorPID function works correctly (PIDs returned by it match the PIDs in the Details tab of Task Manager). For example:

GetColorPID works.png
GetColorPID works.png (6.76 KiB) Viewed 5983 times

(3) AHK_NOTIFYICON gets actual/physical right and left clicks on the tray icons.

However, the hotkeys for the three colors (!#b, !#g, !#r in the posted code) do not result in opening the context for the icons. It would seem that the SendMessage command is not working, but I think it is coded correctly.

The code is below and the four supporting icons (PNG files for Blue, Green, Red, Master) are in the attached ZIP file (so is the script). I hope you can see what's wrong. Thanks very much, Joe

Code: Select all

#SingleInstance Off ; allow multiple instances to run concurrently

; get params
Color:=A_Args[1] ; Blue, Green, Red, Master
Debug:=A_Args[2] ; 0 or 1

DetectHiddenWindows,On
CurrentPID:=DllCall("GetCurrentProcessId")
Modifier:="!#"
TrayIconFile:=A_ScriptDir . "\" . Color . ".png" ; for testing, only 3 colors: Blue.png Green.png Red.png - plus Master.png
If (!FileExist(TrayIconFile))
{
  MsgBox,262160,Fatal Error,TrayIconFile does not exist:`n%TrayIconFile%
  ExitApp
}
Menu,Tray,Icon,%TrayIconFile%

If (Color="Master") ; Master assigns the hotkeys
{
  ; for testing, only 3 hotkeys
  HotkeyBlue:=Modifier . "b"
  Hotkey,%HotkeyBlue%,RightClickBlue,On
  HotkeyGreen:=Modifier . "g"
  Hotkey,%HotkeyGreen%,RightClickGreen,On
  HotkeyRed:=Modifier . "r"
  Hotkey,%HotkeyRed%,RightClickRed,On
}

OnMessage(0x404,"AHK_NOTIFYICON")

AHK_NOTIFYICON(wParam,lParam)
{
  global
  DetectHiddenWindows,On
  If ((Debug) and ((lParam=0x202) or (lParam=0x205)))
    MsgBox,,Enter AHK_NOTIFYICON,wParam=%wParam%`nlParam=%lParam%
  If (lParam=0x202) ; WM_LBUTTONUP=0x0202
    Menu,Tray,Show ; show context menu on left click, too
  If (lParam=0x205) ; WM_RBUTTONUP=0x0205
    Menu,Tray,Show ; show context menu on right click - this should actually result in showing menu twice because system should automatically show it
  Return
}

Return ; end auto-execute

RightClickBlue:
PID:=GetColorPID("Blue")
If (PID=-1)
{
  MsgBox Blue not running
  Return
}
If (Debug)
  MsgBox % "right-click Blue currpid=" . CurrentPID . "`nBluePID=" . PID
SendMessage,0x404,,0x205,,ahk_id %PID% ; WM_RBUTTONUP=0x0205
Return

RightClickGreen:
PID:=GetColorPID("Green")
If (PID=-1)
{
  MsgBox Green not running
  Return
}
If (Debug)
  MsgBox % "right-click Green currpid=" . CurrentPID . "`nGreenPID=" . PID
SendMessage,0x404,,0x205,,ahk_id %PID% ; WM_RBUTTONUP=0x0205
Return

RightClickRed:
PID:=GetColorPID("Red")
If (PID=-1)
{
  MsgBox Red not running
  Return
}
If (Debug)
  MsgBox % "right-click Red currpid=" . CurrentPID . "`nRedPID=" . PID
SendMessage,0x404,,0x205,,ahk_id %PID% ; WM_RBUTTONUP=0x0205
Return

GetColorPID(Color)
{
  global
  DetectHiddenWindows,On
  For Process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
  {
    CmdLine:=Process.CommandLine
    CmdPID:=Process.ProcessId
    If (InStr(CmdLine,A_ScriptName) and InStr(CmdLine,Color))
    {
      If (Debug)
        MsgBox,,Color Running Info - %Color%,CmdLine=%CmdLine%`nScriptName=%A_ScriptName%`nCmdPID=%CmdPID%`nCurrentPID=%CurrentPID%
      Return CmdPID ; as soon as it finds process
    }
  }
  Return -1 ; not found after looking through all processes
}
Attachments
RightClick.zip
(14.02 KiB) Downloaded 883 times

Re: System tray button count

Post by JoeWinograd » 04 Jan 2023, 21:55

lexikos wrote:The "master" script is whichever instance is reordering the tray icons at any given moment.
Understood.
lexikos wrote:One way is to set the icon of the each instance's main window (or a GUI) with WM_SETICON, so it can be retrieved with WM_GETICON. Implementing a custom message is another way.
OK, I'll look into both ways.
lexikos wrote:No, not the tray icon ID. The icon handle. TrayIcon_GetInfo returns it as hicon.
Got it.
lexikos wrote:All of the information is retrieved from a Win32 Toolbar control, which is non-existent on newer builds.
Ah, got it this time...didn't sink in the first time around.

Thanks, Joe

Re: System tray button count

Post by lexikos » 04 Jan 2023, 18:13

JoeWinograd wrote:
03 Jan 2023, 23:50
I don't have the notion of a "master" script, but I could.
It doesn't matter. The "master" script is whichever instance is reordering the tray icons at any given moment.
I can get the PID without using TrayIcon_GetInfo, but don't know if I can get the icon's handle from that...
You can't, unless you implement some way to "ask" the window for its icon. One way is to set the icon of the each instance's main window (or a GUI) with WM_SETICON, so it can be retrieved with WM_GETICON. Implementing a custom message is another way. If you have a GUI window, you can just use WM_GETICON because the icon is already set for you.
what TrayIcon_GetInfo returns as uID.
No, not the tray icon ID. The icon handle. TrayIcon_GetInfo returns it as hicon.

The tray icon ID is always AHK_NOTIFYICON, as I said. Only the HWND-ID pair needs to be unique. AutoHotkey only has one tray icon, so it can just use a constant ID.
Maybe I can pull the code from TrayIcon_GetInfo that gets the uID, but I haven't looked at it carefully yet to know if that's possible in the latest W11.
No, none of that will work, otherwise you wouldn't have started this topic. All of the information is retrieved from a Win32 Toolbar control, which is non-existent on newer builds.

Re: System tray button count

Post by JoeWinograd » 03 Jan 2023, 23:50

lexikos wrote:I suppose that you can just (re)load the scripts in right-to-left order.
For some programs that would work well. For others (such as the Stars program), that would be a big performance hit, as it can take several seconds to load each color star (depending on its configuration). That's one of the nice features of TrayIcon_Move...it's fast.
lexikos wrote:Another option would be to monitor a custom message with OnMessage, and have your master script send this message to each script to instruct it to reapply the tray icon (A_IconHidden := true, A_IconHidden := false).
Fascinating idea! I don't have the notion of a "master" script, but I could. Currently, all the programs with multiple instances (and, thus, multiple/different icons, such as the Stars and Keys programs) execute the same EXE without any master script that runs and/or controls them.
lexikos wrote:Shell_NotifyIcon can be used externally to remove the icon, and I'm almost certain it could be used to add the icon back
Another very interesting idea!
lexikos wrote:but you would need to get a handle to the appropriate icon
I can get the PID without using TrayIcon_GetInfo, but don't know if I can get the icon's handle from that...what TrayIcon_GetInfo returns as uID. Maybe I can pull the code from TrayIcon_GetInfo that gets the uID, but I haven't looked at it carefully yet to know if that's possible in the latest W11.
lexikos wrote:Loading the icon from file in your master script might cause issues if the master script exits before the other process.
If I decide to go with a master script, thanks for the heads-up on that.

Regards, Joe

Re: System tray button count

Post by lexikos » 03 Jan 2023, 00:04

JoeWinograd wrote:The only issue left now is moving/ordering the tray icons
I wrote:The newest icon is placed on the left, so if you remove the icon and add it back, it will move to the far left of the group.
I suppose that you can just (re)load the scripts in right-to-left order.

Another option would be to monitor a custom message with OnMessage, and have your master script send this message to each script to instruct it to reapply the tray icon (A_IconHidden := true, A_IconHidden := false).

Shell_NotifyIcon can be used externally to remove the icon, and I'm almost certain it could be used to add the icon back (or even add an icon for a script that didn't have one), but you would need to get a handle to the appropriate icon. Loading the icon from file in your master script might cause issues if the master script exits before the other process.

Re: System tray button count

Post by JoeWinograd » 02 Jan 2023, 22:48

lexikos wrote:Yes, there is.
Got it!
lexikos wrote:what I see in the screenshots is that all of the stars are grouped together
OK, we're on the same page now. I was imparting a different meaning to "grouped together". Now I understand what you said.
lexikos wrote:you can show a script's tray menu by sending it the same notification message that the tray would send: AHK_NOTIFYICON (1028) with lParam = WM_RBUTTONUP (0x205)
Works perfectly on the latest W11! Great solution! The only issue left now is moving/ordering the tray icons, which I may just simply ditch for A_OSVersion>=10.0.22623 (along with ditching the icon report). Thanks for your help on this. Regards, Joe

Re: System tray button count

Post by lexikos » 02 Jan 2023, 21:09

JoeWinograd wrote:
02 Jan 2023, 15:01
Sorry for the delayed response. I'm in the U.S. Central time zone and had packed it in for the night.
In this medium, I prefer delayed responses. I'd guess most forum users are inactive while I am active (UTC+10).
There is no main window that is always running.
Yes, there is. If there was no window, where do you think the message would be sent, in order to detect that the tray icon was clicked? When I say the script's main window, I mean the script's main window. Every script has it. You must target this window, not one of your GUI windows.
The icons are split, as you can see with the Stars and Keys screenshots above...
No, what I see in the screenshots is that all of the stars are grouped together (icons belonging to Stars.exe), and all of the keys are grouped together (icons belonging to Keys.exe). As I said, I listed the results of testing with multiple instances of one script. In practice, whether they are one script or multiple scripts doesn't matter; only the exe matters.

Re: System tray button count

Post by JoeWinograd » 02 Jan 2023, 15:01

Hi lexikos,

Sorry for the delayed response. I'm in the U.S. Central time zone and had packed it in for the night.
lexikos wrote:You don't need to get that from the tray, because I told you what the message number is, AutoHotkey ignores the ID number when handling the message, and you can find the HWND with WinExist or WinGet List
Ah, got it! Missed that the first time around.
lexikos wrote:or directly address the script's main window by title instead
There is no main window that is always running. The only time a desktop window appears is when the user opens one via the tray context menu (or runs the program's desktop or Start menu shortcut, but that main window goes away after loading the color star icons into the tray).
lexikos wrote:If your alternative to TrayIcon_Remove isn't working out, you might consider using Shell_NotifyIcon.
So far, it's working out, but thanks for the idea...always good to have alternatives. The issue is that I had been using Process,Close with the uID and hWnd returned by TrayInfo, but that leaves stale icons in the tray, so I did a TrayIcon_Remove before the Process,Close to prevent the stale icons. I switched to using DetectHiddenWindows,On followed by a search for the pID via ComObjGet("winmgmts:") on Win32_Process (I know what the CommandLine is that runs the program). Now I'm doing a WinClose,ahk_pid, which properly removes the tray icon.
lexikos wrote:I'm going to guess that the stars are all one program, and the keyboard indicator icons are all a second program. That meaning two programs with multiple instances each, not one program per icon.
Correct! Each instance of a particular program is created via a unique parameter on its command line. For example:

Stars.exe Blue
Stars,exe Green
Stars,exe Red
Keys.exe CapsLock
Keys.exe NumLock
Keys.exe ScrollLock
lexikos wrote:My point was that Windows might not differentiate between multiple icons belonging to one program, with respect to representing them in the Settings app
Interesting point! I just checked Stars.exe and Keys.exe in the Settings app on W11/22H2/22623.1037...you are correct...it does not differentiate! They are either all on or all off. Actually, there's only a single entry for the executable, regardless of the number of instances (with different icons) that are running.
lexikos wrote:or restoring the order when new instances start
Just tested...does not happen.
lexikos wrote:maybe it will leave them in the order that they are added to the tray
It does.
lexikos wrote:In that case, you can remove them and add them back in the appropriate order.
Yes.
lexikos wrote:Windows will refuse to split the icons apart; they are always grouped together.
Not what I'm seeing here. The icons are split, as you can see with the Stars and Keys screenshots above...unless I'm misunderstanding your comment, which I probably am.
lexikos wrote:If you try to drag-drop some other icon between the script's icons, it will end up at either end.
Yes, same behavior here.
lexikos wrote:If you drag one icon to or from the overflow window, the other icons will follow. You cannot "promote" or "demote" the individual icons, only the app to which they belong.
Yes, same behavior here.
lexikos wrote:Drag-drop within the group does not work as expected; whichever icon you drag ends up at the far right.
Yes, same behavior here.
lexikos wrote:The newest icon is placed on the left, so if you remove the icon and add it back, it will move to the far left of the group.
Yes, same behavior here.

Thanks again for your help. Regards, Joe

Re: System tray button count

Post by lexikos » 02 Jan 2023, 03:45

That seems to be what the TrayIcon_Button function does, which is not working on the recent W11 builds.
TrayIcon_Button fails because it relies on the information returned by TrayIcon_GetInfo, which fails. Specifically, it tries to get the message number, ID and HWND based on the process name you gave it. You don't need to get that from the tray, because I told you what the message number is, AutoHotkey ignores the ID number when handling the message, and you can find the HWND with WinExist or WinGet List (or directly address the script's main window by title instead).

The ID number is the same as the message number (1028). This is used with the Shell_NotifyIcon function to add, modify or delete the tray icon ...

Oh. :idea:

If your alternative to TrayIcon_Remove isn't working out, you might consider using Shell_NotifyIcon. See KillTrayIcon.

As noted above, each of my programs is a separately compiled script
But is each icon a separate program? Based on your description, I'm going to guess that the stars are all one program, and the keyboard indicator icons are all a second program. That meaning two programs with multiple instances each, not one program per icon. My point was that Windows might not differentiate between multiple icons belonging to one program, with respect to representing them in the Settings app, persisting them when the program terminates, or restoring the order when new instances start.

That might work out in your favor. I'd guess that if Windows remembers what order the icons should be in, it will put them in that order, ignoring the order that the tray icons were most recently added to the tray. If it doesn't remember the order of individual icons, maybe it will leave them in the order that they are added to the tray. In that case, you can remove them and add them back in the appropriate order.
I don't know...haven't tested that.
I know, because I tested it, hence my words. But I had only tested it on build 22623.1037 with separate programs, one icon per program.

Now I've tested with multiple instances of one script. What I have observed is:
  • Windows will refuse to split the icons apart; they are always grouped together. If you try to drag-drop some other icon between the script's icons, it will end up at either end.
  • If you drag one icon to or from the overflow window, the other icons will follow. You cannot "promote" or "demote" the individual icons, only the app to which they belong.
  • Drag-drop within the group does not work as expected; whichever icon you drag ends up at the far right.
  • The newest icon is placed on the left, so if you remove the icon and add it back, it will move to the far left of the group.

Re: System tray button count

Post by JoeWinograd » 02 Jan 2023, 00:48

lexikos wrote:giving up certain features
Yes, I'm starting to do that. For example, one program has a feature to create a tray icon report, either for all icons in the tray or just for that program's icons (there can be many). The report contains each icon's position number in the tray, its owning process, tooltip, and which tray it is in (Shell_TrayWnd or NotifyIconOverflowWindow). It's a useful report, but at this point, I'm willing to give it up on W11.
lexikos wrote:or supporting only older builds
Agreed. For example, I may keep the tray icon report on earlier W11 builds and all W10 (and prior) releases.
lexikos wrote:These are tray icons created by your scripts?
Each instance of the program has its own icon. For example, one program has various color stars in the tray, such as Blue, Green, Red, Yellow (and lots more):

color star tray icons.png
color star tray icons.png (2.16 KiB) Viewed 6521 times

Another program allows the user to toggle Caps Lock, Num Lock, and Scroll Lock via tray icons. Each key's icon is red when it's off and green when it's on:

caps num scroll lock tray icons.png
caps num scroll lock tray icons.png (1.42 KiB) Viewed 6521 times

Both of those programs have a feature that allows the user to move the icons in the tray. For example, the Caps Lock, Num Lock, and Scroll Lock icons have this context submenu hanging off a Tools menu:

move tray icons.png
move tray icons.png (2.08 KiB) Viewed 6521 times

The process name is the same for all instances of the same program. The various programs are compiled with Ahk2Exe and they all have an installer (a Setup.exe file) created with NSIS.
lexikos wrote:Why automate the tray icons when you can automate the script itself?
The programs have plenty of automation, but I chose to have the UI for these programs center around the context menus of the system tray icons, although many of the context menu choices lead to "normal" windows, many of which contain GUIs, ListViews, etc.
lexikos wrote:You can show a script's tray menu by sending it the same notification message that the tray would send: AHK_NOTIFYICON (1028) with lParam = WM_RBUTTONUP (0x205).
That seems to be what the TrayIcon_Button function does, which is not working on the recent W11 builds. It would be great if I can assign a hotkey to that for each instance, such as Alt+Ctrl+B to open the context menu of the Blue star.
lexikos wrote:Maybe that's not an issue if the tooltips are unique.
Correct...not an issue...each running instance has a unique tooltip.
lexikos wrote:The user can still re-order them with drag-drop
Yes. That had stopped working in W11 Build 22581, but Microsoft fixed it. Interesting thread with Microsoft on that issue (8 months ago):
Microsoft Response: We'll be continuing to monitor this feedback, but with the updates we made for the new tablet-optimized taskbar in Build 22563, we're no longer supporting dragging icons in the system tray or between the system tray and the show hidden icons flyout. Instead, you should use the Settings > Personalization > Taskbar > System tray section to manage these icons.

UPDATE: We have decided to disable the changes to the system tray introduced in Build 22581 for now. The system tray and the Show hidden icons flyout will now function the same way it did with the original release of Windows 11, including the ability to rearrange icons in the flyout. We hope to bring these changes back in the future after further refinement of the experience by addressing some of this feedback. This is now available with Build 22616, now available in the Dev and Beta Channels: https://aka.ms/wip22616
lexikos wrote:as far as I can tell, the order persists across reboots
I don't know...haven't tested that.
lexikos wrote:but maybe for separate compiled scripts
As noted above, each of my programs is a separately compiled script, each with its own (Setup.exe) installer, so that may work.

Thanks for all your thoughts on this...much appreciated! Regards, Joe

Re: System tray button count

Post by lexikos » 01 Jan 2023, 23:28

I meant "alternatives" pretty broadly, including changing your UI to use more conventional patterns built on officially supported APIs, giving up certain features... or supporting only older builds.

These are tray icons created by your scripts? Why automate the tray icons when you can automate the script itself? You can show a script's tray menu by sending it the same notification message that the tray would send: AHK_NOTIFYICON (1028) with lParam = WM_RBUTTONUP (0x205). These are "documented" in the source code, but if you are not comfortable with relying on that, you can implement your own messages or some other form of IPC.

Tray icons must be readable by screen readers and other accessibility software, so can likely be read by MSAA and UI Accessibility, which can also determine the icon's location or set focus to it. However, it's likely that you'll only get the location and tooltip, not any details that identify which process owns it. Maybe that's not an issue if the tooltips are unique.

I doubt there is any way to reorder a XAML-based set of icons/buttons from outside the application which created them, aside from using the mouse. The user can still re-order them with drag-drop, and as far as I can tell, the order persists across reboots. I think that the order is persisted in the same place as the icon's visibility; in the TrayNotify registry key. I've read that Microsoft obfuscated this and specifically chose not to provide programmatic access, to put the user in control (or so they say). Others have apparently worked out that the content of the key uses the ROT13 cipher. You could do some research and try your luck. I suspect that it won't work well for multiple instances of the same application (e.g. AutoHotkey.exe), but maybe for separate compiled scripts.

Re: System tray button count

Post by JoeWinograd » 01 Jan 2023, 21:45

lexikos wrote:Comparing the two, I see the cause of the issue quite clearly.
Thanks for figuring that out and providing the explanation.
lexikos wrote:I would suggest considering alternatives.
I'll gladly consider any alternatives, even if they work only with W11/22623.1020+. I already started doing that, but coming up short. I've been using four functions from the TrayIcon library:

TrayIcon_GetInfo - But I need this only for the other functions, so if I can find alternatives to the functions below, I don't need this one.

TrayIcon_Remove - I have an alternative approach for what I was doing with this. Need to solve only the two below.

TrayIcon_Button - This is the most important. I use it to establish hotkeys that right-click the tray icons so that physically impaired users who have trouble using a mouse can use the keyboard to expose the tray icon's context menu. Do you know an alternative way to do this?

TrayIcon_Move - Several of my programs have multiple instances running, each with its own (different) icon. Their position in the tray is important to users, so I offer three tools to position them: (1) Move All Icons to Beginning of Tray, (2) Move All Icons to End of Tray, (3) Put Icons in Custom Order (based on a user-specified configuration file). Do you know an alternative way to do this?

Thanks much, Joe

Re: System tray button count

Post by lexikos » 01 Jan 2023, 20:30

I have 22621.963 on my main computer, but found I have 22623.1037 on my laptop. Comparing the two, I see the cause of the issue quite clearly.

For the overflow area, it is not exactly that the toolbar messages are not working, but that the window and control you are looking for doesn't exist. The overflow window class is now "TopLevelWindowForOverflowXamlIsland" rather than "NotifyIconOverflowWindow", and it does not contain a Win32 toolbar control.

Errors like this are immediately obvious in v2, because an error is thrown when you attempt to do things with a window or control that does not exist.

As for the main tray, there are still toolbar controls with the text "System Promoted Notification Area" and "User Promoted Notification Area", but they have zero width and height, and are not visible.

It appears that the taskbar and overflow area now use XAML to represent the tray icons. You may notice that the highlight around tray icons now has rounded corners like the rest of the UI, whereas older builds had a rectangular highlight with sharp edges like Windows 10. I believe this was just a matter of time, as most of the Windows 11 UI uses XAML. It wouldn't make sense to embed Win32 controls within that indefinitely, especially given that they don't support things like legacy toolbars on the taskbar.

This change of controls is clearly by design. Perhaps they could insert buttons into the hidden toolbar control as well to make your script work - maybe this is the purpose for which they have kept the two toolbar windows - but it seems very unlikely to me, as they assuredly never supported the use of toolbar messages as a means of manipulating the tray icons. I would suggest considering alternatives.

Top