Page 1 of 2

GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 9:42 am
by marcoagpinto
Heya,

I have a big tooltip for a few gadgets, but on Windows 11 the whole text appears in one line (hard to see), so I decided to place each sentence before a period (followed by a space) in a different paragraph.

This is how I did it:

Code: Select all

  If MARCOAGPINTO_tooltip$<>""
    MARCOAGPINTO_tooltip$=ReplaceString(MARCOAGPINTO_tooltip$,". ","."+#LF$+#LF$)
    GadgetToolTip(MARCOAGPINTO_gadget_target,MARCOAGPINTO_tooltip$)
  EndIf
But after a #LF$ no more text is displayed.

What is wrong?

Thanks!

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 10:06 am
by firace
Hi, netmaestro's solution (2011) works for me:

Code: Select all

Procedure TT_CBTHookProc(nCode, wParam, lParam) 
  Shared _Hook, TT_HWND
  Select nCode 
    Case #HCBT_CREATEWND 
      *pcbt.CBT_CREATEWND = lParam 
      *pcs.CREATESTRUCT = *pcbt\lpcs 
      Select PeekS(*pcs\lpszClass)
        Case "tooltips_class32"
          TT_HWND = wParam
      EndSelect
  EndSelect
  ProcedureReturn CallNextHookEx_(_Hook, nCode, wParam, lParam) 
EndProcedure

Procedure GadgetToolTipEx(gadget_number, tooltip_text$)
  Shared _Hook, TT_HWND
  _Hook = SetWindowsHookEx_(#WH_CBT, @TT_CBTHookProc(), #Null, GetCurrentThreadId_()) 
  GadgetToolTip(gadget_number, tooltip_text$)
  UnhookWindowsHookEx_(_Hook)
  ProcedureReturn TT_HWND
EndProcedure

OpenWindow(0,0,0,320,240,"")
StringGadget(1,20,40,200,20,"stuff")
ttid = GadgetToolTipEx(1, "This is a tooltip        with multiple lines  ")
SendMessage_(ttid, #TTM_SETMAXTIPWIDTH, 0, 100)
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow


Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 10:33 am
by marcoagpinto
firace wrote: Wed Nov 08, 2023 10:06 am Hi, netmaestro's solution (2011) works for me:

Code: Select all

Procedure TT_CBTHookProc(nCode, wParam, lParam) 
  Shared _Hook, TT_HWND
  Select nCode 
    Case #HCBT_CREATEWND 
      *pcbt.CBT_CREATEWND = lParam 
      *pcs.CREATESTRUCT = *pcbt\lpcs 
      Select PeekS(*pcs\lpszClass)
        Case "tooltips_class32"
          TT_HWND = wParam
      EndSelect
  EndSelect
  ProcedureReturn CallNextHookEx_(_Hook, nCode, wParam, lParam) 
EndProcedure

Procedure GadgetToolTipEx(gadget_number, tooltip_text$)
  Shared _Hook, TT_HWND
  _Hook = SetWindowsHookEx_(#WH_CBT, @TT_CBTHookProc(), #Null, GetCurrentThreadId_()) 
  GadgetToolTip(gadget_number, tooltip_text$)
  UnhookWindowsHookEx_(_Hook)
  ProcedureReturn TT_HWND
EndProcedure

OpenWindow(0,0,0,320,240,"")
StringGadget(1,20,40,200,20,"stuff")
ttid = GadgetToolTipEx(1, "This is a tooltip        with multiple lines  ")
SendMessage_(ttid, #TTM_SETMAXTIPWIDTH, 0, 100)
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow

Buaaaaaaaaaaaaaaa... that is using the APIs, and it won't work on all platforms :cry: :cry: :cry: :cry:

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 10:34 am
by marcoagpinto
Why can't these basic things be handled by PureBasic instead of using APIs?

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 12:20 pm
by firace
marcoagpinto wrote: Wed Nov 08, 2023 10:34 am Why can't these basic things be handled by PureBasic instead of using APIs?
Due to OS constraints, I believe.
Did you check if multiline already works with a standard Gadgettooltip on Linux/Mac? Perhaps it does!

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 12:55 pm
by marcoagpinto
firace wrote: Wed Nov 08, 2023 12:20 pm
marcoagpinto wrote: Wed Nov 08, 2023 10:34 am Why can't these basic things be handled by PureBasic instead of using APIs?
Due to OS constraints, I believe.
Did you check if multiline already works with a standard Gadgettooltip on Linux/Mac? Perhaps it does!
Even HandBrake has been using multiline tooltips for decades:
Image

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 1:22 pm
by Kuron
marcoagpinto wrote: Wed Nov 08, 2023 12:55 pm Even HandBrake has been using multiline tooltips for decades:
And Windows has provided for owner-drawn tooltips for decades. HandBrake uses .NET 6.X and uses Windows Forms and not Common Controls (at least not directly).

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 1:28 pm
by BarryG
marcoagpinto wrote: Wed Nov 08, 2023 12:55 pmEven HandBrake has been using multiline tooltips for decades
That's not a multi-line tooltip; that's a custom window.

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 1:36 pm
by marcoagpinto
BarryG wrote: Wed Nov 08, 2023 1:28 pm
marcoagpinto wrote: Wed Nov 08, 2023 12:55 pmEven HandBrake has been using multiline tooltips for decades
That's not a multi-line tooltip; that's a custom window.
But it appears when I hover the mouse over the track bar, and as I move the mouse, the tooltip moves along.

Re: GadgetTooltip, using lines instead of single line

Posted: Wed Nov 08, 2023 2:04 pm
by Mijikai
Example:

Code: Select all

EnableExplicit

;Basic ToolTip nonsense... template thing

Structure TOOLTIP_STRUCT
  window.i
  List gadget.i()
EndStructure

Global tt.TOOLTIP_STRUCT

Procedure.i ttCreate(Window.i)
  With tt
    If IsWindow(Window)
      If Not \window
        \window = OpenWindow(#PB_Any,#Null,#Null,320,200,#Null$,#PB_Window_Invisible|#PB_Window_BorderLess,Window)
        If \window
          SetWindowColor(\window,#Red)
        EndIf
      EndIf
    EndIf
    ProcedureReturn Bool(\window <> #Null)
  EndWith
EndProcedure

Procedure.i ttAdd(Gadget.i)
  With tt
    If IsGadget(Gadget)
      If AddElement(\gadget())
        \gadget() = Gadget
        ProcedureReturn #True
      EndIf
    EndIf
    ProcedureReturn #False
  EndWith
EndProcedure

Procedure.i ttEvent(Window.i)
  Protected.i x,y,gx,gy,gw,gh,gf
  With tt
    x = WindowMouseX(Window)
    y = WindowMouseY(Window)
    ForEach \gadget()
      gx = GadgetX(\gadget())
      gy = GadgetY(\gadget())
      gw = gx + GadgetWidth(\gadget())
      gh = gx + GadgetHeight(\gadget())
      If x >= gx And y >= gy And x < gw And y < gh
        gf = #True
        Break
      EndIf
    Next
    If gf
      x + WindowX(Window,#PB_Window_InnerCoordinate)
      y + WindowY(Window,#PB_Window_InnerCoordinate)
      ResizeWindow(\window,x,y,#PB_Ignore,#PB_Ignore)
      HideWindow(\window,#False) 
    Else
      HideWindow(\window,#True)
    EndIf
    ProcedureReturn #Null
  EndWith
EndProcedure

Procedure.i Main()
  If OpenWindow(0,0,0,800,600,"Dummy",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    ButtonGadget(1,10,10,200,30,"Hello World!")
    ttCreate(0)
    ttAdd(1)
    Repeat
    ttEvent(0)
    Until WaitWindowEvent() = #PB_Event_CloseWindow
    CloseWindow(0)  
  EndIf
  ProcedureReturn #Null
EndProcedure

End Main()

Re: GadgetTooltip, using lines instead of single line

Posted: Thu Nov 09, 2023 1:25 am
by BarryG
marcoagpinto wrote: Wed Nov 08, 2023 1:36 pmBut it appears when I hover the mouse over the track bar, and as I move the mouse, the tooltip moves along.
It's easy to code a custom borderless window to follow the mouse, as Mijikai just showed.

Re: GadgetTooltip, using lines instead of single line

Posted: Thu Nov 09, 2023 6:14 am
by marcoagpinto
What about this in Windows 11, is it a floating window or a real tooltip?

I am still not convinced, sorry.

Image

Re: GadgetTooltip, using lines instead of single line

Posted: Thu Nov 09, 2023 4:44 pm
by Kuron
marcoagpinto wrote: Thu Nov 09, 2023 6:14 am What about this in Windows 11, is it a floating window or a real tooltip?

I am still not convinced, sorry.
You are showing a picture of a notification.

Re: GadgetTooltip, using lines instead of single line

Posted: Thu Nov 09, 2023 6:03 pm
by Mijikai
Example with WinApi - Multiline Tooltip:

Code: Select all

EnableExplicit

Procedure.i ToolTip(Gadget.i,Text.s)
  Protected hwnd.i
  Protected ti.TOOLINFO
  If IsGadget(Gadget)
    ti\cbSize = SizeOf(TOOLINFO)
    ti\uFlags = #TTF_SUBCLASS
    ti\hWnd = GadgetID(Gadget)
    ti\hInst = GetModuleHandle_(#Null)
    ti\lpszText = SysAllocString_(Text) 
    ti\rect\left = GadgetX(Gadget)
    ti\rect\top = GadgetY(Gadget)
    ti\rect\right = ti\rect\left + GadgetWidth(Gadget)
    ti\rect\bottom = ti\rect\top + GadgetHeight(Gadget)
    hwnd = CreateWindowEx_(#Null,#TOOLTIPS_CLASS,#Null,
                                   #WS_POPUP|#TTS_ALWAYSTIP,
                                   #CW_USEDEFAULT,#CW_USEDEFAULT,#CW_USEDEFAULT,
                                   #CW_USEDEFAULT,ti\hWnd,#Null,ti\hInst,#Null)
    If hwnd
      SendMessage_(hwnd,#TTM_ADDTOOL,#Null,@ti)
      SendMessage_(hwnd,#TTM_SETMAXTIPWIDTH,#Null,150)
      ProcedureReturn #True
    EndIf
    If ti\lpszText
      SysFreeString_(ti\lpszText)
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.i Main()
  If OpenWindow(0,0,0,800,600,"Dummy",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    ButtonGadget(1,10,10,200,30,"Hello World!")
    ToolTip(1,"Hello World!" + #CR$ + "How does this magic work?" + #CR$ + "Black Magic!!!!")
    Repeat
    Until WaitWindowEvent() = #PB_Event_CloseWindow
    CloseWindow(0)  
  EndIf
  ProcedureReturn #Null
EndProcedure

End Main()

Re: GadgetTooltip, using lines instead of single line

Posted: Thu Nov 09, 2023 6:29 pm
by RASHAD
For Windows using PG GadgetToolTip()

Code: Select all

Structure PB_Globals
  CurrentWindow.i
  FirstOptionGadget.i
  DefaultFont.i
  *PanelStack
  PanelStackIndex.l
  PanelStackSize.l
  ToolTipWindow.i
EndStructure

Import ""
  PB_Object_GetThreadMemory(*Mem)
  PB_Gadget_Globals
EndImport

Procedure ToolTipHandle()
  Protected *PB_G.PB_Globals
  *PB_G = PB_Object_GetThreadMemory(PB_Gadget_Globals)
  ProcedureReturn *PB_G\ToolTipWindow
EndProcedure

If OpenWindow(0, 0, 0, 300, 100, "GadgetTooltip", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(0, 10, 10, 250, 30, "Button with Tooltip") 
  GadgetToolTip(0, "Tooltip for Button and Now with More Lines")
  
  ButtonGadget(1, 10, 50, 250, 30, "Button with Tooltip") 
  GadgetToolTip(1, "Button #2 Tooltip and Now with More Lines")
  
  ttip = ToolTipHandle() 
  SetWindowLongPtr_(ttip, #GWL_STYLE, GetWindowLongPtr_(ttip, #GWL_STYLE) | #TTS_ALWAYSTIP| #TTS_NOPREFIX| #WS_POPUP)
  
  SendMessage_(ttip,#TTM_SETMAXTIPWIDTH,0,150)
  LoadFont(0, "Tahoma",12,#PB_Font_HighQuality)
  SendMessage_(ttip,#WM_SETFONT,FontID(0),0)
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf