Before I delete it, I'll make a quick backup here.

Code: Select all
; --- update V0.1 : changed the NOTIFYICONDATA structure to receive more events
;
EnableExplicit
; Define an extended version of NOTIFYICONDATA
;
Structure NOTIFYICONDATA_2 Align #PB_Structure_AlignC ; typedef struct _NOTIFYICONDATAW {
cbSize.l ; DWORD cbSize;
hWnd.i ; HWND hWnd;
uID.l ; UINT uID;
uFlags.l ; UINT uFlags;
uCallbackMessage.l ; UINT uCallbackMessage;
hIcon.i ; HICON hIcon;
; If OSVersion() <= #PB_OS_Windows_2000 ; #if ...
; szTip.s{64} ; WCHAR szTip[64];
; Else ; #else
szTip.s{128} ; WCHAR szTip[128];
; EndIf ; #endif
dwState.l ; DWORD dwState;
dwStateMask.l ; DWORD dwStateMask;
szInfo.s{256} ; WCHAR szInfo[256];
StructureUnion ; union {
uTimeout.l ; UINT uTimeout;
uVersion.l ; UINT uVersion;
EndStructureUnion ; } DUMMYUNIONNAME;
szInfoTitle.s{64} ; WCHAR szInfoTitle[64];
dwInfoFlags.l ; DWORD dwInfoFlags;
; different behavior
guidItem.GUID ; GUID guidItem;
hBalloonIcon.l ; HICON hBalloonIcon;
EndStructure ; } NOTIFYICONDATAW, *PNOTIFYICONDATAW;
; ;
; ; --- update V0.1
; ; with these members we lost some messages (#NIN_POPUPOPEN and #NIN_POPUPCLOSE)
; ;
; Structure NOTIFYICONDATA_3 Extends NOTIFYICONDATA_2 Align #PB_Structure_AlignC
; ; ; typedef struct _NOTIFYICONDATAW {
; ;
; guidItem.GUID ; GUID guidItem;
; hBalloonIcon.l ; HICON hBalloonIcon;
; EndStructure ; } NOTIFYICONDATAW, *PNOTIFYICONDATAW;
; Define UI constants
;
Enumeration EWindow
#WINDOW
EndEnumeration
Enumeration EGadget
#GADGET_btnAdd
#GADGET_btnDelete
#GADGET_btnShowInfo
#GADGET_btnShowError
#GADGET_btnShowWarn
#GADGET_btnHide
#GADGET_lstTrace
EndEnumeration
Enumeration EEvent #PB_Event_FirstCustomValue
#EVENT_Begin
#EVENT_Finished
EndEnumeration
Enumeration EShow
#ShowInfo
#ShowError
#ShowWarn
EndEnumeration
; Define event constants and others
;
#WM_APP_ICONNOTIFY = #WM_APP + 1
;
#APP_NOTIFYICON_ID = 1
; Define uFlags .. missing definitions
;
#NIF_MESSAGE = $00000001 ; (0x00000001) 0x00000001. The uCallbackMessage member is valid.
#NIF_ICON = $00000002 ; (0x00000002) 0x00000002. The hIcon member is valid.
#NIF_TIP = $00000004 ; (0x00000004) 0x00000004. The szTip member is valid.
#NIF_STATE = $00000008 ; (0x00000008) 0x00000008. The dwState And dwStateMask members are valid.
#NIF_INFO = $00000010 ; (0x00000010) 0x00000010. Display a balloon notification. The szInfo, szInfoTitle, dwInfoFlags, And uTimeout members are valid. Note that uTimeout is valid only in Windows 2000 And Windows XP.
; To display the balloon notification, specify NIF_INFO And provide text in szInfo.
; To remove a balloon notification, specify NIF_INFO And provide an empty string through szInfo.
; To add a notification area icon without displaying a notification, do Not set the NIF_INFO flag.
#NIF_GUID = $00000020 ; (0x00000020) 0x00000020. Windows 7 And later: The guidItem is valid. Windows Vista And earlier: Reserved.
#NIF_REALTIME = $00000040 ; (0x00000040) 0x00000040. Windows Vista And later. If the balloon notification cannot be displayed immediately, discard it. Use this flag For notifications that represent real-time information which would be meaningless Or misleading If displayed at a later time. For example, a message that states "Your telephone is ringing." NIF_REALTIME is meaningful only when combined With the NIF_INFO flag.
#NIF_SHOWTIP = $00000080 ; (0x00000080) 0x00000080. Windows Vista And later. Use the standard tooltip. Normally, when uVersion is set To NOTIFYICON_VERSION_4, the standard tooltip is suppressed And can be replaced by the application-drawn, pop-up UI. If the application wants To show the standard tooltip With NOTIFYICON_VERSION_4, it can specify NIF_SHOWTIP To indicate the standard tooltip should still be shown.
; Maybe we have an Application Icon
;
Global g_hAppIcon = 0
Declare Trace(Message.s)
Procedure ShowBalloon(Title.s, Info.s, Show=#ShowInfo, NoSound=#False)
Protected nid.NOTIFYICONDATA_2
nid\cbSize = SizeOf(NOTIFYICONDATA_2)
nid\hWnd = WindowID(#WINDOW)
nid\uID = #APP_NOTIFYICON_ID
nid\uFlags = #NIF_INFO
Select Show
Case #ShowInfo : nid\dwInfoFlags = #NIIF_INFO
Case #ShowError : nid\dwInfoFlags = #NIIF_ERROR
Case #ShowWarn : nid\dwInfoFlags = #NIIF_WARNING
EndSelect
If NoSound
nid\dwInfoFlags | #NIIF_NOSOUND
EndIf
nid\szInfo = Info
nid\szInfoTitle = Title
nid\uTimeout = 2 ; s ? this does not work, because system setting is used always!
ProcedureReturn Shell_NotifyIcon_(#NIM_MODIFY, nid)
EndProcedure
Procedure ChangeTooltip(TipText.s="") ; Empty TipText hides the tooltip
Protected nid.NOTIFYICONDATA_2
nid\cbSize = SizeOf(NOTIFYICONDATA_2)
nid\hWnd = WindowID(#WINDOW)
nid\uID = #APP_NOTIFYICON_ID
nid\uFlags = #NIF_TIP | #NIF_SHOWTIP | #NIF_INFO
nid\dwInfoFlags = #NIIF_INFO
nid\szTip = TipText
ProcedureReturn Shell_NotifyIcon_(#NIM_MODIFY, nid)
EndProcedure
Procedure AddNotificationIcon()
Protected nid.NOTIFYICONDATA_2
nid\cbSize = SizeOf(NOTIFYICONDATA_2)
nid\hWnd = WindowID(#WINDOW)
nid\uID = #APP_NOTIFYICON_ID
nid\uFlags = #NIF_TIP | #NIF_SHOWTIP | #NIF_MESSAGE | #NIF_ICON
nid\dwInfoFlags = #NIIF_INFO
nid\uCallbackMessage = #WM_APP_ICONNOTIFY ; <-- self defined event for the callback procedure
If g_hAppIcon
nid\hIcon = g_hAppIcon
Else
nid\hIcon = LoadIcon_(0, #IDI_INFORMATION) ; <- plan-b :)
EndIf
nid\szTip = "Some Tooltip for this beautiful piece of code."
Shell_NotifyIcon_(#NIM_ADD, nid)
nid\uVersion = 4 ; #NOTIFYICON_VERSION_4 ; == 4 .. Use the current behavior.
Shell_NotifyIcon_(#NIM_SETVERSION, nid)
ProcedureReturn 1 ;
EndProcedure
Procedure DeleteNotificationIcon()
Protected nid.NOTIFYICONDATA_2
nid\cbSize = SizeOf(NOTIFYICONDATA_2)
nid\hWnd = WindowID(#WINDOW)
nid\uID = #APP_NOTIFYICON_ID
ProcedureReturn Shell_NotifyIcon_(#NIM_DELETE, nid)
EndProcedure
;
;
Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
Select uMsg
Case #WM_APP_ICONNOTIFY
Select (lParam & $FFFF)
Case #NIN_BALLOONTIMEOUT
Trace("-> Balloon timed out or was closed by the user")
PostEvent(#EVENT_Finished)
Case #NIN_BALLOONUSERCLICK
Trace("-> Balloon got clicked by the user")
Case #NIN_BALLOONHIDE
Trace("-> Balloon got hidden")
Case #NIN_SELECT
Trace("-> User has clicked the Icon")
Case 1026 ; ????
Trace("-> An event for what ...")
Case 1030 ; #NIN_POPUPOPEN ;
Trace("-> Mouse enters the Icon Area ")
Case 1031 ; #NIN_POPUPCLOSE ;
Trace("-> Mouse leaves the Icon Area ")
Case #WM_MOUSEMOVE
Trace("-> mouse move on Icon ")
Case #WM_LBUTTONDOWN, #WM_LBUTTONDBLCLK, #WM_RBUTTONDOWN, #WM_RBUTTONUP
Trace("-> Mouse Button Events (we do not need)")
; eat this message (because of default shows undetected messages ...)
Case #WM_CONTEXTMENU ; <-- on Right Mouse Click
Trace("-> Context Menu ... ")
Case #WM_LBUTTONUP
Trace("-> Systrayicon got clicked.")
Default ; <-- which messages are received by this
Trace("-> Default with LOWORD(lParam) == " + Str(lParam & $FFFF))
EndSelect ; (lParam & $FFFF)
EndSelect ; uMsg
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
; ---
Procedure Trace(Message.s)
Static s_lastMessage.s, s_count = 0, s_index = 0
If Message = s_lastMessage
s_count + 1
SetGadgetItemText(#GADGET_lstTrace, s_index, s_lastMessage + "(" + s_count + ")")
Else ; If Message <> s_lastMessage
s_count = 0
s_index + 1
AddGadgetItem(#GADGET_lstTrace, s_index, Message)
SetGadgetState(#GADGET_lstTrace, s_index)
s_lastMessage = Message
EndIf
;Debug "TRACE[" + RSet(Str(s_index), 4) + "]: " + Message
EndProcedure
Procedure main()
Protected title.s, info.s
If OpenWindow(#WINDOW, 0, 0, 308+176, 232, "Icon Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StickyWindow(#WINDOW, 1) ; <--- I want this window on top (for test reasons) .. should not hide behinde the IDE
ButtonGadget(#GADGET_btnAdd, 8, 8, 160, 24, "Add NotifiyIcon")
ButtonGadget(#GADGET_btnDelete, 8, 40, 160, 24, "Delete NotifiyIcon")
ButtonGadget(#GADGET_btnShowInfo, 8, 80, 160, 24, "Show Info Message")
ButtonGadget(#GADGET_btnShowError, 8, 112, 160, 24, "Show Error Message")
ButtonGadget(#GADGET_btnShowWarn, 8, 144, 160, 24, "Show Warn Message")
ButtonGadget(#GADGET_btnHide, 8, 176, 160, 24, "Hide Balloon Message")
ListViewGadget(#GADGET_lstTrace, 176, 8, 300, 216, $4000) ; #LBS_NOSEL
; You might wanna specify a path which corresponds to any valid .ico file on your system.
g_hAppIcon = LoadImage(0, #PB_Compiler_Home + "\Examples\Sources - Advanced\Waponez II\Waponez.ico")
SetWindowCallback(@WindowCallback(), #WINDOW)
AddNotificationIcon()
DisableGadget(#GADGET_btnAdd, 1)
AddGadgetItem(#GADGET_lstTrace, -1, "Show Notification Events:")
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow ; <---------------------------------------- Event
Break ; say good bye
Case #EVENT_Begin ; <------------------------------------------------- Event
DisableGadget(#GADGET_btnShowInfo, 1)
DisableGadget(#GADGET_btnShowError, 1)
DisableGadget(#GADGET_btnShowWarn, 1)
Case #EVENT_Finished ; <---------------------------------------------- Event
DisableGadget(#GADGET_btnShowInfo, 0)
DisableGadget(#GADGET_btnShowError, 0)
DisableGadget(#GADGET_btnShowWarn, 0)
Case #PB_Event_Gadget ; <--------------------------------------------- Event
Select EventGadget()
Case #GADGET_btnAdd
DisableGadget(#GADGET_btnAdd, 1)
DisableGadget(#GADGET_btnDelete, 0)
AddNotificationIcon()
Case #GADGET_btnDelete
DisableGadget(#GADGET_btnAdd, 0)
DisableGadget(#GADGET_btnDelete, 1)
DeleteNotificationIcon()
Case #GADGET_btnShowInfo
PostEvent(#EVENT_Begin)
title = "This is a balloon information."
info = "This is some example text being displayed in a balloon." + #LF$ + #LF$ + "(c) 2023 nice stuff."
ShowBalloon(title, info, #ShowInfo, #True)
Case #GADGET_btnShowError
PostEvent(#EVENT_Begin)
title = "This is the balloon error."
info = "This is some example text being displayed in a balloon." + #LF$ + #LF$ + "Ohh, this is not good."
ShowBalloon(title, info, #ShowError) ; <-- with ballon with sound !!
Case #GADGET_btnShowWarn
PostEvent(#EVENT_Begin)
title = "This is the balloon warning."
info = "This is some example text being displayed in a balloon." + #LF$ + #LF$ + "Relax -- Nothing is under control."
ShowBalloon(title, info, #ShowWarn, #True)
Case #GADGET_btnHide
PostEvent(#EVENT_Finished)
Debug "MAINLOOP: Hide Tooltip "
ChangeTooltip("") ; <-- hide the ballon
EndSelect ; EventGadget()
Case #PB_Event_SysTray ; <-------------------------------------------- Event
Debug "MAINLOOP: SysTray Event "
EndSelect ; WaitWindowEvent()
ForEver ; repeat until #PB_Event_CloseWindow
EndIf ; OpenWindow()
ProcedureReturn 0
EndProcedure
End main()