Dual SysTray, Threaded & "Animated" "imageres.dll" Icons...
Posted: Sun Mar 30, 2014 1:16 pm
This afternoon I had some spare time and decided to see what I can do with PureBasic. I was looking through some of the examples and noticed the system tray example displayed two icons but no menu(s). Thought I'd have a try at fixing that. In the process I entirely used icons from "imageres.dll" and one of the tray icons automatically cycles through the whole set. I guess this could be a way of adding system tray icon animation if you wanted to modify it. It's threaded too so it allows the menu to be used when in operation. The second tray icon when clicked on cycles through the icons manually. The menu's I could only get to display separately by using SetWindowCallback. I'm not sure if "imageres.dll" is available on Windows Vista but it's available on Windows 7 and 8 in varying quantities of icons.
Feel free to use and abuse it, I'm still very green to PureBasic so I'm interested on seeing your improvements! If this is in the wrong forum please move it...
Ted.
Feel free to use and abuse it, I'm still very green to PureBasic so I'm interested on seeing your improvements! If this is in the wrong forum please move it...
Code: Select all
;
; ------------------------------------------------------------------
;
; Dual SysTray, Threaded & "Animated" "imageres.dll" System Icons
; "imageres.dll" is available on Window 7 & 8 (Vista??)
;
; By Teddy Rogers / PureBasic 5.22
;
; ------------------------------------------------------------------
;
; Declare our procedures
Declare WinCallback_Icon1(WindowID, uMsg, wParam, lParam)
Declare WinCallback_Icon2(WindowID, uMsg, wParam, lParam)
Declare SetImage(iMenu, iID, ico)
Declare ChangeIcon(void)
; Setup some variables/constants
Global Num1 = 100 ; Set our default "imageres.dll" tray icon 1
Global Num2 = 101 ; Set our default "imageres.dll" tray icon 2
Global ThreadID ; This is used to end the thread
Global TaskbarRestart = RegisterWindowMessage_("TaskbarCreated") ; Register a message with the "TaskbarCreated" string
; Start the example program...
If OpenWindow(1, 0, 0, 0, 0, "", #PB_Window_Invisible) ; Define two windows for seperate icons/menu's and callbacks
If OpenWindow(2, 0, 0, 0, 0, "", #PB_Window_Invisible)
SetWindowCallback(@WinCallback_Icon1(), 1) ; These are the callbacks to watch for events on each of the icons
SetWindowCallback(@WinCallback_Icon2(), 2)
AddSysTrayIcon(1, WindowID(1), ImageID(SetImage(WindowID(1), 0, Num1))) ; Add the system tray icons using icons from "imageres.dll"
AddSysTrayIcon(2, WindowID(2), ImageID(SetImage(WindowID(2), 0, Num2)))
SysTrayIconToolTip(1, "You are hovering over icon 1") ; Setup some tooltips...
SysTrayIconToolTip(2, "You are hovering over icon 2")
If CreatePopupImageMenu(0, #PB_Menu_ModernLook) ; Create icon 1 menu with PureBasic modern look (we use "imageres.dll" for menu icons)
MenuItem(01, "Open", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 174)))
MenuItem(02, "Save", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 39)))
MenuItem(03, "Save as", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 23)))
MenuItem(04, "Quit", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 84)))
MenuBar()
OpenSubMenu("Recent files")
MenuItem(05, "PureBasic.exe")
MenuItem(06, "Test.txt")
CloseSubMenu()
EndIf
If CreatePopupImageMenu(2, 0) ; Create icon 2 menu with standard look (we use "imageres.dll" for menu icons)
MenuItem(07, "Open", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 174)))
MenuItem(08, "Save", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 39)))
MenuItem(09, "Save as", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 23)))
MenuItem(10, "Quit", ImageID(SetImage(GetSubMenu_(MenuID(0),0), 0, 84)))
MenuBar()
OpenSubMenu("Recent files")
MenuItem(11, "PureBasic.exe")
MenuItem(12, "Test.txt")
CloseSubMenu()
EndIf
; Wait for a MenuItem to be selected... then do some stuff...
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Menu ; An item of the popup-menu was clicked
Select EventMenu() ; Get the clicked menu item...
; Icon 1 menu actions...
Case 01 : Debug "Menu: Open (Icon 1)"
Case 02 : Debug "Menu: Save (Icon 1)"
Case 03 : Debug "Menu: Save as (Icon 1)"
Case 04 : End
Case 05 : Debug "Menu: PureBasic.exe (Icon 1)"
Case 06 : Debug "Menu: Text.txt (Icon 1)"
; Icon 2 menu actions...
Case 07 : Debug "Menu: Open (Icon 2)"
Case 08 : Debug "Menu: Save (Icon 2)"
Case 09 : Debug "Menu: Save as (Icon 2)"
Case 10 : End
Case 11 : Debug "Menu: PureBasic.exe (Icon 2)"
Case 12 : Debug "Menu: Text.txt (Icon 2)"
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
EndIf
EndIf
; We will use the Windows default system icons for our own the menu options
Procedure SetImage(iMenu, iID, ico)
ExtractIconEx_("imageres.dll", ico, 0, @iIcon, 1)
im=CreateImage(#PB_Any, 16, 16 ,32) ; Dimensions and bit depth (16, 256, 32bits)
StartDrawing(ImageOutput(im))
Box(0, 0, 16, 16, GetSysColor_(#COLOR_MENU))
DrawingMode(#PB_2DDrawing_AllChannels)
DrawImage(iIcon, 0, 0, 16, 16) ; Display icon size
StopDrawing()
DestroyIcon_(iIcon)
ProcedureReturn im
EndProcedure
; Icon Number 1 (clicking left mouse button starts automatic cycling through the icons, clicking left again end the thread)
Procedure WinCallback_Icon1(WindowID, uMsg, wParam, lParam)
Select lParam
Case #WM_LBUTTONDOWN
If Not ThreadID = 1
CreateThread(@ChangeIcon(), 0)
Else
ThreadID = 0 ; Tell the running thread to end.
EndIf
Case #WM_RBUTTONDOWN
DisplayPopupMenu(0, WindowID(1)) ; Display popup-menu 1
EndSelect
; Listen for "TaskbarCreated" broadcast to be sent to all windows if the taskbar is recreated then...
; Recreate our tray icon including the tool tip...
Select uMsg
Case TaskbarRestart
AddSysTrayIcon(1, WindowID(1), ImageID(SetImage(WindowID(1), 0, Num1)))
SysTrayIconToolTip(1, "You are hovering over icon 1")
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
; Icon Number 2 (clicking left mouse button manually cycles through the icons one at a time)
Procedure WinCallback_Icon2(WindowID, uMsg, wParam, lParam)
Select lParam
Case #WM_LBUTTONDOWN
If Not Num2 = 218 ; Cycle through "imageres.dll" icons. Windows 7 has 218 and Window 8 has 384!!!
ChangeSysTrayIcon(2, ImageID(SetImage(WindowID(2), 0, Num2)))
Num2 + 1
Else
Num2 = 0
EndIf
Case #WM_RBUTTONDOWN
DisplayPopupMenu(2, WindowID(1)) ; Display popup-menu 2
EndSelect
; Listen for "TaskbarCreated" broadcast to be sent to all windows if the taskbar is recreated then...
; Recreate our tray icon including the tool tip...
Select uMsg
Case TaskbarRestart
AddSysTrayIcon(2, WindowID(2), ImageID(SetImage(WindowID(2), 0, Num2)))
SysTrayIconToolTip(2, "You are hovering over icon 2")
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
; Create a thread to cycle through the icons, creating a thread allows us to continue using tray menu(s)
Procedure ChangeIcon(void)
ThreadID = 1 ; If we set this we can check if we have a thread running so we don't start it again
Repeat
If Not Num1 = 218 ; Cycle through "imageres.dll" icons. Windows 7 has 218 and Window 8 has 384!!!
Sleep_(500)
ChangeSysTrayIcon(1, ImageID(SetImage(WindowID(1), 0, Num1)))
Num1 + 1
Else
Num1 = 0
EndIf
Until ThreadID = 0
EndProcedure