Teddy Rogers Posted June 1, 2020 Posted June 1, 2020 This is a repostĀ from the "PureBasic Adventures" blog... Last year a friend of mine was talking about PureBasic and how easy and good it was for coding and how much he liked working with it. I didn't really take much notice of it - it was just another Basic language, right?! Earlier this year he started showing off some of his remade old school crack intro's and demos from way back in the early 80's and 90's from the Amiga scene including some general effects so I decided to download a copy of PureBasic and tried out some of the features of the language. I liked it so much that I ended up purchasing a licence for PureBasic and have been using it ever since when I've needed to quickly code some tool or another. Why do I like it? Simply because of the ease in which I can get something done with minimal fuss and time. I can access all Windows API's and code can be natively compiled (and switched) between 32 and 64 bit with a couple of mouse clicks and PureBasics own command set is extensive. It's a very good basic language. I don't normally do blogs, it's not my thing. I certainly don't have the time but I want to help spread the language. I'm likely not going to be posting amazing demo effects as I don't have the time to be spending on such things but I will post some snippets of code I needed to come up with in PureBasic for applications or tools. I can't promise you will be wowed or amazed by any of the samples I'm really just going to be posting things I've worked on and included in some programs or just code snippets to better understand how PureBasic works. The first PureBasic sample I am going to post is some test code for a tool I coded where I needed multiple animated tray icons to be displayed to provide various information to the user. I hadn't found any similar code in PureBasic either in the example or archived code libraries or in the PureBasic forums. This example creates two tray icons that cycles through imageres.dll via threads. Imageres.dll is basically an image library that comes with Windows, I believe its on Vista and later and its similar to shell32.dll but with nicer icons and a larger library. The example also listens out for the TaskbarCreated Windows message, if the taskbar crashes and has to reload and your application does not listen for the TaskbarCreated message your trayicon will not reappear. Cycling through the icons was a cheap way to get some "animation" to show up in the example. A callback is created to listen for events happening over the tray icons such as mouse clicks and mouse hover. Normally if you have only one icon in your program you don't have to use callbacks, I needed the callbacks because it was the only way I could get multiple icons working effectively in PureBasic. The threads are used to stop the tray icons locking up once the cycling of the icons is started. I have added some comments but if you have any particular questions about the example please ask... ; ; ------------------------------------------------------------------ ; ; 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(Icon) Declare ChangeIcon(void) ; Declare some global variables... 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 IconNum = ExtractIconEx_("imageres.dll", -1, #Null, #Null, #Null) ; Register a message with the "TaskbarCreated" string Global TaskbarRestart = RegisterWindowMessage_("TaskbarCreated") ; Define two windows for seperate icons/menu's and callbacks If OpenWindow(1, 0, 0, 0, 0, "", #PB_Window_Invisible) If OpenWindow(2, 0, 0, 0, 0, "", #PB_Window_Invisible) ; These are the callbacks to watch for events on each of the icons SetWindowCallback(@WinCallback_Icon1(), 1) SetWindowCallback(@WinCallback_Icon2(), 2) ; Add the system tray icons using icons from "imageres.dll" AddSysTrayIcon(1, WindowID(1), SetImage(Num1)) AddSysTrayIcon(2, WindowID(2), SetImage(Num2)) ; Setup some tooltips... SysTrayIconToolTip(1, "You are hovering over icon 1") SysTrayIconToolTip(2, "You are hovering over icon 2") ; Create icon 1 menu with PureBasic modern look (we use "imageres.dll" for menu icons) If CreatePopupImageMenu(1, #PB_Menu_ModernLook) MenuItem(01, "Open", SetImage(174)) MenuItem(02, "Save", SetImage(39)) MenuItem(03, "Save as", SetImage(23)) MenuItem(04, "Quit", SetImage(84)) MenuBar() OpenSubMenu("Recent files") MenuItem(05, "PureBasic.exe") MenuItem(06, "Test.txt") CloseSubMenu() EndIf ; Create icon 2 menu with standard look (we use "imageres.dll" for menu icons) If CreatePopupImageMenu(2, 0) MenuItem(07, "Open", SetImage(174)) MenuItem(08, "Save", SetImage(39)) MenuItem(09, "Save as", SetImage(23)) MenuItem(10, "Quit", SetImage(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 Select EventMenu() ; 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(Icon) ExtractIconEx_("imageres.dll", Icon, 0, @iIcon, 1) If CreateImage(MyImage, 16, 16 ,32) StartDrawing(ImageOutput(MyImage)) Box(0, 0, 16, 16, GetSysColor_(#COLOR_MENU)) DrawingMode(#PB_2DDrawing_AllChannels) DrawImage(iIcon, 0, 0, 16, 16) StopDrawing() EndIf DestroyIcon_(iIcon) ProcedureReturn ImageID(MyImage) 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) ; End the thread if it is already running or start it... Select lParam Case #WM_LBUTTONDOWN If ThreadID ThreadID = #Null Else ThreadID = CreateThread(@ChangeIcon(), 0) EndIf ; Display popup-menu 1 Case #WM_RBUTTONDOWN DisplayPopupMenu(1, WindowID(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), SetImage(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) ; Cycle through "imageres.dll" icons. Windows 7 has 218 and Window 8 has 384!!! Select lParam Case #WM_LBUTTONDOWN Num2 = Num2 + 1 If Num2 > IconNum Num2 = 0 EndIf ChangeSysTrayIcon(2, SetImage(Num2)) ; Display popup-menu 2 Case #WM_RBUTTONDOWN DisplayPopupMenu(2, WindowID(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(2, WindowID(2), SetImage(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) ; Cycle through "imageres.dll" icons. Windows 7 has 218 and Window 8 has 384!!! Repeat Num1 = Num1 + 1 If Num1 > IconNum Num1 = 0 EndIf Sleep_(500) ChangeSysTrayIcon(1, SetImage(Num1)) Until ThreadID = #Null EndProcedure Ted. Animated Tray Icon.zip
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now