Balloon tip in systray

Windows specific forum
MarkH
New User
New User
Posts: 1
Joined: Thu Aug 05, 2004 4:18 pm
Location: Netherlands

Balloon tip in systray

Post by MarkH »

I couldn't find a working example on how to use the the Windows 2000/XP balloontip. So I took all the information I could find in the purebasic forum and a simular application I once wrote in VB 6. This is the result. Let me know if it doesn't work for you. It's tested on NT, W2000, XP and 98. NT and 98 off course don't have the balloontips, but the add/remove trayicon procedures still works without problems.

Mark.

Code: Select all


  #TRAY_ID = 999
  #NIM_ADD = $0
  #NIM_MODIFY = $1
  #NIM_DELETE = $2
  #NIF_MESSAGE = $1
  #NIF_ICON = $2
  #NIF_TIP = $4
  #NIF_STATE = $8
  #NIF_INFO = $10
  #NIS_SHAREDICON = $2
  #NIFF_NONE = $0
  #NIIF_INFO = $1
  #NIIF_WARNING = $2
  #NIIF_ERROR = $3
  #NIIF_NOSOUND = $10
  #NIN_BALLOONSHOW=$402
  #NIN_BALLOONHIDE=$403
  #NIN_BALLOONTIMEOUT =$404
  #NIN_BALLOONUSERCLICK=$405
  #NOTIFYICON_VERSION = $3
  #NOTIFYICONDATA_V1_SIZE = 88
  #NOTIFYICONDATA_V2_SIZE = 488
  #NOTIFYICONDATA_V3_SIZE = 504
  
Enumeration  
  #Window_0
  #TRAYICON_0
  #image_0
EndEnumeration

Structure IconData
  cbSize.l
  hwnd.l
  uID.l
  uFlags.l
  uCallbackMessage.l
  hIcon.l
  szTip.b[128]
  dwState.l
  dwStateMask.l
  szInfo.b[256]
  StructureUnion
    uTimeout.l
    uVersion.l
  EndStructureUnion
  szInfoTitle.b[64]
  dwInfoFlags.l
EndStructure 

Procedure MyWindowCallback(WindowID, Message, wParam, lParam) 
  Result = #PB_ProcessPureBasicEvents 
  Select Message
    Case #WM_USER
      Select lParam
        Case #WM_LBUTTONDOWN
          Debug "Left mousebutton click on Icon"
          
        Case #WM_RBUTTONDOWN
          Debug "Right mousebutton click on Icon"

        Case #WM_LBUTTONDBLCLK 
          Debug "Left button doublecklick on Icon"
          
        Case #WM_MOUSEMOVE
          ;Debug "Mouse moved over TrayIcon"
          
        Case #NIN_BALLOONSHOW
          Debug "SHow balloon"
          
        Case #NIN_BALLOONTIMEOUT
          Debug "Timeout or X pressed" ; The 'X' doesn't seem to be available in W2K?!
        Case #NIN_BALLOONUSERCLICK
          Debug "Balloon user click"
          
        Case #NIN_BALLOONHIDE
          Debug "Balloon closed"
          
      EndSelect
EndSelect
  
  ProcedureReturn Result 
EndProcedure 

Procedure.w GetDataSize()
  
