Make Application Icon visible with Systray (Windows only)
Posted: Mon Nov 13, 2023 4:08 pm
If you use the AddSystrayIcon() in your application your Icon is hidden in the systray menu window on default.
There is a (smart) way of making the icon visible with the help of the registry.
See this small example base on the Help AddSysTrayIcon() example.
There is a (smart) way of making the icon visible with the help of the registry.
See this small example base on the Help AddSysTrayIcon() example.
Code: Select all
;
; Visibility of the Application Icon if we use the Systray
; Version: 0.1
;
; Works on Windows 11
;
; ---------------------------------------------------------------------------------------------------------------------
Procedure SetNotifyIconIsPromoted(TopKey, sKeyName.s, State, ComputerName.s = "") ; State == 0 or 1
Protected hKey, lhRemoteRegistry, r1, ret_value
Protected lpData.s{256}, lpcbData, lValue
sKeyName = Trim(sKeyName)
If ComputerName = ""
r1 = RegOpenKeyEx_(TopKey, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
Else
r1 = RegConnectRegistry_(ComputerName, TopKey, @lhRemoteRegistry)
If r1 = #ERROR_SUCCESS
r1 = RegOpenKeyEx_(lhRemoteRegistry, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
EndIf
EndIf
If r1 = #ERROR_SUCCESS
If State = 0 Or State = 1 ; check the parameter
r1 = RegSetValueEx_(hKey, "IsPromoted", 0, #REG_DWORD, @State, 4)
EndIf
If r1 = #ERROR_SUCCESS
ret_value = #True
EndIf
EndIf
RegCloseKey_(hKey)
If lhRemoteRegistry
RegCloseKey_(lhRemoteRegistry)
EndIf
ProcedureReturn ret_value
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure GetNotifyIconIsPromoted(TopKey, sKeyName.s, ComputerName.s = "")
Protected ret_value, hKey, lhRemoteRegistry
Protected lpData.s{256}
Protected lpcbData, lType, lpDataDWORD, r1
sKeyName = Trim(sKeyName, "\") ;
If ComputerName = ""
r1 = RegOpenKeyEx_(TopKey, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
Else
r1 = RegConnectRegistry_(ComputerName, TopKey, @lhRemoteRegistry)
If r1 = #ERROR_SUCCESS
r1 = RegOpenKeyEx_(lhRemoteRegistry, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
EndIf
EndIf
If r1 = #ERROR_SUCCESS
lpcbData = 4 ;
r1 = RegQueryValueEx_(hKey, "IsPromoted", 0, @lType, @lpDataDWORD, @lpcbData)
If r1 = #ERROR_SUCCESS And lType = #REG_DWORD
ret_value = lpDataDWORD
Debug " IsPromoted == " + Str(lpDataDWORD)
EndIf
RegCloseKey_(hKey)
EndIf
If lhRemoteRegistry
RegCloseKey_(lhRemoteRegistry)
EndIf
ProcedureReturn ret_value
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure.s GetKeyNotifyIcon(TopKey, sKeyName.s, sProgramFileName.s, ComputerName.s = "")
Protected hKey, lhRemoteRegistry, r1, index, lpcbData, lType, lpftLastWriteTime.FILETIME
Protected lpData.s{256}, subkey.s, listsubkey.s
Protected NewList listsubkeys.s()
sKeyName = Trim(sKeyName, "\") ;
If ComputerName = ""
r1 = RegOpenKeyEx_(TopKey, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
Else
r1 = RegConnectRegistry_(ComputerName, TopKey, @lhRemoteRegistry)
If r1 = #ERROR_SUCCESS
r1 = RegOpenKeyEx_(lhRemoteRegistry, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
EndIf
EndIf
If r1 = #ERROR_SUCCESS ; with an open key
For index = 0 To 1000 ; <---------------------- should be enough ???
lpcbData = 255
r1 = RegEnumKeyEx_(hKey, index, @lpData, @lpcbData, 0, 0, 0, @lpftLastWriteTime)
If r1 = #ERROR_SUCCESS And lpcbData
AddElement(listsubkeys())
listsubkeys() = Left(lpData, lpcbData) ; <---
Else
Break ;
EndIf
Next index
RegCloseKey_(hKey) ; <------- close key
ForEach listsubkeys()
subkey = sKeyName + "\" + listsubkeys()
If lhRemoteRegistry
r1 = RegOpenKeyEx_(lhRemoteRegistry, subkey, 0, #KEY_ALL_ACCESS, @hKey)
Else
r1 = RegOpenKeyEx_(TopKey, subkey, 0, #KEY_ALL_ACCESS, @hKey)
EndIf
If r1 = #ERROR_SUCCESS
lpcbData = 255
r1 = RegQueryValueEx_(hKey, "ExecutablePath", 0, @lType, @lpData, @lpcbData)
If r1 = #ERROR_SUCCESS And lType = #REG_SZ
If Left(lpData, lpcbData - 1) = sProgramFileName
listsubkey = subkey ; <--- keep and return it !!!
Debug " => found the key "
Break ; get out of here
EndIf
EndIf
RegCloseKey_(hKey) ; <----- close key
EndIf
Next listsubkeys()
ClearList(listsubkeys())
EndIf
If lhRemoteRegistry
RegCloseKey_(lhRemoteRegistry)
EndIf
ProcedureReturn listsubkey
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
Define state, NotifyIconKey.s
Define ProgFileName.s = ProgramFilename()
If OpenWindow(0, 0, 0, 300, 100, "", #PB_Window_Invisible)
AddSysTrayIcon(0, WindowID(0), LoadImage(0, #PB_Compiler_Home + "Examples\Sources\Data\CdPlayer.ico"))
NotifyIconKey = GetKeyNotifyIcon(#HKEY_CURRENT_USER, "Control Panel\NotifyIconSettings", ProgFileName)
Debug " => " + NotifyIconKey
; Create a pop-up menu and a Systray icon (CD symbol) with this menu associated:
If CreatePopupImageMenu(0)
If NotifyIconKey
MenuItem(1, "Toggle Icon Visibility")
MenuBar()
EndIf
MenuItem(0, "Exit")
EndIf
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 1 ; Toggle Icon Visibility
If NotifyIconKey
state = 1 - GetNotifyIconIsPromoted(#HKEY_CURRENT_USER, NotifyIconKey) ; toggle
SetMenuItemState(0, 1, state)
SetNotifyIconIsPromoted(#HKEY_CURRENT_USER, NotifyIconKey, state)
EndIf
Case 0 ; Exit
RemoveSysTrayIcon(0)
FreeMenu(0)
CloseWindow(0)
End
EndSelect
EndSelect
ForEver
EndIf
CompilerEndIf