Page 1 of 1

ListView: Tooltip if text is too long for the list

Posted: Mon Jun 09, 2008 4:12 pm
by c4s

Code: Select all

#Window = 1
#ListIcon = 2
#Text = 3
#ListView = 4
#LVS_EX_LABELTIP = $4000


If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 200, 420, "ListView Tooltip", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(#Window))
   ListIconGadget(#ListIcon, 0, 0, 200, 200, "ListIconGadget:", 200)
    SendMessage_(GadgetID(#ListIcon), #LVM_SETEXTENDEDLISTVIEWSTYLE, 0, #LVS_EX_LABELTIP)
   TextGadget(#Text, 0, 200, 200, 20, "'ListViewGadget':")
   ListIconGadget(#ListView, 0, 220, 200, 200, "", 170, #LVS_NOCOLUMNHEADER)
    SendMessage_(GadgetID(#ListView), #LVM_SETEXTENDEDLISTVIEWSTYLE, 0, #LVS_EX_LABELTIP)
EndIf

For i = 1 To 100
   Text.s = RSet("", i, Chr(Random(95) + 32))
   AddGadgetItem(#ListIcon, -1, Text)
   AddGadgetItem(#ListView, -1, Text)
Next i

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow: End
This doesn't work on a classic ListViewGadget. But we can easily build our
own with a ListIconGadget (see the example).

Hopefully someone finds it as usefull as I did...
c4s

P.S.
I think this should be available in PB with a flag option..!
That's also a reason why I post it here too (already did in the german forum ;))

Re: ListView: Tooltip if text is too long for the list

Posted: Mon Jun 09, 2008 10:24 pm
by UserOfPure
c4s wrote:I think this should be available in PB with a flag option..!
If the ListIconGadget has more than one column then it makes it impossible to use #PB_ListIcon_FullRowSelect to highlight the whole row. That's probably why it's not supported.

Code: Select all

#Window = 1
#ListIcon = 2
#Text = 3
#ListView = 4
#LVS_EX_LABELTIP = $4000

If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 200, 420, "ListView Tooltip", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(#Window))

   ListIconGadget(#ListIcon, 0, 0, 200, 200, "ListIconGadget:", 200, #PB_ListIcon_FullRowSelect)
    AddGadgetColumn(#ListIcon, 1, "Second column", 100)
    SendMessage_(GadgetID(#ListIcon),#LVM_SETEXTENDEDLISTVIEWSTYLE,0,#LVS_EX_LABELTIP)
    TextGadget(#Text, 0, 200, 200, 20, "'ListViewGadget':")

   ListIconGadget(#ListView, 0, 220, 200, 200, "", 170)
    SendMessage_(GadgetID(#ListView),#LVM_SETEXTENDEDLISTVIEWSTYLE,0,#LVS_EX_LABELTIP)

EndIf

For i = 1 To 100
   Text.s = RSet("", i, Chr(Random(95) + 32))
   AddGadgetItem(#ListIcon, -1, Text + #LF$ + Text)
   AddGadgetItem(#ListView, -1, Text + #LF$ + Text)
Next i

SetActiveGadget(#ListIcon)

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow: End

Posted: Mon Jun 30, 2008 11:59 am
by Michael Vogel
Does anyone know if there is a similar 'trick' for comboboxes?

Code: Select all

Code:
#Window = 1
#ListIcon = 2
#Text = 3
#ListView = 4
#LVS_EX_LABELTIP = $4000


If OpenWindow(#Window,#PB_Ignore,#PB_Ignore,200,420,"ListView Tooltip",#PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(#Window))
	ComboBoxGadget(#ListIcon,0,0,200,200,200)
	SendMessage_(GadgetID(#ListIcon), #LVM_SETEXTENDEDLISTVIEWSTYLE, 0, #LVS_EX_LABELTIP)
	TextGadget(#Text, 0, 200, 200, 20, "'ListViewGadget':")
	ListIconGadget(#ListView, 0, 220, 200, 200, "", 170, #LVS_NOCOLUMNHEADER)
	SendMessage_(GadgetID(#ListView), #LVM_SETEXTENDEDLISTVIEWSTYLE, 0, #LVS_EX_LABELTIP)
EndIf

For i = 1 To 100
	Text.s = RSet("", i, Chr(Random(95) + 32))
	AddGadgetItem(#ListIcon, -1, Text)
	AddGadgetItem(#ListView, -1, Text)
Next i

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow: End

Posted: Fri Jul 18, 2008 10:30 pm
by Michael Vogel
Just trying to refresh the former question, maybe it has been missed:

does anyone know if it is possible to get automatic info lines for long text entries of comboboxes (see example code in previous posting)?

Thank you for your lenity,
Michael

Posted: Sat Jul 26, 2008 2:16 pm
by waldschrath
I dont think it is possible with just a Flag. You have to handle the Tooltips yourself.

Posted: Sun Jul 27, 2008 8:30 pm
by waldschrath
Since my last Comment was probably not very helpful, I should probably add some sample Code to show what I mean.

Code: Select all

#TTF_TRACK = $20
#TTF_TRANSPARENT = $100

#SM_CXTHUMB = 10

#LB_ITEMFROMPOINT = $01A9


Structure CBINFOTIPINFO
  TipHandle.l
  ListboxHandle.l
  TipInfo.TOOLINFO
  CurrentItem.l
  TipTextLength.l
  *TipText
  *PrevWinProc
EndStructure


Procedure.l ComboBoxInfoTipInitTip ( WindowHandle.l, *Info.CBINFOTIPINFO )

  *Info\TipHandle = CreateWindowEx_(#WS_EX_TOPMOST, @"tooltips_class32", 0, #TTS_NOPREFIX + #TTS_ALWAYSTIP, #CW_USEDEFAULT, #CW_USEDEFAULT, #CW_USEDEFAULT,  #CW_USEDEFAULT, WindowHandle, 0, 0, 0)
  If #Null = *Info\TipHandle
    FreeMemory(*Info)
    ProcedureReturn #False
  EndIf
  
  *Info\TipInfo\cbSize = SizeOf(TOOLINFO)
  *Info\TipInfo\uFlags = #TTF_TRACK + #TTF_TRANSPARENT
  *Info\TipInfo\hwnd   = WindowHandle
  
  SendMessage_(*Info\TipHandle, #TTM_SETMAXTIPWIDTH, 0, 32767)
  SendMessage_(*Info\TipHandle, #TTM_ADDTOOL, 0, @*Info\TipInfo)
  SendMessage_(*Info\TipHandle, #TTM_SETTIPBKCOLOR, GetSysColor_(#COLOR_INFOBK), 0)
  SendMessage_(*Info\TipHandle, #TTM_SETTIPTEXTCOLOR, GetSysColor_(#COLOR_INFOTEXT), 0)
  
  Margins.RECT\left = 0
  Margins\top = -1
  Margins\right = 0
  Margins\bottom = -1
  SendMessage_(*Info\TipHandle, #TTM_SETMARGIN, 0, @Margins)
  
  SendMessage_(*Info\TipHandle, WM_SETFONT, SendMessage_(WindowHandle, #WM_GETFONT, 0, 0), 0)

  ProcedureReturn #True
  
EndProcedure  



Procedure.l ComboBoxInfoTipShowTip ( WindowHandle.l, *Info.CBINFOTIPINFO, TextLength.l, MaxWidth.l, XPos.l, YPos.l )

  dc.l = GetDC_(WindowHandle)
  OldFont.l = SelectObject_(dc, SendMessage_(WindowHandle, #WM_GETFONT, 0, 0))
  GetTextExtentPoint32_(dc, *Info\TipText, TextLength, @TextSize.SIZE)
  SelectObject_(dc, OldFont)
  ReleaseDC_(WindowHandle, dc)
  If TextSize\cx > MaxWidth 
    PokeW(@TipPoint.l, XPos & $ffff)
    PokeW(@TipPoint + 2, YPos & $ffff)
    SendMessage_(*Info\TipHandle, #TTM_UPDATETIPTEXT, 0, @*Info\TipInfo);
    SendMessage_(*Info\TipHandle, #TTM_TRACKPOSITION, 0, TipPoint);
    SendMessage_(*Info\TipHandle, #TTM_TRACKACTIVATE, 1, @*Info\TipInfo);
    ProcedureReturn #True
  EndIf
    
  ProcedureReturn #False
  
EndProcedure


Procedure.l ComboBoxInfoTipItemText ( WindowHandle.l, *Info.CBINFOTIPINFO, ItemIndex.l )

  TextLength.l = 0
  If ItemIndex < 0 
    TextLength = GetWindowTextLength_(WindowHandle)
  Else
    TextLength = SendMessage_(WindowHandle, #LB_GETTEXTLEN, ItemIndex, 0)
  EndIf
    
  If TextLength > 0
    If TextLength > (*Info\TipTextLength - 2)
      If #Null <> *Info\TipText
        FreeMemory(*Info\TipText)
      EndIf
      TextLength = TextLength + 128
      *Info\TipText = AllocateMemory(TextLength * SizeOf(Character))
      If #Null <> *Info\TipText 
        *Info\TipTextLength = TextLength
      Else
        *Info\TipTextLength = 0
      EndIf
    EndIf
    
    If #Null <> *Info\TipText
      If ItemIndex < 0 
        TextLength = GetWindowText_(WindowHandle, *Info\TipText, *Info\TipTextLength)
      Else
        TextLength = SendMessage_(WindowHandle, #LB_GETTEXT, ItemIndex, *Info\TipText)
      EndIf
  
      If TextLength >= 0      
        PokeW(*Info\TipText + (TextLength * SizeOf(Character)), 0)
      EndIf
    EndIf  
  EndIf
  
  ProcedureReturn TextLength
  
EndProcedure



Procedure.l ComboBoxInfoTipListBoxWinProc ( WindowHandle.l, Message.l, WParam.l, LParam.l )
  
  *Info.CBINFOTIPINFO = GetProp_(WindowHandle, @"cbinfotip")
  If #Null = *Info
    ProcedureReturn 0
  EndIf
  
  *WinProc = *Info\PrevWinProc
  If #Null = *WinProc
    ProcedureReturn 0
  EndIf

  Select Message
  
    Case #WM_NCDESTROY
      KillTimer_(WindowHandle, 1)
      SetWindowLong_(WindowHandle, #GWL_WNDPROC, *WinProc)
      RemoveProp_(WindowHandle, @"cbinfotip") 
      If #Null <> *Info\TipText
        FreeMemory(*Info\TipText)
      EndIf  
      FreeMemory(*Info)

    Case #WM_MOUSEWHEEL
      SendMessage_(*Info\TipHandle, #TTM_TRACKACTIVATE, 0, @*info\TipInfo)
      *Info\CurrentItem = -1
      KillTimer_(WindowHandle, 1)
      
    Case #WM_MOUSEMOVE
      GetClientRect_(WindowHandle, @ClientRect.RECT)
      If PtInRect_(@ClientRect, PeekW(@LParam), PeekW(@LParam + 2))
        SelectedItem.l = SendMessage_(WindowHandle, #LB_ITEMFROMPOINT, 0, LParam)
        If SelectedItem >= 0 
          If SelectedItem = *Info\CurrentItem
            ProcedureReturn CallWindowProc_(*WinProc, WindowHandle, Message, WParam, LParam)
          EndIf
          *Info\CurrentItem = SelectedItem
          SetWindowPos_(WindowHandle, #HWND_NOTOPMOST, 0, 0, 0, 0, #SWP_NOSIZE + #SWP_NOMOVE)
        
          TextLength.l = ComboBoxInfoTipItemText(WindowHandle, *Info, SelectedItem)
          If TextLength > 0
            *Info\TipInfo\lpszText = *info\TipText
            SendMessage_(WindowHandle, #LB_GETITEMRECT, SelectedItem, @ItemRect.RECT)
            ClientToScreen_(WindowHandle, @ItemRect)
            If ComboBoxInfoTipShowTip(WindowHandle, *Info, TextLength, ClientRect\right - ClientRect\left - 3, ItemRect\left, ItemRect\top)      
              SetTimer_(WindowHandle, 1, 50, 0)
              ProcedureReturn CallWindowProc_(*WinProc, WindowHandle, Message, WParam, LParam)
            EndIf
          EndIf    
        EndIf  
      EndIf
      SendMessage_(*Info\TipHandle, #TTM_TRACKACTIVATE, 0, @*info\TipInfo)
      *Info\CurrentItem = -1
      KillTimer_(WindowHandle, 1)
      
    Case #WM_TIMER
      If 1 = WParam 
        GetCursorPos_(@CurrentPoint.POINT)  
        ScreenToClient_(WindowHandle, @CurrentPoint)
        GetClientRect_(WindowHandle, @CurrentRect.RECT)
        ListBoxStyle.l = GetWindowLong_(WindowHandle, #GWL_STYLE)
        If (ListBoxStyle & #WS_VISIBLE) = 0 Or Not PtInRect_(@CurrentRect, CurrentPoint\x, CurrentPoint\y)
          SendMessage_(*Info\TipHandle, #TTM_TRACKACTIVATE, 0, @*info\TipInfo)
          KillTimer_(WindowHandle, 1)
        EndIf
      EndIf      

  EndSelect
          
  ProcedureReturn CallWindowProc_(*WinProc, WindowHandle, Message, WParam, LParam)
  
EndProcedure



Procedure.l ComboBoxInfoTipWinProc ( WindowHandle.l, Message.l, WParam.l, LParam.l )
  
  *Info.CBINFOTIPINFO = GetProp_(WindowHandle, @"cbinfotip")
  If #Null = *Info
    ProcedureReturn 0
  EndIf
  
  *WinProc = *Info\PrevWinProc
  If #Null = *WinProc
    ProcedureReturn 0
  EndIf
    
  Select Message
  
    Case #WM_NCDESTROY
      KillTimer_(WindowHandle, 1)
      SetWindowLong_(WindowHandle, #GWL_WNDPROC, *WinProc)
      RemoveProp_(WindowHandle, @"cbinfotip") 
      If #Null <> *Info\TipText
        FreeMemory(*Info\TipText)
      EndIf  
      FreeMemory(*Info)

    Case #WM_CTLCOLORLISTBOX 
      If *Info\ListBoxHandle = #Null
        *ListInfo.CBINFOTIPINFO = AllocateMemory(SizeOf(CBINFOTIPINFO))
        If #Null <> *ListInfo 
          If Not ComboBoxInfoTipInitTip(LParam, *ListInfo)
            FreeMemory(*ListInfo)
          Else
            *ListInfo\CurrentItem = -1 
            *ListInfo\PrevWinProc = GetWindowLong_(LParam, #GWL_WNDPROC)  
            SetProp_(LParam, @"cbinfotip", *ListInfo)
            SetWindowLong_(LParam, #GWL_WNDPROC, @ComboBoxInfoTipListBoxWinProc())
            *Info\ListBoxHandle = LParam 
          EndIf
        EndIf    
      EndIf          
    
    Case #WM_MOUSEMOVE
      GetClientRect_(WindowHandle, @ClientRect.RECT)
      ClientRect\right = ClientRect\right - GetSystemMetrics_(#SM_CXTHUMB) - 2
      If PtInRect_(@ClientRect, PeekW(@LParam), PeekW(@LParam + 2))
        ClientToScreen_(WindowHandle, @ClientRect)
        ClientToScreen_(WindowHandle, @ClientRect + 8)
        TextLength.l = ComboBoxInfoTipItemText(WindowHandle, *Info, -1)
        If TextLength > 0
          *Info\TipInfo\lpszText = *info\TipText
          If ComboBoxInfoTipShowTip(WindowHandle, *Info, TextLength, ClientRect\right - ClientRect\left, ClientRect\left, ClientRect\top)      
            SetTimer_(WindowHandle, 1, 50, 0)
            ProcedureReturn CallWindowProc_(*WinProc, WindowHandle, Message, WParam, LParam)
          EndIf
        EndIf  
      EndIf
      KillTimer_(WindowHandle, 1)
      SendMessage_(*Info\TipHandle, #TTM_TRACKACTIVATE, 0, @*info\TipInfo)

          
    Case #WM_TIMER
      If 1 = WParam 
        GetCursorPos_(@CurrentPoint.POINT)  
        ScreenToClient_(WindowHandle, @CurrentPoint)
        GetClientRect_(WindowHandle, @CurrentRect.RECT)
        CurrentRect\right = CurrentRect\right - GetSystemMetrics_(#SM_CXTHUMB) - 2
        If Not PtInRect_(@CurrentRect, CurrentPoint\x, CurrentPoint\y)
          SendMessage_(*Info\TipHandle, #TTM_TRACKACTIVATE, 0, @*info\TipInfo)
          KillTimer_(WindowHandle, 1)
        EndIf
      EndIf      
         
  EndSelect
          
  ProcedureReturn CallWindowProc_(*WinProc, WindowHandle, Message, WParam, LParam)
  
EndProcedure


Procedure.l ComboBoxInfoTip ( WindowHandle.l )

  *Info.CBINFOTIPINFO = AllocateMemory(SizeOf(CBINFOTIPINFO))
  If #Null = *Info 
    ProcedureReturn #False
  EndIf
    
  If Not ComboBoxInfoTipInitTip(WindowHandle, *Info)
    FreeMemory(*Info)
    ProcedureReturn #False
  EndIf
   
  *Info\PrevWinProc = GetWindowLong_(WindowHandle, #GWL_WNDPROC)  
  SetProp_(WindowHandle, @"cbinfotip", *Info)
  SetWindowLong_(WindowHandle, #GWL_WNDPROC, @ComboBoxInfoTipWinProc())
   
  ProcedureReturn #True   

EndProcedure
  





#Window = 1
#ListIcon = 2
#Text = 3
#ListView = 4
#LVS_EX_LABELTIP = $4000


If OpenWindow(#Window,#PB_Ignore,#PB_Ignore,200,420,"ListView Tooltip",#PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(#Window))
   ComboBoxGadget(#ListIcon,0,0,200,200,200)
   ComboBoxInfoTip(GadgetID(#ListIcon))
   TextGadget(#Text, 0, 200, 200, 20, "'ListViewGadget':")
   ListIconGadget(#ListView, 0, 220, 200, 200, "", 170, #LVS_NOCOLUMNHEADER)
   SendMessage_(GadgetID(#ListView), #LVM_SETEXTENDEDLISTVIEWSTYLE, 0, #LVS_EX_LABELTIP)
EndIf

For i = 1 To 100
   Text.s = RSet("", i, Chr(Random(95) + 32))
   AddGadgetItem(#ListIcon, -1, Text)
   AddGadgetItem(#ListView, -1, Text)
Next i


Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow: End 


Posted: Fri Aug 08, 2008 4:11 pm
by Michael Vogel
Late response to waldschrath - THANKS!

Michael