Page 1 of 2

Always show systray icon in notification area

Posted: Wed Nov 08, 2023 11:03 am
by Little John
Example code from PB's help for AddSysTrayIcon():

Code: Select all

If OpenWindow(0, 0, 0, 300, 100, "", #PB_Window_Invisible)
   ; Create a pop-up menu and a Systray icon (CD symbol) with this menu associated:
   If CreatePopupImageMenu(0)
      MenuItem(0, "Exit")
   EndIf
   AddSysTrayIcon(0, WindowID(0), LoadImage(0, #PB_Compiler_Home + "Examples\Sources\Data\CdPlayer.ico"))
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_SysTray
            Select EventType()
               Case #PB_EventType_RightClick, #PB_EventType_LeftClick
                  DisplayPopupMenu(0, WindowID(0)) ; Show pop-up menu after a mouse-click on the Systray icon
            EndSelect
         Case #PB_Event_Menu
            Select EventMenu()
               Case 0 ; Exit 
                  RemoveSysTrayIcon(0)
                  FreeMenu(0)
                  CloseWindow(0)
                  End
            EndSelect
      EndSelect
   ForEver
EndIf
When the code is run for the first time e.g. on Windows 11, the CD player icon is not shown in the taskbar notification area, but is hidden in the taskbar corner overflow (see red arrow on the left side of the following picture):

Image

I know I can move any icon from there to the taskbar notification area, e.g. by drag and drop with the mouse. However, I'm writing a program, the only purpose of which is to show an icon in the tasbar notification area that represents some information about the current status of the computer. Is it possible to programmatically tell Windows (11) to show my icon from the very beginning in the taskbar notification area, without the user having to move it there manually?

Re: Always show systray icon in notification area

Posted: Wed Nov 08, 2023 11:26 am
by Oso
Little John wrote: Wed Nov 08, 2023 11:03 am I know I can move any icon from there to the taskbar notification area, e.g. by drag and drop with the mouse.
I wish I had an answer for you, Little John, I had exactly the same requirement -- a status indicator for users.

The only solution I could find was to change the Windows setting for notifications, which I think, off the top of my head, enabled me to choose my specific application name to 'always show'. I'm not very happy with that, because when colleagues install these applications on users' PCs, they'll unfortunately have a lot of configuring to do.

I wouldn't be surprised if there's an API to do this, but I'm not well versed on that. Sorry I can't provide any more than this.

Re: Always show systray icon in notification area

Posted: Wed Nov 08, 2023 11:35 am
by BarryG
Little John wrote: Wed Nov 08, 2023 11:03 amIs it possible to programmatically tell Windows (11) to show my icon from the very beginning in the taskbar notification area, without the user having to move it there manually?
Nope. This is a Windows setting, so you can't programmatically do it. Source -> https://devblogs.microsoft.com/oldnewth ... 0/?p=10833

As Raymond said there: "Users decide which icons they want to see, and you don’t get to snoop in on the users’ decisions."

Re: Always show systray icon in notification area

Posted: Fri Nov 10, 2023 2:32 pm
by Little John
The linked text by Raymond Chen doesn't answer my question, and I didn't write a single word that I intend to snoop in on the users’ decisions.
BarryG wrote: Wed Nov 08, 2023 11:35 am As Raymond said there: "Users decide which icons they want to see [...]"
Yes, of course. When a user installs my program, the only reason for doing so is that s/he wants to see its icon. If s/he doesn't want to see the icon of my program, then the program doesn't make sense at all. Since this will be clearly documented, the user will not even install my program in that case.

As I previously wrote, my problem is that Windows “decides” not to automatically show the icon, and the user has to take extra steps to make it happen.

Re: Always show systray icon in notification area

Posted: Fri Nov 10, 2023 4:00 pm
by Oso
Little John wrote: Fri Nov 10, 2023 2:32 pm As I previously wrote, my problem is that Windows “decides” not to automatically show the icon, and the user has to take extra steps to make it happen.
I felt similarly about the article and that there's a subtle difference in terms of installing new software, then reasonably expecting to see its corresponding icon until indicating otherwise. Windows annoyingly doesn't show new systray icons because it's already far too cluttered already. The onus is on the user, unfortunately, to configure the tray to display it, but as we know, many users are just not that savvy with these things. Microsoft assumes that every user is technically proficient (and interested enough).

Re: Always show systray icon in notification area

Posted: Fri Nov 10, 2023 8:46 pm
by Little John
Hello Oso,
thanks for your reply.
Oso wrote: Fri Nov 10, 2023 4:00 pm The onus is on the user, unfortunately, to configure the tray to display it, but as we know, many users are just not that savvy with these things.
That's indeed my concern. If there is no programmatic solution (and currently it sems to me there isn't any), then I'm going to add some text to the program documentation (probably along with an animated GIF) that addresses this issue.

Re: Always show systray icon in notification area

Posted: Fri Nov 10, 2023 9:24 pm
by Oso
Little John wrote: Fri Nov 10, 2023 8:46 pm That's indeed my concern. If there is no programmatic solution (and currently it sems to me there isn't any), then I'm going to add some text to the program documentation (probably along with an animated GIF) that addresses this issue.
In fact, it was the motivation behind my question a few weeks ago about self-closing messages, which then developed into 'toast' messages and pop-outs. I felt they were preferable under the circumstances, since the tray icons are now too heavily concealed.

viewtopic.php?t=82643

I suppose it's a question of explaining to users what they need to do, as you say. For years, we've been a reseller of a database product that pauses part-way through its installation and displays a graphic image instructing how to download and install the Microsoft SDK on which it depends :(

Re: Always show systray icon in notification area

Posted: Sat Nov 11, 2023 1:37 am
by BarryG
Little John wrote: Fri Nov 10, 2023 2:32 pmmy problem is that Windows “decides” not to automatically show the icon, and the user has to take extra steps to make it happen.
Correct, which is what Raymond said is the normal behavior that can't be overridden by the app itself. Add it to your docs (like you said). It's what I've done for years.

Re: Always show systray icon in notification area

Posted: Sat Nov 11, 2023 4:11 pm
by Axolotl
Hey there,

Here is a description of how to work with the taskbar icons.
Besides Settings, Control Panel and Drag&Drop there is also the possibility to control the whole thing with the registry.

I'm just not quite sure whether it always affects the entire taskbar, or whether individual programs / icons can also be edited.
I have not tried it, .....

Re: Always show systray icon in notification area

Posted: Sat Nov 11, 2023 7:28 pm
by Little John
Axolotl wrote: Sat Nov 11, 2023 4:11 pm I'm just not quite sure whether it always affects the entire taskbar, or whether individual programs / icons can also be edited.
I don't want to programmatically change the behaviour of the whole notification area, but only the behaviour of the icon of my program. That's not described in that text.

Re: Always show systray icon in notification area

Posted: Mon Nov 13, 2023 12:34 pm
by Axolotl
Little John wrote: Sat Nov 11, 2023 7:28 pm ...
I don't want to programmatically change the behaviour of the whole notification area, but only the behaviour of the icon of my program. That's not described in that text.
Sorry, but now I found the following key contains a list of apps that use the system tray:

Code: Select all

HKEY_CURRENT_USER\Control Panel\NotifyIconSettings 
And within some of those app keys, there is a DWORD called 'IsPromoted'. If the value of this key is 1, the tray icon is visible always, and 0 means it is hidden.

If you change the value of IsPromoted, it has an immediate effect, as in you don't need to restart Explorer.exe.

I have tested this with Windows 11 Home.

Problem: The 'Key' is very unique and always different, also occurs between different users on the same device.

So, Windows appears to generate a unique app id when naming the keys, per user/system. Therefore, the solution here would be to create a tool with a loop to search through each key within 'NotifyIconSettings' to find the specific executables you are looking to promote, and when found, edit the IsPromoted DWORD with a value of 1.

Hope this helps.

Re: Always show systray icon in notification area

Posted: Mon Nov 13, 2023 12:41 pm
by Little John
Wow, many thanks Axolotl! Hopefully I'll have some time soon for taking a close look at this stuff.

Re: Always show systray icon in notification area

Posted: Mon Nov 13, 2023 12:53 pm
by Axolotl
you are welcome...

with some registry stuff from mk-soft (see here)
you can do this very easy...

Code: Select all

 
 Global RegLastMessage.s 
 
  Procedure.s FormatMessage(ErrorNumber.l)

    Protected *Buffer, len, result.s
   
    len = FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM,0,ErrorNumber,0,@*Buffer,0,0)
    If len
      result = PeekS(*Buffer, len - 2)
      LocalFree_(*Buffer)
      ProcedureReturn result
    Else
      ProcedureReturn "Errorcode: " + Hex(ErrorNumber)
    EndIf
   
  EndProcedure


Procedure.s Reg_ListSubKey(topKey, sKeyName.s, Index, ComputerName.s = "")

  Protected hKey.l, lhRemoteRegistry.l
  Protected r1.l, Result.l
  Protected lpName.s{256}, ListSubKey.s
  Protected lpcbName.l
  Protected lpftLastWriteTime.FILETIME
 
  RegLastError = 0
 
  If Left(sKeyName, 1) = "\" : sKeyName = Right(sKeyName, Len(sKeyName) - 1) : EndIf
  If Right(sKeyName,1)="\" : sKeyName = Left(sKeyName, Len(sKeyName) - 1) : EndIf
 
  If ComputerName = ""
    r1 = RegOpenKeyEx_(topKey, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
  Else
    r1 = RegConnectRegistry_(ComputerName, topKey, @lhRemoteRegistry)
    If r1 <> #ERROR_SUCCESS
      RegLastError = r1
      RegLastMessage = FormatMessage(RegLastError)
      ProcedureReturn ""
    EndIf
    r1 = RegOpenKeyEx_(lhRemoteRegistry, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
  EndIf
 
  If r1 = #ERROR_SUCCESS
    lpcbName = 255
    r1 = RegEnumKeyEx_(hKey, Index, @lpName, @lpcbName, 0, 0, 0, @lpftLastWriteTime)
    If r1 = #ERROR_SUCCESS
      ListSubKey.s = Left(lpName, lpcbName)
    Else
      RegLastError = r1
      RegLastMessage = FormatMessage(RegLastError)
      ListSubKey.s = ""
    EndIf
  Else
    RegLastError = r1
    RegLastMessage = FormatMessage(RegLastError)
    ListSubKey.s = ""
  EndIf
 
  ; Close Key
  RegCloseKey_(hKey)
  ; Close Remote
  If lhRemoteRegistry
    RegCloseKey_(lhRemoteRegistry)
  EndIf
 
  ProcedureReturn ListSubKey
EndProcedure


Procedure.s Reg_GetValue(topKey, sKeyName.s, sValueName.s, ComputerName.s = "")
   
  Protected hKey.l, lhRemoteRegistry.l
  Protected r1.l, Result.l
  Protected lpData.s{256}, GetValue.s
  Protected lType.l, lpcbData.l, lpDataDWORD.l
 
  RegLastError = 0
  GetValue.s = ""
 
  If Left(sKeyName, 1) = "\" : sKeyName = Right(sKeyName, Len(sKeyName) - 1) : EndIf
  If Right(sKeyName,1)="\" : sKeyName = Left(sKeyName, Len(sKeyName) - 1) : EndIf
 
  If ComputerName = ""
    r1 = RegOpenKeyEx_(topKey, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
  Else
    r1 = RegConnectRegistry_(ComputerName, topKey, @lhRemoteRegistry)
    If r1 <> #ERROR_SUCCESS
      RegLastError = r1
      RegLastMessage = FormatMessage(RegLastError)
      ProcedureReturn ""
    EndIf
    r1 = RegOpenKeyEx_(lhRemoteRegistry, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
  EndIf
 
  If r1 = #ERROR_SUCCESS
    lpcbData = 255
    r1 = RegQueryValueEx_(hKey, sValueName, 0, @lType, @lpData, @lpcbData)
    If r1 = #ERROR_SUCCESS
      Select lType
        Case #REG_SZ
          r1 = RegQueryValueEx_(hKey, sValueName, 0, @lType, @lpData, @lpcbData)
          If r1 = #ERROR_SUCCESS
            GetValue = Left(lpData, lpcbData - 1)
          Else
            GetValue = ""
          EndIf
        Case #REG_DWORD
          r1 = RegQueryValueEx_(hKey, sValueName, 0, @lType, @lpDataDWORD, @lpcbData)
          If r1 = #ERROR_SUCCESS
            GetValue = Str(lpDataDWORD)
          Else
            GetValue = ""
          EndIf
      EndSelect
      If r1 = #ERROR_SUCCESS
        Result = #True
      Else
        RegLastError = r1
        RegLastMessage = FormatMessage(RegLastError)
        Result = #False
      EndIf
    Else
      RegLastError = r1
      RegLastMessage = FormatMessage(RegLastError)
    EndIf
  Else
    RegLastError = r1
    RegLastMessage = FormatMessage(RegLastError)
  EndIf
 
  ; Close Key
  RegCloseKey_(hKey)
  ; Close Remote
  If lhRemoteRegistry
    RegCloseKey_(lhRemoteRegistry)
  EndIf
 
  ProcedureReturn GetValue
EndProcedure


Define nn, res.s, res2.s 


Debug "start "
For nn = 0 To 100 	; I don't know how many keys we will find ... so we check on empty string 
  res = Reg_ListSubKey(#HKEY_CURRENT_USER, "Control Panel\NotifyIconSettings", nn)
  If res 
    Debug " -> " + res 
    res2 = Reg_GetValue(#HKEY_CURRENT_USER, "Control Panel\NotifyIconSettings\" + res, "ExecutablePath") 
    
    If res2 And res2 = ProgramFilename()	 ; <-- this value only exists if you have previously executed a program with AddSysTrayIcon()  
      res2 = Reg_GetValue(#HKEY_CURRENT_USER, "Control Panel\NotifyIconSettings\" + res, "IsPromoted") 
      Debug " ----> IsPromoted == " + res2 
    EndIf 
  Else 
    Debug "escape the loop, no more keys."
    Break 
  EndIf 
Next nn 
Debug "done" 


Re: Always show systray icon in notification area

Posted: Sat Dec 02, 2023 10:37 pm
by Oso
I've just managed to catch up with this recent topic, which is of interest, on showing an application icon in the system tray by default. Would someone mind clarifying for me please, was the last code sample above, the way in which a successful outcome was achieved?

I ask the question because neither of my systems — Windows Server 2016 and Windows 10 64-bit — have HKEY_CURRENT_USER\Control Panel\NotifyIconSettings key or value shown in Regedit. The Windows 10 system has not been updated for a while. Perhaps this is a more recent addition to Windows. Thanks.

Image

Re: Always show systray icon in notification area

Posted: Sat Dec 02, 2023 11:02 pm
by Little John
Hi,

the most recent contributions to this topic are in this thread in the Tricks 'n' Tips section.
There Axolotl wrote: Yes, as far as I understood, this behavior was introduced in the 22H2 release of win11.