Page 1 of 1

GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 2:36 pm
by GG
Is it possible to have GadgetToolTip to print several lines ?

Code: Select all

  GadgetToolTip(x,"Why are multiple"+#CR$+"lines NOT possible???")
For me, carriage return is considered as a blank square when tooltip appears.

Is there a way to bypass this problem ?

Re: GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 3:05 pm
by falsam
Here's an old code (2004) written by Sparks and Andre.It is rewritten (1) for version 4.51 of Pure basic.
http://forum.purebasic.com/english/viewtopic.php?p=83963

(1) je ne sais pas comment dire en anglais "adapté pour la version ...." :oops:

Code: Select all

; Multiline Tooltips - method 1: only supporting one-line string as parameter, 
; it will be splitted automatically if the 'maxW'idth is reached.
Enumeration 
  #Menu_Main 
EndEnumeration 

Enumeration 
  #Menu_Remove_Button_TT 
  #Menu_Remove_String_TT 
  #Menu_Change_Button_TT 
  #Menu_Change_String_TT 
EndEnumeration 

Enumeration 
  #Button_0 
  #String_0 
EndEnumeration 

Procedure.l AddTooltip(Gadget, Tooltext$, maxW) 
  ;--> Remove the #TTS_BALLOON flag in the next line if you want the rectangular Tooltip
  hToolTip = CreateWindowEx_(0, "ToolTips_Class32", "", #TTS_NOPREFIX | #TTS_BALLOON, 0, 0, 0, 0, 0, 0, GetModuleHandle_(0), 0) 
  SendMessage_(hToolTip, #TTM_SETTIPTEXTCOLOR, GetSysColor_(#COLOR_INFOTEXT), 0) 
  SendMessage_(hToolTip, #TTM_SETTIPBKCOLOR, GetSysColor_(#COLOR_INFOBK), 0) 
  ttAdd.TOOLINFO\cbSize = SizeOf(TOOLINFO) 
  ttAdd\uFlags = #TTF_SUBCLASS | #TTF_IDISHWND 
  ;--> Here's where the multiline comes into play by setting the maxWidth 
  SendMessage_(hToolTip, #TTM_SETMAXTIPWIDTH, 0, maxW) 
  ttAdd\hWnd = WindowID(0)
  ttAdd\uId = GadgetID(Gadget) 
  ttAdd\hinst = 0 
  ttAdd\lpszText = @Tooltext$ 
  SendMessage_(hToolTip, #TTM_ADDTOOL, 0, ttAdd) 
  SendMessage_(hToolTip, #TTM_SETDELAYTIME, #TTDT_AUTOPOP, 15000) 
  SendMessage_(hToolTip, #TTM_UPDATE , 0, 0) 
  ProcedureReturn hToolTip
EndProcedure 

Procedure.l RemoveToolTip(hTT.l, Gadget.l) 
  ttRemove.TOOLINFO\cbSize = SizeOf(TOOLINFO) 
  ttRemove\hWnd = WindowID(0) 
  ttRemove\uId = GadgetID(Gadget) 
  SendMessage_(hTT, #TTM_DELTOOL, 0, ttRemove) 
EndProcedure 

Procedure.l ChangeToolTip(hTT.l, Gadget.l, Tooltext$) 
  ttChange.TOOLINFO\cbSize = SizeOf(TOOLINFO) 
  ttChange\hWnd = WindowID(0) 
  ttChange\uId = GadgetID(Gadget) 
  ttChange\lpszText = @Tooltext$
  SendMessage_(hTT, #TTM_UPDATETIPTEXT, 0, ttChange) 
EndProcedure 


If OpenWindow(0, 0, 0, 270, 110, "Multiline Gadget Tooltip", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ; Menu creation
  CreateMenu(#Menu_Main, WindowID(0)) 
  MenuTitle("ToolTip Remove") 
  MenuItem(#Menu_Remove_Button_TT, "Remove Button ToolTip") 
  MenuItem(#Menu_Remove_String_TT, "Remove String ToolTip") 
  MenuTitle("ToolTip Text") 
  MenuItem(#Menu_Change_Button_TT, "Change Button ToolTip") 
  MenuItem(#Menu_Change_String_TT, "Change String ToolTip") 

  ; Gadget creation, the return values of AddToolTip() is needed to change/remove them later
  ButtonGadget(#Button_0, 10, 10, 250, 20, "ButtonGadget with Tooltip") 
  hButtonTT.l = AddTooltip(#Button_0, "This is a multiline Tooltip for the ButtonGadget", 200) 
  StringGadget(#String_0, 10, 60, 250, 20, "StringGadget with Tooltip") 
  hStringTT.l = AddTooltip(#String_0, "This is a multiline Tooltip for the StringGadget", 200) 

  quit = #False 
  Repeat 
    event = WaitWindowEvent() 
    Select event 
      Case #PB_Event_Menu 
        Select EventMenu() 
          Case #Menu_Change_Button_TT 
            ChangeToolTip(hButtonTT, #Button_0, InputRequester("Change Button ToolTip Text", "Enter new text.", ""))
            
          Case #Menu_Change_String_TT 
            ChangeToolTip(hStringTT, #String_0, InputRequester("Change String ToolTip Text", "Enter new text.", ""))

          Case #Menu_Remove_Button_TT 
            ;--> Remove the ButtonGadget Tooltip 
            RemoveToolTip(hButtonTT, #Button_0) 
            ;--> Disable menu items for ButtonGadget ToolTip 
            DisableMenuItem(#Menu_Remove_Button_TT, 1, #True) 
            DisableMenuItem(#Menu_Change_Button_TT, 1, #True) 

          Case #Menu_Remove_String_TT 
            ;--> Remove the StringGadget Tooltip 
            RemoveToolTip(hStringTT, #String_0) 
            ;--> Disable menu items for StringGadget ToolTip 
            DisableMenuItem(#Menu_Remove_String_TT, 1, #True) 
            DisableMenuItem(#Menu_Change_String_TT, 1, #True) 

        EndSelect 
      Case #PB_Event_CloseWindow 
        quit = #True 
    EndSelect 
  Until quit = #True 
EndIf 
End

Re: GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 3:09 pm
by netmaestro
You can easily cause the tooltip to wordwrap by sending the #TTM_SETMAXTIPWIDTH message. However, in order to do that you need to get the handle of the tooltip Purebasic created for you:

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 usable with multiple lines ?

Posted: Tue Oct 18, 2011 4:24 pm
by GG
Thanks netmaestro, that's perfect. :)

Re: GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 4:37 pm
by gnozal
Also possible :

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 ToolTipID() 
  Protected *PB_Globals.PB_Globals 
  *PB_Globals = PB_Object_GetThreadMemory(PB_Gadget_Globals) 
  ProcedureReturn *PB_Globals\ToolTipWindow 
EndProcedure

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

Re: GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 5:06 pm
by WilliamL

Code: Select all

GadgetToolTip(x,"Why are multiple"+#CR$+"lines NOT possible???")
Works for me! (on Mac) Maybe you need a line feed?

Code: Select all

GadgetToolTip(gethefid(MFile,47),"Month spent/"+Chr(13)+"Posted balance/"+Chr(13)+"Total balance")

Re: GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 5:35 pm
by GG
Doesn't work for me under XP : chr(13) is considered as a blank square in the tooltip.
netmaesto and gnozal's snippets solve my problems. :)

Re: GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 5:42 pm
by WilliamL
I was suggesting using (for the linefeed)

Code: Select all

#CRLF$
but maybe it just doesn't work on your version.

Re: GadgetToolTip usable with multiple lines ?

Posted: Tue Oct 18, 2011 7:20 pm
by blueznl
Under Windows I think a CHR(10) is used for linefeeds, but I could be wrong :-)

Re: GadgetToolTip usable with multiple lines ?

Posted: Wed Oct 19, 2011 9:01 am
by GG
Absolutely, but same result. :(
Both solutions (netmaestro and gnozal) are very interesting.

Re: GadgetToolTip usable with multiple lines ?

Posted: Wed Oct 19, 2011 10:43 am
by Shardik
For a Windows solution using #CR$ as a ToolTip linefeed take a look into
a previous code example from me that utilizes netmaestro's ToolTipID()
code:
http://www.purebasic.fr/english/viewtop ... 0&start=11

Re: GadgetToolTip usable with multiple lines ?

Posted: Wed Oct 19, 2011 11:44 am
by RASHAD
Hi

Code: Select all

;#TTS_BUBBLE = $40

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, 270, 100, "GadgetTooltip", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(0, 10, 30, 250, 30, "Button with Tooltip")
  
  GadgetToolTip(0, "Tooltip for "+#CR$+"Button And Now With More Lines for GG")
  ttip = ToolTipHandle()
 
  SetWindowLongPtr_(ttip, #GWL_STYLE, GetWindowLongPtr_(ttip, #GWL_STYLE) | #TTS_ALWAYSTIP| #TTS_NOPREFIX| #WS_POPUP| #TTS_BALLOON)    ;#TTS_BUBBLE
  SetWindowTheme_(ttip, @null.w, @null.w)

  SendMessage_(ttip,#TTM_SETDELAYTIME,#TTDT_INITIAL,0)
  SendMessage_(ttip,#TTM_SETTIPTEXTCOLOR,$0002FF,0)                  ;TextColor Tooltip 
  SendMessage_(ttip,#TTM_SETTIPBKCOLOR,$D1FFFF,0)                    ;BackColor Tooltip
  SendMessage_(ttip,#TTM_SETMAXTIPWIDTH,0,100)                       ;Max tip width  
  ;SetRect_(r.RECT,5,5,5,5)                                          ;Tip Margins
  ;SendMessage_(ttip,#TTM_SETMARGIN,0,r)
  LoadFont(0, "Tahoma",10,#PB_Font_HighQuality) 
  SendMessage_(ttip,#WM_SETFONT,FontID(0),0)   
  ;SendMessage_(ttip,#TTM_ACTIVATE,#False,0)                         ;DeActivate  
  ;SendMessage_(ttip,#TTM_ACTIVATE,#True,0)                          ;Activate
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf