Adding Multiline Balloon ToolTips to ListView Items

Environment: VB4 (32-bit), VB5, VB6

The accompanying code demonstrates a technique you can use to create multiline balloon tooltips for ListView items.

The code is based on the following simple idea. In the MouseMove event, you need to check the index of the item under the mouse pointer, and if this item is changed, you simply redefine the text of the tooltip attached to the ListView control. Notice that you should destroy the tooltip if there is no item under the mouse pointer.

To determine the index of the list-view item under the mouse pointer, we send the LVM_HITTEST message to the ListView control. The SendMessage function you should use to send this message returns the index of the item at the specified position, if any, or -1 otherwise. Before you send the message, populate the pt field of an instance of the LVHITTESTINFO structure with the coordinates of the mouse pointer (you pass the reference to this structure as the value of the lParam parameter in SendMessage). You can use for this purpose the X and Y parameters of the MouseMove event of the control, but draw attention at the fact that these parameters can be measured in twips and you need to convert them in pixels.

This simple idea can be used to create such tooltips for ListBox items, any grid control items, and so on. For instance, we use this technique in extra samples for an iGrid ActiveX Control we produce. (This is an editable replacement for ListView and FlexGrid. Visit for more info.)

Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; _
Begin VB.Form Form1
   Caption         =   "Form1"
   ClientHeight    =   3195
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   5745
   LinkTopic       =   "Form1"
   ScaleHeight     =   3195
   ScaleWidth      =   5745
   StartUpPosition =   3    'Windows Default
   Begin MSComctlLib.ListView ListView1
      Height          =   2595
      Left            =   120
      TabIndex        =   0
      Top             =   300
      Width           =   5475
      _ExtentX        =   9657
      _ExtentY        =   4577
      View            =   3
      LabelWrap       =   -1    'True
      HideSelection   =   -1    'True
      AllowReorder    =   -1    'True
      _Version        =   393217
      ForeColor       =   -2147483640
      BackColor       =   -2147483643
      BorderStyle     =   1
      Appearance      =   1
      NumItems        =   3
      BeginProperty ColumnHeader(1) _
         Text            =   "Column 1"
         Object.Width    =   2540
      BeginProperty ColumnHeader(2) _
         SubItemIndex    =   1
         Text            =   "Column 2"
         Object.Width    =   2540
      BeginProperty ColumnHeader(3) _
         SubItemIndex    =   2
         Text            =   "Column 3"
         Object.Width    =   2540
Attribute VB_Name            = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable       = False
Attribute VB_PredeclaredId   = True
Attribute VB_Exposed         = False
Option Explicit

Private Declare Function SendMessage Lib "user32" _
        Alias "SendMessageA" (ByVal hwnd As Long, _
                              ByVal wMsg As Long, _
                              ByVal wParam As Long, _
                              lParam As Any) As Long

Const LVM_FIRST   = &H1000&

Private Type POINTAPI
    x As Long
    y As Long
End Type

   flags As Long
   iItem As Long
   iSubItem As Long
End Type

Dim TT As CTooltip
Dim m_lCurItemIndex As Long

Private Sub Form_Load()
   With ListView1.ListItems
      .Add Text:="Test item #1"
      .Add Text:="Test item #2"
      .Add Text:="Long long long test item #3"
   End With

   Set TT = New CTooltip
   TT.Style = TTBalloon
   TT.Icon = TTIconInfo
End Sub

Private Sub ListView1_MouseMove(Button As Integer, _
                                Shift As Integer, _
                                x As Single, _
                                y As Single)
   Dim lItemIndex As Long = x / Screen.TwipsPerPixelX = y / Screen.TwipsPerPixelY
   lItemIndex = SendMessage(ListView1.hwnd, _
                            LVM_HITTEST, 0, lvhti) + 1

   If m_lCurItemIndex <> lItemIndex Then
      m_lCurItemIndex    = lItemIndex
      If m_lCurItemIndex = 0 Then   ' no item under the mouse
                                    ' pointer
         TT.Title = "Multiline tooltip"
         TT.TipText = ListView1.ListItems(m_lCurItemIndex).Text
         TT.Create ListView1.hwnd
      End If
   End If