If OpenLibrary(1,"VERSION.DLL")
  BuffSize.l= CallFunction(1,"GetFileVersionInfoSizeA","shell32.dll",0)
  If BuffSize>0 
    databuf.s=Space(BuffSize-1)
    ;Dim databuf.b(BuffSize-1)
    Result=CallFunction(1,"GetFileVersionInfoA","shell32.dll",0,BuffSize,@databuf)
    Result=CallFunction(1,"VerQueryValueA",@databuf,"\",@lpBuffer,@puLen)
    CopyMemory(lpBuffer+10,@nVerMajor,2)
  EndIf
  CloseLibrary(1)
  Select nVerMajor
    Case 6
      ProcedureReturn #NOTIFYICONDATA_V3_SIZE
      
    Case 5
      ProcedureReturn #NOTIFYICONDATA_V2_SIZE
      
    Default
      ProcedureReturn #NOTIFYICONDATA_V1_SIZE
  EndSelect
EndIf

EndProcedure

Procedure StatusAreaAddIcon(tooltiptext.s)
  Balloon.IconData\cbSize=GetDataSize()
  
  Balloon\hwnd = WindowID(#Window_0)
  Balloon\uID = #TRAY_ID
  Balloon\uFlags = #NIF_MESSAGE | #NIF_ICON | #NIF_TIP 
  Balloon\hIcon = UseImage(#image_0)
  Balloon\dwState = #NIS_SHAREDICON
  Balloon\uCallbackMessage=#WM_USER
  If OSVersion() < #PB_OS_Windows_2000
    Balloon\uVersion = 0
  Else
    Balloon\uVersion = #NOTIFYICON_VERSION
  EndIf
  Balloon\uTimeout = 11000 ; The balloon will not disappear if you don't move the mouse!
  Balloon\dwInfoFlags = #NIIF_INFO
  If Balloon.IconData\cbSize=#NOTIFYICONDATA_V1_SIZE
    PokeS(@Balloon\szTip, tooltiptext,64)
  Else
    PokeS(@Balloon\szTip, tooltiptext,128)
  EndIf
  
  Result= CallFunction(0,"Shell_NotifyIcon",#NIM_ADD,@Balloon)
EndProcedure 

Procedure StatusAreaRemoveIcon()
  Balloon.IconData\cbSize=GetDataSize()
  
  Balloon\hwnd = WindowID(#Window_0)
  Balloon\uID = #TRAY_ID
  Result= CallFunction(0,"Shell_NotifyIcon",#NIM_DELETE,@Balloon)
EndProcedure 

Procedure ShowBalloonTip(title.s,maintext.s,tooltiptext.s,IconType.l)
  Balloon.IconData\cbSize=GetDataSize()
  
  Balloon\hwnd = WindowID(#Window_0)
  Balloon\uID = #TRAY_ID
  Balloon\uFlags =  #NIF_INFO | #NIF_MESSAGE | #NIF_ICON | #NIF_TIP 
  Balloon\hIcon = UseImage(#image_0)
  Balloon\dwState = #NIS_SHAREDICON
  Balloon\uCallbackMessage=#WM_USER
  Balloon\uTimeout = 10000
  If OSVersion() < #PB_OS_Windows_2000
    Balloon\uVersion = 0
  Else
    Balloon\uVersion = #NOTIFYICON_VERSION
  EndIf
  Balloon\dwInfoFlags = IconType
  
  If Balloon.IconData\cbSize=#NOTIFYICONDATA_V1_SIZE
    PokeS(@Balloon\szTip, tooltiptext,64)
  Else
    PokeS(@Balloon\szTip, tooltiptext,128)
    PokeS(@Balloon\szInfo,maintext.s,255)
    PokeS(@Balloon\szInfoTitle,title.s,63)
  EndIf
  Result= CallFunction(0,"Shell_NotifyIcon",#NIM_MODIFY,@Balloon)
EndProcedure 


OpenLibrary(0,"shell32.dll")

If OpenWindow(#Window_0,0,0,300,90,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Status Area(Systray) Balloon tip example") And CreateGadgetList(WindowID()) 
    ButtonGadget  (1, 50, 10,200, 20, "Add Status area icon") 
    ButtonGadget  (2, 50, 30,200, 20, "Show Balloon tip") 
    ButtonGadget  (3, 50, 50,200, 20, "Remove Icon") 
    CatchImage(#image_0,?Icon)
    SetWindowCallback(@MyWindowCallback())
  
  Repeat 
    EventID = WaitWindowEvent() 
    
    Select EventID 
      
      Case #PB_Event_Gadget 
        Select EventGadgetID() 
          Case 1
            StatusAreaAddIcon("Tool tip text")
          Case 2
            ShowBalloonTip("Status Area Balloon Tip demo","This is the first line"+Chr(13)+"This should be the second line","Tool tip text",#NIIF_INFO)
          Case 3
            StatusAreaRemoveIcon()
        EndSelect 
    EndSelect 
  Until EventID = #PB_Event_CloseWindow 
  StatusAreaRemoveIcon()
  CloseLibrary(0)
EndIf 
End

DataSection
Icon:
IncludeBinary "d:\PureBasic\Examples\Sources\Data\CdPlayer.ico"
EndDataSection 
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

it works fine here.

using xp pro (dk)
Last edited by thefool on Sat Aug 07, 2004 3:59 pm, edited 1 time in total.
GreenGiant
Enthusiast
Enthusiast
Posts: 252
Joined: Fri Feb 20, 2004 5:43 pm

Post by GreenGiant »

Yep, working here too. (XP Home)
deMattin
New User
New User
Posts: 1
Joined: Thu Aug 12, 2004 9:39 pm
Location: Germany

Post by deMattin »

On Win2k (SP4) manually setting the balloon works but the #NIN-messages don't come up.
So it's not possible to substitute the default tooltip with the balloon-tip in your app.
Because if you use the mouseover-message (#WM_MOUSEMOVE) to generate the balloon, you get many messages in queue if you move the mouse over the icon (eg. move mouse over icon - 20 move-messages: ballontip stays visible for 20 x timeout time if you use this message to bring up the balloon - it's called 20 times in queue)
It would be easy to supress this by setting a block variable within the "#NIN_BALLOONSHOW" message but this message doesn't come up with win2k. I think the "#NIN_BALLOONSHOW" message under WinXP comes up when the balloon comes up?!

So you are only able to use this as a message balloon and not as a real tooltip balloon, I think.

It would be great if someone has an idea to solve this to use this balloonstyle as a real tooltip (under win2k) that comes up with the mouse over the trayicon and goes away after the timout time.

greets,
Martin
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post by Ollivier »

Updated (V4.10 B2) ! Nice code !

Code: Select all

#TRAY_ID = 999 
  #NIM_ADD = $0 
  #NIM_MODIFY = $1 
  #NIM_DELETE = $2 
  #NIF_MESSAGE = $1 
  #NIF_ICON = $2 
  #NIF_TIP = $4 
  #NIF_STATE = $8 
  #NIF_INFO = $10 
  #NIS_SHAREDICON = $2 
  #NIFF_NONE = $0 
  #NIIF_INFO = $1 
  #NIIF_WARNING = $2 
  #NIIF_ERROR = $3 
  #NIIF_NOSOUND = $10 
  #NIN_BALLOONSHOW=$402 
  #NIN_BALLOONHIDE=$403 
  #NIN_BALLOONTIMEOUT =$404 
  #NIN_BALLOONUSERCLICK=$405 
  #NOTIFYICON_VERSION = $3 
  #NOTIFYICONDATA_V1_SIZE = 88 
  #NOTIFYICONDATA_V2_SIZE = 488 
  #NOTIFYICONDATA_V3_SIZE = 504 
  
Enumeration  
  #Window_0 
  #TRAYICON_0 
  #image_0 
EndEnumeration 

Structure IconData 
  cbSize.l 
  hwnd.l 
  uID.l 
  uFlags.l 
  uCallbackMessage.l 
  hIcon.l 
  szTip.b[128] 
  dwState.l 
  dwStateMask.l 
  szInfo.b[256] 
  StructureUnion 
    uTimeout.l 
    uVersion.l 
  EndStructureUnion 
  szInfoTitle.b[64] 
  dwInfoFlags.l 
EndStructure 

Procedure MyWindowCallback(WindowID, Message, wParam, lParam) 
  Result = #PB_ProcessPureBasicEvents 
  Select Message 
    Case #WM_USER 
      Select lParam 
        Case #WM_LBUTTONDOWN 
          Debug "Left mousebutton click on Icon" 
          
        Case #WM_RBUTTONDOWN 
          Debug "Right mousebutton click on Icon" 

        Case #WM_LBUTTONDBLCLK 
          Debug "Left button doublecklick on Icon" 
          
        Case #WM_MOUSEMOVE 
          ;Debug "Mouse moved over TrayIcon" 
          
        Case #NIN_BALLOONSHOW 
          Debug "SHow balloon" 
          
        Case #NIN_BALLOONTIMEOUT 
          Debug "Timeout or X pressed" ; The 'X' doesn't seem to be available in W2K?! 
        Case #NIN_BALLOONUSERCLICK 
          Debug "Balloon user click" 
          
        Case #NIN_BALLOONHIDE 
          Debug "Balloon closed" 
          
      EndSelect 
EndSelect 
  
  ProcedureReturn Result 
EndProcedure 

Procedure.w GetDataSize() 
  
If OpenLibrary(1,"VERSION.DLL") 
  BuffSize.l= CallFunction(1,"GetFileVersionInfoSizeA","shell32.dll",0) 
  If BuffSize>0 
    databuf.s=Space(BuffSize-1) 
    ;Dim databuf.b(BuffSize-1) 
    Result=CallFunction(1,"GetFileVersionInfoA","shell32.dll",0,BuffSize,@databuf) 
    Result=CallFunction(1,"VerQueryValueA",@databuf,"\",@lpBuffer,@puLen) 
    CopyMemory(lpBuffer+10,@nVerMajor,2) 
  EndIf 
  CloseLibrary(1) 
  Select nVerMajor 
    Case 6 
      ProcedureReturn #NOTIFYICONDATA_V3_SIZE 
      
    Case 5 
      ProcedureReturn #NOTIFYICONDATA_V2_SIZE 
      
    Default 
      ProcedureReturn #NOTIFYICONDATA_V1_SIZE 
  EndSelect 
EndIf 

EndProcedure 

Procedure StatusAreaAddIcon(tooltiptext.s) 
  Balloon.IconData\cbSize=GetDataSize() 
  
  Balloon\hwnd = WindowID(#Window_0) 
  Balloon\uID = #TRAY_ID 
  Balloon\uFlags = #NIF_MESSAGE | #NIF_ICON | #NIF_TIP 
  Balloon\hIcon = ImageID(#image_0) 
  Balloon\dwState = #NIS_SHAREDICON 
  Balloon\uCallbackMessage=#WM_USER 
  If OSVersion() < #PB_OS_Windows_2000 
    Balloon\uVersion = 0 
  Else 
    Balloon\uVersion = #NOTIFYICON_VERSION 
  EndIf 
  Balloon\uTimeout = 11000 ; The balloon will not disappear if you don't move the mouse! 
  Balloon\dwInfoFlags = #NIIF_INFO 
  If Balloon.IconData\cbSize=#NOTIFYICONDATA_V1_SIZE 
    PokeS(@Balloon\szTip, tooltiptext,64) 
  Else 
    PokeS(@Balloon\szTip, tooltiptext,128) 
  EndIf 
  
  Result= CallFunction(0,"Shell_NotifyIcon",#NIM_ADD,@Balloon) 
EndProcedure 

Procedure StatusAreaRemoveIcon() 
  Balloon.IconData\cbSize=GetDataSize() 
  
  Balloon\hwnd = WindowID(#Window_0) 
  Balloon\uID = #TRAY_ID 
  Result= CallFunction(0,"Shell_NotifyIcon",#NIM_DELETE,@Balloon) 
EndProcedure 

Procedure ShowBalloonTip(title.s,maintext.s,tooltiptext.s,IconType.l) 
  Balloon.IconData\cbSize=GetDataSize() 
  
  Balloon\hwnd = WindowID(#Window_0) 
  Balloon\uID = #TRAY_ID 
  Balloon\uFlags =  #NIF_INFO | #NIF_MESSAGE | #NIF_ICON | #NIF_TIP 
  Balloon\hIcon = ImageID(#image_0) 
  Balloon\dwState = #NIS_SHAREDICON 
  Balloon\uCallbackMessage=#WM_USER 
  Balloon\uTimeout = 10000 
  If OSVersion() < #PB_OS_Windows_2000 
    Balloon\uVersion = 0 
  Else 
    Balloon\uVersion = #NOTIFYICON_VERSION 
  EndIf 
  Balloon\dwInfoFlags = IconType 
  
  If Balloon.IconData\cbSize=#NOTIFYICONDATA_V1_SIZE 
    PokeS(@Balloon\szTip, tooltiptext,64) 
  Else 
    PokeS(@Balloon\szTip, tooltiptext,128) 
    PokeS(@Balloon\szInfo,maintext.s,255) 
    PokeS(@Balloon\szInfoTitle,title.s,63) 
  EndIf 
  Result= CallFunction(0,"Shell_NotifyIcon",#NIM_MODIFY,@Balloon) 
EndProcedure 


OpenLibrary(0,"shell32.dll") 

If OpenWindow(#Window_0,0,0,300,90,"Status Area(Systray) Balloon tip example",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  If CreateGadgetList(WindowID(#Window_0))
    ButtonGadget  (1, 50, 10,200, 20, "Add Status area icon") 
    ButtonGadget  (2, 50, 30,200, 20, "Show Balloon tip") 
    ButtonGadget  (3, 50, 50,200, 20, "Remove Icon") 
    CatchImage(#image_0,?Icon) 
    SetWindowCallback(@MyWindowCallback()) 
  
  Repeat 
    EventID = WaitWindowEvent() 
    
    Select EventID 
      
      Case #PB_Event_Gadget 
        Select EventGadget() 
          Case 1 
            StatusAreaAddIcon("Tool tip text") 
          Case 2 
            ShowBalloonTip("Status Area Balloon Tip demo","This is the first line"+Chr(13)+"This should be the second line","Tool tip text",#NIIF_INFO) 
          Case 3 
            StatusAreaRemoveIcon() 
        EndSelect 
    EndSelect 
  Until EventID = #PB_Event_CloseWindow 
  StatusAreaRemoveIcon() 
  CloseLibrary(0) 
  EndIf
EndIf 
End 

DataSection 
Icon: 
IncludeBinary "h:\PureBasic\Examples\Sources\Data\CdPlayer.ico" 
EndDataSection 
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Just tested and this does not work with Vista; it's only showing "T" as normal tooltip. The second button seems to have no effect, because nothing happens.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Works fine here with Vista64 ultimate.

(have to have an icon to get the tooltip) :)

cheers

also - very nice :D
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Well, I'm using the same OS with SP1 and I use #PB_Compiler_Home to get the CD-icon, but the code does not work.
I tried it 2 times: First, I updated the code myself to 4.x and prior then I took the code of Ollivier.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

Very nice. Like it a lot.

- np
NSaneBMX
New User
New User
Posts: 4
Joined: Fri Mar 28, 2008 11:12 pm

Post by NSaneBMX »

Works so good (xp pro, sp2)
Post Reply