Always show systray icon in notification area

Windows specific forum
Little John
Addict
Addict
Posts: 4786
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Always show systray icon in notification area

Post 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?
Oso
Enthusiast
Enthusiast
Posts: 595
Joined: Wed Jul 20, 2022 10:09 am

Re: Always show systray icon in notification area

Post 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.
BarryG
Addict
Addict
Posts: 4168
Joined: Thu Apr 18, 2019 8:17 am

Re: Always show systray icon in notification area

Post 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."
Little John
Addict
Addict
Posts: 4786
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Always show systray icon in notification area

Post 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.
Oso
Enthusiast
Enthusiast
Posts: 595
Joined: Wed Jul 20, 2022 10:09 am

Re: Always show systray icon in notification area

Post 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).
Little John
Addict
Addict
Posts: 4786
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Always show systray icon in notification area

Post 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.
Oso
Enthusiast
Enthusiast
Posts: 595
Joined: Wed Jul 20, 2022 10:09 am

Re: Always show systray icon in notification area

Post 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 :(
BarryG
Addict
Addict
Posts: 4168
Joined: Thu Apr 18, 2019 8:17 am

Re: Always show systray icon in notification area

Post 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.
Axolotl
Addict
Addict
Posts: 832
Joined: Wed Dec 31, 2008 3:36 pm

Re: Always show systray icon in notification area

Post 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, .....
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Little John
Addict
Addict
Posts: 4786
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Always show systray icon in notification area

Post 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.
Axolotl
Addict
Addict
Posts: 832
Joined: Wed Dec 31, 2008 3:36 pm

Re: Always show systray icon in notification area

Post 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.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Little John
Addict
Addict
Posts: 4786
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Always show systray icon in notification area

Post by Little John »

Wow, many thanks Axolotl! Hopefully I'll have some time soon for taking a close look at this stuff.
Axolotl
Addict
Addict
Posts: 832
Joined: Wed Dec 31, 2008 3:36 pm

Re: Always show systray icon in notification area

Post 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" 

Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Oso
Enthusiast
Enthusiast
Posts: 595
Joined: Wed Jul 20, 2022 10:09 am

Re: Always show systray icon in notification area

Post 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
Little John
Addict
Addict
Posts: 4786
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Always show systray icon in notification area

Post 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.
Post Reply