End Sub

  MultiUse            = -1   'True
  Persistable         = 0    'NotPersistable
  DataBindingBehavior = 0    'vbNone
  DataSourceBehavior  = 0    'vbNone
  MTSTransactionMode  = 0    'NotAnMTSObject
Attribute VB_Name            = "CTooltip"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable       = True
Attribute VB_PredeclaredId   = False
Attribute VB_Exposed         = False
Attribute VB_Ext_KEY         = "SavedWithClassBuilder6" ,"Yes"
Attribute VB_Ext_KEY         = "Top_Level" ,"Yes"
Option Explicit

Private Declare Sub InitCommonControls Lib "comctl32.dll" ()

''Windows API Functions
Private Declare Function CreateWindowEx Lib "user32" _
        Alias "CreateWindowExA" (ByVal dwExStyle As Long, _
        ByVal lpClassName As String, ByVal lpWindowName As String, _
        ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, _
        ByVal nWidth As Long, ByVal nHeight As Long, _
        ByVal hWndParent As Long, ByVal hMenu As Long, _
        ByVal hInstance As Long, lpParam As Any) As Long
Private Declare Function SendMessage Lib "user32" _
        Alias "SendMessageA" (ByVal hwnd As Long, _
        ByVal wMsg As Long, ByVal wParam As Long, _
        lParam As Any) As Long
Private Declare Function SendMessageLong Lib "user32" _
        Alias "SendMessageA" (ByVal hwnd As Long, _
        ByVal wMsg As Long, ByVal wParam As Long, _
        ByVal lParam As Long) As Long
Private Declare Function DestroyWindow Lib "user32" _
        (ByVal hwnd As Long) As Long

''Windows API Constants
Private Const WM_USER       = &H400
Private Const CW_USEDEFAULT = &H80000000

''Windows API Types
Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

''Tooltip Window Constants
Private Const TTS_NOPREFIX        = &H2
Private Const TTF_TRANSPARENT     = &H100
Private Const TTF_CENTERTIP       = &H2
Private Const TTM_ADDTOOLA        = (WM_USER + 4)
Private Const TTM_ACTIVATE        = WM_USER + 1
Private Const TTM_UPDATETIPTEXTA  = (WM_USER + 12)
Private Const TTM_SETMAXTIPWIDTH  = (WM_USER + 24)
Private Const TTM_SETTIPBKCOLOR   = (WM_USER + 19)
Private Const TTM_SETTITLE        = (WM_USER + 32)
Private Const TTS_BALLOON         = &H40
Private Const TTS_ALWAYSTIP       = &H1
Private Const TTF_SUBCLASS        = &H10
Private Const TTF_IDISHWND        = &H1
Private Const TTM_SETDELAYTIME    = (WM_USER + 3)
Private Const TTDT_AUTOPOP        = 2
Private Const TTDT_INITIAL        = 3

Private Const TOOLTIPS_CLASSA = "tooltips_class32"

''Tooltip Window Types
Private Type TOOLINFO
    lSize As Long
    lFlags As Long
    hwnd As Long
    lId As Long
    lpRect As RECT
    hInstance As Long
    lpStr As String
    lParam As Long
End Type

Public Enum ttIconType
    TTNoIcon      = 0
    TTIconInfo    = 1
    TTIconWarning = 2
    TTIconError   = 3
End Enum

Public Enum ttStyleEnum
End Enum

'local variable(s) to hold property value(s)
Private mvarBackColor As Long
Private mvarTitle As String
Private mvarForeColor As Long
Private mvarIcon As ttIconType
Private mvarCentered As Boolean
Private mvarStyle As ttStyleEnum
Private mvarTipText As String
Private mvarVisibleTime As Long
Private mvarDelayTime As Long

'private data
Private m_lTTHwnd As Long        ' hwnd of the tooltip
Private m_lParentHwnd As Long    ' hwnd of the window the tooltip
                                 ' attached to
Private ti As TOOLINFO

