Re: [SUPERIOR!!] (Windows) Mouse Over Gadget BalloonTips

Share your advanced PureBasic knowledge/code with the community.
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: [SUPERIOR!!] (Windows) Mouse Over Gadget BalloonTips

Post by Randy Walker »

[LATEST EDIT] 02/20/26 Forget all the garbage below and jump to the best part here: viewtopic.php?p=651852#p651852

[EDIT] 02/20/26 More ultimate than any posted here so far. This uses an include file as the engine to create and edit the BalloonTip. See it here: viewtopic.php?p=651836#p651836

[OLD/OBSOLETE EDIT] Go to my next post for more proper solution. This first post just illustrates over thinking the problem.
Kind of embarrassing. :oops:
[OLD/OBSOLETE EDIT] =2/18/26 -- Better yet, go here for an even better solution{ viewtopic.php?p=651787#p651787

I suspect some here have a more sophisticated way to do this but this works for me. I wanted to get tootips by hovering on various gadgets and it may not be pretty but it works:

Code: Select all

EnableExplicit

Define Event
Dim Disc.s(10)  ; Gadget description Array
Enumeration
  #Gad0
  #Gad1
  #Gad2
  #Gad3
  #Gad4
  #Gad5
EndEnumeration
;EXTRA SPACE HERE VVVVVV MOVES TEXT TO RIGHT OFTHE MOUSE POINTER So you can read the text
Disc(#Gad0)  = "`       LISTBOX #0"
Disc(#Gad1) = "`        Button #1"
Disc(#Gad2) = "`        Button #2"
Disc(#Gad3)  = "`       STRING #3"
Disc(#Gad4)  = "`       STRING #4"

OpenWindow(0, 100, 100, 320, 200, "REAL Hover Test")

ListViewGadget(#Gad0,5,5,200,60)
ButtonGadget(#Gad1, 40, 70, 100, 30, "Button 1")
ButtonGadget(#Gad2, 180, 70, 100, 30, "Button 2")
StringGadget(#Gad3,49,110,100,30,"")
StringGadget(#Gad4,49,155,100,30,"")
AddWindowTimer(0, 1, 300)

Global lastID = -1
Global pt.POINT
Global hwnd
Global id

Repeat
    event = WaitWindowEvent()
    Select Event
       Case #PB_Event_Timer 
            GetCursorPos_(pt)  ;<<<< Save energy -- Wait for timer to test mouse position
            hwnd = WindowFromPoint_(PeekQ(@pt)) ; POINT passed as 64-bit
            If hwnd
              id = GetDlgCtrlID_(hwnd) ; Convert Win Handle to gadget ID Number
              Debug GetDlgCtrlID_(hwnd)
            EndIf
             Select id
               Case #Gad0 To #Gad4  ; ONLY acknowledge our gadgets
                 GadgetToolTip(id,Disc(id))
             EndSelect
    EndSelect
Until event = #PB_Event_CloseWindow
After burning up hours with ChatGPT to get a staring point. Maybe this will help some newcomer.
Last edited by Randy Walker on Sat Feb 21, 2026 2:10 am, edited 7 times in total.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: (Windows) Mouse Over Gadget TIPS

Post by Randy Walker »

OK, Let me be the first to say DUHHHhhh!!!!
HOw much simpler can it get? DUHH!!
The proper way:

Code: Select all

Dim Disc.s(10)  ; Gadget description Array
Enumeration
  #Gad0
  #Gad1
  #Gad2
  #Gad3
  #Gad4
  #Gad5
EndEnumeration
;EXTRA SPACE HERE VVVVVV MOVES TEXT TO RIGHT OFTHE MOUSE POINTER So you can read the text
Disc(#Gad0)  = "`       LISTBOX #0"
Disc(#Gad1) = "`        Button #1"
Disc(#Gad2) = "`        Button #2"
Disc(#Gad3)  = "`       STRING #3"
Disc(#Gad4)  = "`       STRING #4"

OpenWindow(0, 100, 100, 320, 200, "REAL Hover Test")

ListViewGadget(#Gad0,5,5,200,60)
ButtonGadget(#Gad1, 40, 70, 100, 30, "Button 1")
ButtonGadget(#Gad2, 180, 70, 100, 30, "Button 2")
StringGadget(#Gad3,49,110,100,30,"")
StringGadget(#Gad4,49,155,100,30,"")
GadgetToolTip(#Gad0, Disc(#Gad0))
GadgetToolTip(#Gad1, Disc(#Gad1))
GadgetToolTip(#Gad2, Disc(#Gad2))
GadgetToolTip(#Gad3, Disc(#Gad3))
GadgetToolTip(#Gad4, Disc(#Gad4))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
AZJIO
Addict
Addict
Posts: 2284
Joined: Sun May 14, 2017 1:48 am

Re: (Windows) Mouse Over Gadget TIPS

Post by AZJIO »

Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: (Windows) Mouse Over Gadget TIPS

Post by Randy Walker »

AZJIO wrote: Tue Feb 17, 2026 5:51 pm BalloonTip
Your link didn't take me to a solution, but I searched the term BallonTip And found a very cool post from QuimV:
viewtopic.php?p=194837#p194837 <<< (THIS IS THE BEST!!!!)
...that does give a solutuion for tool tip MUCH BETTER than Windows style tooltip.
THANKS AZJIO!!!!
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: (Windows) Mouse Over Gadget TIPS - IMPROVED!!!

Post by Randy Walker »

Randy Walker wrote: Tue Feb 17, 2026 8:09 pm viewtopic.php?p=194837#p194837 <<< (THIS IS THE BEST!!!!)
I battled ChatGPT another full day and we came up with the following code sample. Tested in v5.46 and 6.30. Anyway, here you go:

Code: Select all

EnableExplicit

Global ToolTipHWND
Define event

; ====== Window ======
OpenWindow(0, 0, 0, 400, 200, "Custom Tooltip Test",
           #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

; ====== Gadgets ======
ButtonGadget(1, 40, 60, 140, 30, "Change Tip")
ButtonGadget(2, 220, 60, 140, 30, "Button Two")
ButtonGadget(3, 140, 140, 140, 30, "Button Three")

; ====== Create ONE Tooltip Window ======
ToolTipHWND = CreateWindowEx_(0,
                              "tooltips_class32",
                              0,
                              #TTS_ALWAYSTIP | #TTS_BALLOON,
                              0, 0, 0, 0,
                              WindowID(0),
                              0,
                              GetModuleHandle_(0),
                              0)

SetWindowPos_(ToolTipHWND, #HWND_TOPMOST, 0,0,0,0,
              #SWP_NOMOVE | #SWP_NOSIZE | #SWP_NOACTIVATE)

SendMessage_(ToolTipHWND, #TTM_SETMAXTIPWIDTH, 0, 200)

; ====== Add Tool ======
Procedure AddBalloon(Gadget, Title$, Text$)
  Protected ti.TOOLINFO

  ti\cbSize   = SizeOf(TOOLINFO)
  ti\uFlags   = #TTF_SUBCLASS | #TTF_IDISHWND
  ti\hwnd     = WindowID(0)
  ti\uId      = GadgetID(Gadget)
  ti\hInst    = GetModuleHandle_(0)
  ti\lpszText = @Text$

  SendMessage_(ToolTipHWND, #TTM_ADDTOOL, 0, @ti)
  SendMessage_(ToolTipHWND, #TTM_SETTITLE, 1, @Title$)
EndProcedure

; ====== Update Text ======
Procedure UpdateBalloonText(Gadget, NewText$)
  Protected ti.TOOLINFO

  ti\cbSize   = SizeOf(TOOLINFO)
  ti\uFlags   = #TTF_IDISHWND
  ti\hwnd     = WindowID(0)
  ti\uId      = GadgetID(Gadget)
  ti\lpszText = @NewText$

  SendMessage_(ToolTipHWND, #TTM_UPDATETIPTEXT, 0, @ti)
EndProcedure

; ====== Apply Tooltips ======
AddBalloon(1, "Button One Title", "This is the first button.")
AddBalloon(2, "Button Two Title", "This is the second button.")
AddBalloon(3, "Button Three Title", "This is the Third button.")

; ====== Event Loop ======
Repeat
  event = WaitWindowEvent()

  If event = #PB_Event_Gadget
    Select EventGadget()
      Case 1
      UpdateBalloonText(1, "New Button1 Tip text!")
      Case 2
      UpdateBalloonText(2, "New Button2 Tip text!")
      Case 3
      UpdateBalloonText(3, "New Button3 Tip text!")
    EndSelect
  EndIf

Until event = #PB_Event_CloseWindow
Any ask of CharGPT is going to be a one or two day battle. It is SO stupid,
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
User avatar
minimy
Addict
Addict
Posts: 900
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Re: [REVISED & IMPROVED!!] (Windows) Mouse Over Gadget TIPS

Post by minimy »

Interesting! thanks for share. Tooltip title no change because is global for all tooltips, is allways "Button Three Title". This is a problem with tooltip in windows.
I try any times with GPT but it gets on my nerves, it always adds garbage and most of the time, almost all of them mix several languages or take away parts of code that you already had. :shock:
I try to use it only to replace complex texts in the code or some query and allways expecting the worst. :lol:
If translation=Error: reply="Sorry, Im Spanish": Endif
AZJIO
Addict
Addict
Posts: 2284
Joined: Sun May 14, 2017 1:48 am

Re: [REVISED & IMPROVED!!] (Windows) Mouse Over Gadget TIPS

Post by AZJIO »

This is taken from the Launcher

Code: Select all

EnableExplicit
Global hIcon1, hIcon2, hIcon3
Global TTip
Global TipTime = 4
; Global TipStyle = 0
Global TipStyle = 64
Global TipWidth = 220
TipTime * 1000

Procedure BalloonTip()
	Protected null.w
	Protected TStyle = #TTS_NOPREFIX | #TTS_ALWAYSTIP | #WS_POPUP
	If TipStyle & #TTS_BALLOON
		TStyle | #TTS_BALLOON
	EndIf
	TTip = CreateWindowEx_(#WS_EX_TOPMOST, "tooltips_class32", 0, TStyle, 0, 0, 0, 0, 0, 0, GetModuleHandle_(0), 0)
	SetWindowTheme_(TTip, @null.w, @null.w)
	SendMessage_(TTip, #TTM_SETTIPTEXTCOLOR, GetSysColor_(#COLOR_INFOTEXT), 0)
	SendMessage_(TTip, #TTM_SETTIPBKCOLOR, GetSysColor_(#COLOR_INFOBK), 0)
	SendMessage_(TTip, #TTM_SETMAXTIPWIDTH, 0, TipWidth)
	SendMessage_(TTip, #TTM_SETDELAYTIME, 2, TipTime)
EndProcedure

Procedure BalloonTip2(Gadget, Tip$, Title$ = "", Icon = 0)
	If Asc(Title$)
		BalloonTip()
		SendMessage_(TTip, #TTM_SETTITLE, Icon, @Title$)
	EndIf

	Protected ti.TOOLINFO
	ti\cbSize = SizeOf(ti)
	ti\hInst = GetModuleHandle_(0)
	ti\uFlags = #TTF_IDISHWND | #TTF_SUBCLASS
	ti\hwnd = GadgetID(Gadget)
	ti\uId = GadgetID(Gadget)
	ti\lpszText = @Tip$
	SendMessage_(TTip, #TTM_ADDTOOL, 0, ti)
EndProcedure

If Not TipStyle & 1
	BalloonTip()
EndIf


Define event

; ====== Window ======
OpenWindow(0, 0, 0, 400, 200, "Custom Tooltip Test",
           #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

; ====== Gadgets ======
ButtonGadget(1, 40, 60, 140, 30, "Change Tip")
ButtonGadget(2, 220, 60, 140, 30, "Button Two")
ButtonGadget(3, 140, 140, 140, 30, "Button Three")

; SmallIcon
; ExtractIconEx_("Shell32.dll", 3, 0, @hIcon1, 1)
; ExtractIconEx_("Shell32.dll", 144, 0, @hIcon2, 1)
; ExtractIconEx_("Shell32.dll", 131, 0, @hIcon3, 1)

; LargeIcon
ExtractIconEx_("Shell32.dll", 3, @hIcon1, 0, 1)
ExtractIconEx_("Shell32.dll", 144, @hIcon2, 0, 1)
ExtractIconEx_("Shell32.dll", 131, @hIcon3, 0, 1)

BalloonTip2(1, "Change Tip", "Folder", hIcon1)
BalloonTip2(2, "Button Two", "Check", hIcon2)
BalloonTip2(3, "Button Three", "Close", hIcon3)

; ====== Event Loop ======
Repeat
  event = WaitWindowEvent()

  If event = #PB_Event_Gadget
    Select EventGadget()
      Case 1
      Case 2
      Case 3
    EndSelect
  EndIf

Until event = #PB_Event_CloseWindow

DestroyIcon_(hIcon1)
DestroyIcon_(hIcon2)
DestroyIcon_(hIcon3)
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: [REVISED & IMPROVED!!] (Windows) Mouse Over Gadget TIPS

Post by Randy Walker »

After Another Full Day Battling ChatGPT Stupidity we finally hammered out a more perfect solution that even allows you to change the BallonTip text while leaving the BalloonTip tutle unchanged. And it's done using an Xinclude so it's very versatile. Sample given in two parts of course... the main app and the include file:

MAIN APP; BalloonTEST.pb:

Code: Select all

XIncludeFile "BalloonTips.pbi"

OpenWindow(0, 100, 100, 420, 220, "Balloon Test", #PB_Window_SystemMenu)

ButtonGadget(1, 30, 30, 150, 30, "Button 1")
ButtonGadget(2, 30, 80, 150, 30, "Button 2")
ButtonGadget(3, 30,130, 150, 30, "Button 3")

; Initial titles + text
BalloonTips::Add(1, "Button One Title",   "This is the first button.")
BalloonTips::Add(2, "Button Two Title",   "This is the second button.")
BalloonTips::Add(3, "Button Three Title", "This is the third button.")

Repeat

  event = WaitWindowEvent()

  If event = #PB_Event_Gadget

    Select EventGadget()

      Case 1
        BalloonTips::Update(1, "Button 1 clicked!")

      Case 2
        BalloonTips::Update(2, "Button 2 clicked!")

      Case 3
        BalloonTips::Update(3, "Button 3 clicked!")

    EndSelect

  EndIf

Until event = #PB_Event_CloseWindow
And the Xinclude; BalloonTips.pbi

Code: Select all

DeclareModule BalloonTips
  Declare Add(Gadget, Title$, Text$)
  Declare Update(Gadget, NewText$)
EndDeclareModule

Module BalloonTips

  Structure TipData
    hTooltip.i
    TOOLINFO.TOOLINFO
    Text$
    Title$
  EndStructure

  Global NewMap Tips.TipData()

  Procedure Add(Gadget, Title$, Text$)

    If FindMapElement(Tips(), Str(Gadget))
      ProcedureReturn
    EndIf

    AddMapElement(Tips(), Str(Gadget))

    Protected hGadget = GadgetID(Gadget)
    Protected hParent = GetParent_(hGadget)

    Tips()\Text$  = Text$
    Tips()\Title$ = Title$

    Tips()\hTooltip = CreateWindowEx_(0, "tooltips_class32", "", #TTS_ALWAYSTIP,
                                      0, 0, 0, 0,
                                      hParent, 0, GetModuleHandle_(0), 0)

    SetWindowPos_(Tips()\hTooltip, #HWND_TOPMOST,
                  0, 0, 0, 0,
                  #SWP_NOMOVE | #SWP_NOSIZE | #SWP_NOACTIVATE)

    With Tips()\TOOLINFO
      \cbSize = SizeOf(TOOLINFO)
      \uFlags = #TTF_IDISHWND | #TTF_SUBCLASS
      \hwnd   = hParent
      \uId    = hGadget
      \lpszText = @Tips()\Text$
    EndWith

    SendMessage_(Tips()\hTooltip, #TTM_ADDTOOL, 0, @Tips()\TOOLINFO)
    SendMessage_(Tips()\hTooltip, #TTM_SETTITLE, #TTI_INFO, @Tips()\Title$)

  EndProcedure


  Procedure Update(Gadget, NewText$)

    If FindMapElement(Tips(), Str(Gadget))

      Tips()\Text$ = NewText$

      Tips()\TOOLINFO\lpszText = @Tips()\Text$

      SendMessage_(Tips()\hTooltip,
                   #TTM_UPDATETIPTEXT,
                   0,
                   @Tips()\TOOLINFO)

    EndIf

  EndProcedure

EndModule
This is my first experience creating and using an include file so I was extremely pleased to see it working so well and already added it into my main project. Although it is not so impressive running in v5.46, It looks very good in v6.30, for me at least.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: [SUPERIOR!!] (Windows) Mouse Over Gadget TIPS

Post by Randy Walker »

NEW AND IMPROVED BalloonTips.pbi Xinlcude Compatible with both v5.46 and v6.30 but now the BalloonTip looks same in both versions.

Code: Select all

; ========================================================================
;  BalloonTips2.pbi  (PureBasic 5.46 Stable)
;  Balloon style tooltip
;  Add() sets title + text
;  Update() changes text only
; ========================================================================

#TTS_BALLOON = $40

DeclareModule BalloonTips
  Declare Add(Gadget, Title.s, Text.s)
  Declare Update(Gadget, Text.s)
EndDeclareModule


Module BalloonTips

  Structure TipData
    hTip.i
    Text.s
    Title.s
  EndStructure

  Global NewMap Tips.TipData()

  ; ----------------------------------------------------------------------
  Procedure Add(Gadget, Title.s, Text.s)

    Protected hTip = CreateWindowEx_(0,
                                     "tooltips_class32",
                                     "",
                                     #WS_POPUP | #TTS_BALLOON,
                                     0, 0, 0, 0,
                                     WindowID(GetActiveWindow()),
                                     0,
                                     GetModuleHandle_(0),
                                     0)

    If hTip

      AddMapElement(Tips(), Str(Gadget))
      Tips()\hTip  = hTip
      Tips()\Text  = Text
      Tips()\Title = Title

      Protected ti.TOOLINFO
      ti\cbSize   = SizeOf(TOOLINFO)
      ti\uFlags   = #TTF_IDISHWND | #TTF_SUBCLASS
      ti\hwnd     = WindowID(GetActiveWindow())
      ti\uId      = GadgetID(Gadget)
      ti\lpszText = @Tips()\Text

      SendMessage_(hTip, #TTM_ADDTOOL, 0, @ti)
      SendMessage_(hTip, #TTM_SETTITLE, 1, @Tips()\Title)

    EndIf

  EndProcedure

  ; ----------------------------------------------------------------------
  Procedure Update(Gadget, Text.s)

    If FindMapElement(Tips(), Str(Gadget))

      Tips()\Text = Text

      Protected ti.TOOLINFO
      ti\cbSize   = SizeOf(TOOLINFO)
      ti\uFlags   = #TTF_IDISHWND
      ti\hwnd     = WindowID(GetActiveWindow())
      ti\uId      = GadgetID(Gadget)
      ti\lpszText = @Tips()\Text

      SendMessage_(Tips()\hTip, #TTM_UPDATETIPTEXT, 0, @ti)

    EndIf

  EndProcedure

EndModule
Again compliments of another half day grinding gears with ChatGPT.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: [SUPERIOR!!] (Windows) Mouse Over Gadget BalloonTIips

Post by Randy Walker »

Randy Walker wrote: Tue Feb 17, 2026 12:22 am [EDIT] 02/20/26 More ultimate than any posted here so far. This uses an include file as the engine to create and edit the BalloonTip. See it here: viewtopic.php?p=651836#p651836

[OLD/OBSOLETE EDIT] Go to my next post for more proper solution. This first post just illustrates over thinking the problem.
Kind of embarrassing. :oops:
[OLD/OBSOLETE EDIT] =2/18/26 -- Better yet, go here for an even better solution{ viewtopic.php?p=651787#p651787

I suspect some here have a more sophisticated way to do this but this works for me. I wanted to get tootips by hovering on various gadgets and it may not be pretty but it works:

Code: Select all

EnableExplicit

Define Event
Dim Disc.s(10)  ; Gadget description Array
Enumeration
  #Gad0
  #Gad1
  #Gad2
  #Gad3
  #Gad4
  #Gad5
EndEnumeration
;EXTRA SPACE HERE VVVVVV MOVES TEXT TO RIGHT OFTHE MOUSE POINTER So you can read the text
Disc(#Gad0)  = "`       LISTBOX #0"
Disc(#Gad1) = "`        Button #1"
Disc(#Gad2) = "`        Button #2"
Disc(#Gad3)  = "`       STRING #3"
Disc(#Gad4)  = "`       STRING #4"

OpenWindow(0, 100, 100, 320, 200, "REAL Hover Test")

ListViewGadget(#Gad0,5,5,200,60)
ButtonGadget(#Gad1, 40, 70, 100, 30, "Button 1")
ButtonGadget(#Gad2, 180, 70, 100, 30, "Button 2")
StringGadget(#Gad3,49,110,100,30,"")
StringGadget(#Gad4,49,155,100,30,"")
AddWindowTimer(0, 1, 300)

Global lastID = -1
Global pt.POINT
Global hwnd
Global id

Repeat
    event = WaitWindowEvent()
    Select Event
       Case #PB_Event_Timer 
            GetCursorPos_(pt)  ;<<<< Save energy -- Wait for timer to test mouse position
            hwnd = WindowFromPoint_(PeekQ(@pt)) ; POINT passed as 64-bit
            If hwnd
              id = GetDlgCtrlID_(hwnd) ; Convert Win Handle to gadget ID Number
              Debug GetDlgCtrlID_(hwnd)
            EndIf
             Select id
               Case #Gad0 To #Gad4  ; ONLY acknowledge our gadgets
                 GadgetToolTip(id,Disc(id))
             EndSelect
    EndSelect
Until event = #PB_Event_CloseWindow
After burning up hours with ChatGPT to get a staring point. Maybe this will help some newcomer.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: [SUPERIOR!!] (Windows) Mouse Over Gadget BalloonTips

Post by Randy Walker »

Randy Walker wrote: Tue Feb 17, 2026 12:22 am [EDIT] 02/20/26 More ultimate than any posted here so far. This uses an include file as the engine to create and edit the BalloonTip. See it here: viewtopic.php?p=651836#p651836

[OLD/OBSOLETE EDIT] Go to my next post for more proper solution. This first post just illustrates over thinking the problem.
Kind of embarrassing. :oops:
[OLD/OBSOLETE EDIT] =2/18/26 -- Better yet, go here for an even better solution{ viewtopic.php?p=651787#p651787

I suspect some here have a more sophisticated way to do this but this works for me. I wanted to get tootips by hovering on various gadgets and it may not be pretty but it works:

Code: Select all

EnableExplicit

Define Event
Dim Disc.s(10)  ; Gadget description Array
Enumeration
  #Gad0
  #Gad1
  #Gad2
  #Gad3
  #Gad4
  #Gad5
EndEnumeration
;EXTRA SPACE HERE VVVVVV MOVES TEXT TO RIGHT OFTHE MOUSE POINTER So you can read the text
Disc(#Gad0)  = "`       LISTBOX #0"
Disc(#Gad1) = "`        Button #1"
Disc(#Gad2) = "`        Button #2"
Disc(#Gad3)  = "`       STRING #3"
Disc(#Gad4)  = "`       STRING #4"

OpenWindow(0, 100, 100, 320, 200, "REAL Hover Test")

ListViewGadget(#Gad0,5,5,200,60)
ButtonGadget(#Gad1, 40, 70, 100, 30, "Button 1")
ButtonGadget(#Gad2, 180, 70, 100, 30, "Button 2")
StringGadget(#Gad3,49,110,100,30,"")
StringGadget(#Gad4,49,155,100,30,"")
AddWindowTimer(0, 1, 300)

Global lastID = -1
Global pt.POINT
Global hwnd
Global id

Repeat
    event = WaitWindowEvent()
    Select Event
       Case #PB_Event_Timer 
            GetCursorPos_(pt)  ;<<<< Save energy -- Wait for timer to test mouse position
            hwnd = WindowFromPoint_(PeekQ(@pt)) ; POINT passed as 64-bit
            If hwnd
              id = GetDlgCtrlID_(hwnd) ; Convert Win Handle to gadget ID Number
              Debug GetDlgCtrlID_(hwnd)
            EndIf
             Select id
               Case #Gad0 To #Gad4  ; ONLY acknowledge our gadgets
                 GadgetToolTip(id,Disc(id))
             EndSelect
    EndSelect
Until event = #PB_Event_CloseWindow
After burning up hours with ChatGPT to get a staring point. Maybe this will help some newcomer.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: [TRULY THE BEST!!] (Windows) Mouse Over Gadget BalloonTips

Post by Randy Walker »

Seems the Windows Tooltip function has to be tied to the window in which it will appear and gives very little control to the user how it will behave. After yet another huge battle with ChatGPT we finally came up with a more versatile Xinclude solution that allows the user to specify the Window in which it will apprear. The syntax for calls made to procedures in the Xinclude now requires the window number be alpplied as the first parameter.
;Create balloonTip

[EDIT] 02/21/26 -- THANKS to boddhi, we can now control duration balloonTip will be visible while pointer remains on the gadget.
BalloonTips::Add(#window,#gadget,Title$,buttonText$) ;Placed at bottom of window creation.

;FOR TEXT UPDATE:
BalloonTips::Update(#window,#gadget,buttonText$) ; Placed as needed in the main loop

Here are the revised samples:
MAIN BalloonTEST.pb file with buttons:

Code: Select all

XIncludeFile "BalloonTips.pbi"

OpenWindow(0, 100, 100, 420, 220, "Balloon Test", #PB_Window_SystemMenu)

ButtonGadget(1, 30, 30, 150, 30, "Button 1")
ButtonGadget(2, 30, 80, 150, 30, "Button 2")
ButtonGadget(3, 30,130, 150, 30, "Button 3")

; Initial titles + text
BalloonTips::Add(0,1, "Button One Title",   "This is the first button.")
BalloonTips::Add(0,2, "Button Two Title",   "This is the second button.")
BalloonTips::Add(0,3, "Button Three Title", "This is the third button.")

Repeat

  event = WaitWindowEvent()

  If event = #PB_Event_Gadget

    Select EventGadget()

      Case 1
        BalloonTips::Update(0,1, "Button 1 clicked!")

      Case 2
        BalloonTips::Update(0,2, "Button 2 clicked!")

      Case 3
        BalloonTips::Update(0,3, "Button 3 clicked!")

    EndSelect

  EndIf

Until event = #PB_Event_CloseWindow
And the BalloonTips.pbi Xinclude file That must be in the same folder as the Main file posted above:

Code: Select all

; ========================================================================
;  BalloonTips.pbi
;  PureBasic 5.46 + 6.x compatible
;  Multi-window safe (explicit window parameter)
; ========================================================================

#TTS_BALLOON = $40

DeclareModule BalloonTips
  Declare Add(Window, Gadget, Title.s, Text.s)
  Declare Update(Window, Gadget, Text.s)
EndDeclareModule


Module BalloonTips

  Structure TipData
    hTip.i
    Text.s
    Title.s
  EndStructure

  Global NewMap Tips.TipData()

  ; ------------------------------------------------------------------
  Procedure Add(Window, Gadget, Title.s, Text.s)

    If IsWindow(Window) = 0 Or IsGadget(Gadget) = 0
      ProcedureReturn
    EndIf

    Protected hTip = CreateWindowEx_(0,
                                     "tooltips_class32",
                                     "",
                                     #WS_POPUP | #TTS_BALLOON,
                                     0, 0, 0, 0,
                                     WindowID(Window),
                                     0,
                                     GetModuleHandle_(0),
                                     0)

    If hTip = 0
      ProcedureReturn
    EndIf

    AddMapElement(Tips(), Str(Gadget))
    Tips()\hTip  = hTip
    Tips()\Text  = Text
    Tips()\Title = Title

    Protected ti.TOOLINFO
    ti\cbSize   = SizeOf(TOOLINFO)
    ti\uFlags   = #TTF_IDISHWND | #TTF_SUBCLASS
    ti\hwnd     = WindowID(Window)
    ti\uId      = GadgetID(Gadget)
    ti\lpszText = @Tips()\Text

    SendMessage_(hTip, #TTM_ADDTOOL, 0, @ti)
    SendMessage_(hTip, #TTM_SETTITLE, 1, @Tips()\Title)
    SendMessage_(hTip, #TTM_SETDELAYTIME,#TTDT_AUTOPOP, 4500) ;Delay for time while on gadget

  EndProcedure


  ; ------------------------------------------------------------------
  Procedure Update(Window, Gadget, Text.s)

    If FindMapElement(Tips(), Str(Gadget)) = 0
      ProcedureReturn
    EndIf

    Tips()\Text = Text

    Protected ti.TOOLINFO
    ti\cbSize   = SizeOf(TOOLINFO)
    ti\uFlags   = #TTF_IDISHWND
    ti\hwnd     = WindowID(Window)
    ti\uId      = GadgetID(Gadget)
    ti\lpszText = @Tips()\Text

    SendMessage_(Tips()\hTip, #TTM_UPDATETIPTEXT, 0, @ti)

  EndProcedure

EndModule
TESTED on Windows 11 Pro with PureBasic v5.46 and v 6.30
Last edited by Randy Walker on Sat Feb 21, 2026 8:00 pm, edited 3 times in total.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
boddhi
Enthusiast
Enthusiast
Posts: 532
Joined: Mon Nov 15, 2010 9:53 pm

Re: [SUPERIOR!!] (Windows) Mouse Over Gadget BalloonTips

Post by boddhi »

Hello,

You can also use TTM_SETDELAYTIME message to set various display times for the tooltip :wink:
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
Randy Walker
Addict
Addict
Posts: 1279
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA
Contact:

Re: [SUPERIOR!!] (Windows) Mouse Over Gadget BalloonTips

Post by Randy Walker »

boddhi wrote: Sat Feb 21, 2026 11:43 am Hello,

You can also use TTM_SETDELAYTIME message to set various display times for the tooltip :wink:
That's very good to know. No idea that control was available. Thanks boddhi!!
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Nothing is faster, more stable, or easier to maintain than code that doesn’t exist. :mrgreen:
Little_man
Enthusiast
Enthusiast
Posts: 160
Joined: Fri Mar 29, 2013 4:55 pm
Location: The Netherland

Re: [SUPERIOR!!] (Windows) Mouse Over Gadget BalloonTips

Post by Little_man »

Is it possible to scale “Tooltip”:

I scaled an “OpenWindow”, after scaling I get the values “ScaleX” and “ScaleY”
(I would like to use several “Tooltips” on the “Openwindow”.)

I would like to scale the “Tooltips” in size and the “Font Height” and be visible for maximum time,
change the fontstyle of the Tooltip to Italic or Normal when running the program.

Little_man
Post Reply