Public Property Let Style(ByVal vData As ttStyleEnum)
   'used when assigning a value to the property, on the left side
   'of an assignment.
   'Syntax: X.Style = 5
   mvarStyle        = vData
End Property

Public Property Get Style() As ttStyleEnum
   'used when retrieving value of a property, on the right side
   'of an assignment.
   'Syntax: Debug.Print X.Style
   Style = mvarStyle
End Property

Public Property Let Centered(ByVal vData As Boolean)
   'used when assigning a value to the property, on the left side
   'of an assignment.
   'Syntax: X.Centered = 5
   mvarCentered        = vData
End Property

Public Property Get Centered() As Boolean
   'used when retrieving value of a property, on the right side
   'of an assignment.
   'Syntax: Debug.Print X.Centered
   Centered = mvarCentered
End Property

Public Function Create(ByVal ParentHwnd As Long) As Boolean
   Dim lWinStyle As Long

   If m_lTTHwnd <> 0 Then
      DestroyWindow m_lTTHwnd
   End If

   m_lParentHwnd = ParentHwnd


   ''create baloon style if desired
   If mvarStyle = TTBalloon Then lWinStyle = lWinStyle _
                                             Or TTS_BALLOON
   m_lTTHwnd = CreateWindowEx(0&, _
      vbNullString, _
      lWinStyle, _
      0&, _
      0&, _
      App.hInstance, _

   ''now set our tooltip info structure
   With ti
      ''if we want it centered, then set that flag
      If mvarCentered Then
      End If
      ''set the hwnd prop to our parent control's hwnd
      .hwnd      = m_lParentHwnd
      .lId       = m_lParentHwnd '0
      .hInstance = App.hInstance
      '.lpstr    = ALREADY SET
      '.lpRect   = lpRect
      .lSize     = Len(ti)
   End With

   ''add the tooltip structure
   SendMessage m_lTTHwnd, TTM_ADDTOOLA, 0&, ti

   ''if we want a title or we want an icon
   If mvarTitle <> vbNullString Or mvarIcon <> TTNoIcon Then
      SendMessage m_lTTHwnd, TTM_SETTITLE, CLng(mvarIcon), _
                  ByVal mvarTitle
   End If

   If mvarForeColor <> Empty Then
      SendMessage m_lTTHwnd, TTM_SETTIPTEXTCOLOR, mvarForeColor, 0&
   End If

   If mvarBackColor <> Empty Then
      SendMessage m_lTTHwnd, TTM_SETTIPBKCOLOR, mvarBackColor, 0&
   End If

End Function

Public Property Let Icon(ByVal vData As ttIconType)
   mvarIcon = vData
   If m_lTTHwnd <> 0 And mvarTitle <> Empty And mvarIcon <> _
      TTNoIcon Then
      SendMessage m_lTTHwnd, TTM_SETTITLE, CLng(mvarIcon), _
      ByVal mvarTitle
   End If
End Property

Public Property Get Icon() As ttIconType
   Icon = mvarIcon
End Property

Public Property Let ForeColor(ByVal vData As Long)
   mvarForeColor = vData
   If m_lTTHwnd <> 0 Then
      SendMessage m_lTTHwnd, TTM_SETTIPTEXTCOLOR, mvarForeColor, 0&
   End If
End Property

Public Property Get ForeColor() As Long
   ForeColor = mvarForeColor
End Property

Public Property Let Title(ByVal vData As String)
   mvarTitle = vData
   If m_lTTHwnd <> 0 And mvarTitle <> Empty And mvarIcon <> _
                     TTNoIcon Then
      SendMessage m_lTTHwnd, TTM_SETTITLE, CLng(mvarIcon), _
                  ByVal mvarTitle
   End If
End Property

Public Property Get Title() As String
   Title = ti.lpStr
End Property

Public Property Let BackColor(ByVal vData As Long)
   mvarBackColor = vData
   If m_lTTHwnd <> 0 Then
      SendMessage m_lTTHwnd, TTM_SETTIPBKCOLOR, mvarBackColor, 0&
   End If
End Property

Public Property Get BackColor() As Long
   BackColor = mvarBackColor
End Property

Public Property Let TipText(ByVal vData As String)
   mvarTipText = vData
   ti.lpStr    = vData
   If m_lTTHwnd <> 0 Then
      SendMessage m_lTTHwnd, TTM_UPDATETIPTEXTA, 0&, ti
   End If
End Property

Public Property Get TipText() As String
   TipText = mvarTipText
End Property

Private Sub Class_Initialize()
   mvarDelayTime   =  500
   mvarVisibleTime = 5000
End Sub

Private Sub Class_Terminate()
End Sub

Public Sub Destroy()
   If m_lTTHwnd <> 0 Then
      DestroyWindow m_lTTHwnd
   End If
End Sub

Public Property Get VisibleTime() As Long
   VisibleTime = mvarVisibleTime
End Property

Public Property Let VisibleTime(ByVal lData As Long)
   mvarVisibleTime = lData
End Property

Public Property Get DelayTime() As Long
   DelayTime = mvarDelayTime
End Property

Public Property Let DelayTime(ByVal lData As Long)
   mvarDelayTime = lData
End Property


Download demo project - 12 Kb


  • グッチ グッチ 財布 グッチ バッグ コーチ コーチ バッグ コーチ 財布

    Posted by scgchurtis on 07/19/2013 06:00pm

    シャネル 財布 2013 ちゃんと興味のある人間なら彼女のおかれた悲惨な環境を知っているはずです コーチ プラダリュック育児に協力的なことも明かす コーチ 長財布 この作品こそが今回のプロジェクトのコンセプトそのものだと語る クロエ 財布 アウトレット 団体の部ともに優勝し [url=]インターネット[/url] [url=]PRADA 財布[/url] シャネル 財布 メンズ グッチアウトレット プラダ アウトレット ルイヴィトン ミュウミュウ 財布 シャネル 新作 シャネル 財布 プラダ バッグ クロエバッグ ミュウミュウ アウトレット

  • It's been a active week in bung of teach potential retailer|mentor duct online

    Posted by Stoompota on 06/26/2013 11:14am

    Ladies, these aren't your momma's fanny packs. Hands-free bags are the perfect alternative to heavy shoulder bags. They allow you to hold the essentials around your waist so that your arms and hands are free to wave [url=]coach outlet[/url] in the air to your favorite band or hold a drink to keep you cool in the hot desert sun. I can't think of a better bag to show off your fashion sense at a concert! The original: [url=][/url] the Gucci Belt Bag. Wear it to a concert, a bar, on a marathon shopping weekend in the city. The trendsetter: Angel Jackson Belle Star Bum Bag. Fringe is the best trend to take to a music festival in the wild wild west. Comfort is key at all day music festivals, but that doesn't mean you should sacrifice style. Be daring with your bag choice and show off your fashion sense! The leader of the pack: Zara Terez 14th Precint. Stick em up! Modeled after a gun holster, features adjustable double shoulder straps with snap-closure holster and back pocket. Understated at any price point: The LeSportsac Frieda Nylon Waist Bag is simple and affordable. The BE and D Taylor Cross Body doubles as [url=]coach outlet bag[/url] a Belt Bag and is chic in black with silver hardware. Our obsession with hands-free bags began when talking about the infamous indie music fest, Coachella. What one wears to the 3 day music event is almost as important as who's playing. Oversized sunnies? Check. Billowy [url=]coach outlet blog[/url] peasant dress? Check. Cut off denim shorts? Obviously. But what bag do I wear? Certainly no one wants to be schlepping around their oversized hobo or expensive leather bag that weighs down your shoulders or could potentially be ruined by the desert elements. Then I thought of quintessential fashionista, Carrie Bradshaw. Of course! I knew I could turn to Sex and the City to shine a light on fashion trends. I popped in Season 4 (the Aidan days) and found her wearing the iconic Gucci Belt Bag. Everybody needs a Louis: The colorful Louis Vuitton Bum Bag from SS10 or the understated Louis Vuitton Melville Bum Bag in Damier canvas.

  • oroton outlet online sale

    Posted by kellywhosal47 on 05/24/2013 11:41pm

    celine bags How her loss. celine handbags The players will be measured for body weight and percent body fat, which will give us a true measure of a player's rotundness. celine luggage This contributes to making Louis Vuitton brand bags the industry leader. isabel marant Controversial public intellectual Denise Bombardier contributed La Diva, a song inspired by the tragic life of Greek opera singer Maria Callas. isabel marant sneakers Exotic leather is the hallmark of these handbags. Rihanna et Kate Moss apparaissent nue dans des poses provocantes, la double couverture du nouveau numro du Magazine V. - celine bags - celine bags - celine bags You can go for ridge version which has got stitching outside or souple version that got a softer feel and inside stitching. The the need for stitches enjoy the same dimensions.

  • Cheap NFL Jerseys China

    Posted by pyncPneunty on 05/15/2013 02:16pm

    Shutdown Nook will probably be [url=]Cheap Jerseys Free Shipping[/url] inside Lucas Acrylic Ground for your quarterback/receiver soccer drills for kids nowadays, and also we are going to up-date an individual on what these kinds of quickly fellas seemed any time working some approved avenues. ANY throat problem provides brought up any health-related reddish hole about Jarvis Jones (USA Nowadays Sporting activities Images)In a couple of periods with Ga, the particular 6-foot-3, 241-pound Jones acquired twenty eight totes then one interception and also has been 2 times known as a great All-American just before proclaiming early on for your set up following 2012 time of year. Jones will be widely-regarded being [url=]Cheap Jerseys Wholesale[/url] a prospective Top [url=]Cheap Jerseys USA[/url] select inside the 2013 AMERICAN FOOTBAL Set up and also consumes the particular Simply no. 10 i'm all over this the original " Shutdown Nook Huge Board". Armstead has an appealing account, even though. The particular 6-foot-5, 306-pound small-school superstar, which enjoyed sufficiently on the East-West Shrine Video game to be able to improve more attention, and also make a great invites for the Mature Pan as a possible injuries substitute.

  • Wholesale NFL Jerseys Free Shipping

    Posted by valoimmonfing on 05/15/2013 09:09am

    Right after Notre Dame has been usual, 42-14 from the Birmingham, al Red Hold inside the BCS World-class video game, the particular set up inventory regarding [url=]Wholesale NFL Jerseys USA[/url] linebacker Manti Te'o got several quite significant visits inside the trying to find local community. Considered to be the particular kind-of every-down thumper together with insurance coverage expertise that will push your pet in to the top with the 2013 AMERICAN FOOTBAL Set up, Te'o has been uncovered being a respectable, rangy opponent together with significant issues conquering prevents and also manning against greater, a lot more mainly appear participants. Nonetheless, it absolutely was considered, Te'o's persona would certainly retain your pet upwards inside [url=]Wholesale Jerseys Cheap[/url] the set up rotate in manners in which his / her utter actual skill may well [url=]Wholesale Jerseys USA[/url] not.

  • Luol Deng Jersey

    Posted by TeenueIntit on 05/15/2013 03:20am

    We are not really likely to help to make humor regarding that groups or even gamers he or she had been tugging with regard to, simply because occasionally a person allow simple (and possibly libelous) types proceed correct through. However we will wager you are able to speculate. Simpson, grow older 65, happens to be helping the 33-year phrase for any Sept [url=]Authenitc Kevin Durant Jersey[/url] 2007 equipped thievery within Vegas. He'll maintain jail till a minimum of 2017 prior to [url=]Authentic Kevin Martin Jersey[/url] he's entitled to parole. The actual 26-year-old [url=]Kevin Durant Jersey[/url] Lopes lives in Angola as the 31-year-old Umenyiora was created within Birmingham prior to shifting in order to Nigeria after which america. It isn't an excessive amount of the extend to express both of these have been in collection to create a few fairly good-looking Extremely Dish those who win and/or elegance a queen every time they circumvent to using kids.

  • Cheap Jerseys USA

    Posted by Inojernerry on 05/13/2013 04:03pm

    Together with David Harrison out there the entranceway and several total inquiries relating to Pittsburgh's complete dash, Ga OLB Jarvis Jones delivers quick prospective creation with a obligatory place inside Cock LeBeau's security. He has speedy across the side, robust, and also possibly a lot more adaptable inside his / her fresh structure as compared to this individual was at school. The particular Steelers furthermore misplaced Rashard Mendenall for the Cardinals inside the offseason, and also Mich Express halfback Le'Veon Bell has been the most notable person about basic director Kevin Colbert's table. He has any bullish strength again that will holder the holds, yet has to work with his / her complete defense in a crime more and more mindful that Dan Roethlisberger needs far better defense. The particular take regarding Pittsburgh's set up could be third-round [url=]Cheap Jerseys USA[/url] radio Markus [url=]Cheap Jerseys Free Shipping[/url] Wheaton regarding Or Express. There were your pet positioned 50th on this year's Shutdown 50, and [url=]Cheap NFL Jerseys USA[/url] also this individual reminds myself with the successful model regarding Brandon Lloyd -- some guy who is able to acquire downfield (a massive will need right after Robert Wallace's starting to be able to Miami) yet may also acquire available beneath specific zones and also acquire meters following your get.

  • Cheap Jerseys USA

    Posted by oppofsTaw on 05/12/2013 09:31am

    Coaching/front office changes: The Browns cleaned house this offseason, firing GM Tom Heckert and head coach Pat Shurmur on Dec. 31, 2012. The departures of Heckert and Shurmur were not a surprise as the change in ownership ?Randy Lerner to Jimmy Haslam ?had already [url=]Cheap NFL Jerseys Free Shipping[/url] resulted in the departure of president Mike Holmgren, who was replaced by Joe Banner. The Browns' personnel department is now led by Michael Lombardi, a former personnel executive who was most recently working as an analyst for the NFL Network. The Browns replaced Shurmur with Carolina Panthers [url=]Cheap Jerseys USA[/url] offensive coordinator Rob Chudzinski, who hired Norv Turner (offense) and Ray Horton (defense) [url=]Cheap NFL Jerseys[/url] as coordinators.

  • Wholesale Jerseys

    Posted by SLANYNATS on 05/11/2013 11:59pm

    You can find sports selections, and [url=]Cheap Jerseys Paypal[/url] also you can find sports selections. And also inside the sphere regarding sports selections, the particular Dallas Cowboys' selection to be able to business straight down from other authentic eighteenth total set up select and also shift straight down the particular 31st select earlier [url=]Cheap Jerseys Free Shipping[/url] held from the San francisco bay area 49ers will be wondered by simply concerning every person. Not really much since they bought and sold straight down, yet due to person they will got if they would thus -- Wisconsin heart Travis Frederick, a new player several experts acquired using a second- to be able to third-round level. Several would certainly claim in which Frederick wasn' big t also the most effective focus on the particular table; Cal' azines John Schwenke and also Alabama' azines Barrett Jones would certainly furthermore [url=]Cheap NFL Jerseys USA[/url] acquire ballots. Nevertheless the major problem has been the Cowboys, any staff which includes picked quite badly throughout the last handful of periods, manage to have inked that once more inside the completely wrong course.

  • Wholesale Jerseys Free Shipping

    Posted by Dedoaccoxia on 05/11/2013 11:04am

    NATIONAL FOOTBALL LEAGUE groups may usually let you know which gamers who've powerful mix exercises simply ask them to returning towards the mp3. Nevertheless, gamers along with excellent sports intrusions upward their own share constantly. You are able to state all that's necessary about how exactly the actual " Under garments Olympics" possess absolutely nothing [url=]Wholesale Jerseys Free Shipping[/url] related to the particular online game associated with soccer, however [url=]Wholesale NFL Jerseys Free Shipping[/url] do not inform Vernon Davis yet others such as him or her. The actual Bay area 49ers celebrity restricted finish as [url=]Wholesale Jerseys Cheap[/url] well as Annapolis alum strike the actual 2006 searching mix such as a lot of stones, managing a four. thirty seven 40-yard splash from 6-foot-3 as well as 254 lbs. Which work out chance him or her to the the surface of the very first circular, as well as there is no method he'd possess eliminated 6th general without having this.

  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date