Link to home
Start Free TrialLog in
Avatar of Bryce Bassett
Bryce BassettFlag for United States of America

asked on

VBA Listbox: Mouseover to display full text of listbox items

Working in Word 2016.  I have a UserForm with a listbox containing paragraph-length entries.  The listbox lets the user see the start of each paragraph, but I have a preview box below where I'd like to display the full text of the listbox item when the user mouses over it.

I've found several different approaches on the web, and have implemented one that uses some API calls, to successfully report the X (which I don't need) and Y position of the cursor when I mouseover the listbox.  But I'm struggling with the last part, how to translate that back to which item in the listbox the cursor is over.  
Public Type POINTAPI
 x As Long
 Y As Long
End Type

Public Function GetXCursorPos() As Long
Dim pt As POINTAPI
GetCursorPos pt
GetXCursorPos = pt.x
End Function

Public Function GetYCursorPos() As Long
Dim pt As POINTAPI
GetCursorPos pt
GetYCursorPos = pt.Y
End Function

Private Sub ListBox1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal Y As Single)
Me.Label2.Caption = "X Screen Position = " & GetXCursorPos  'for testing
Me.Label3.Caption = "Y Screen Position = " & GetYCursorPos  'for testing
'************translate Y position to ListBox1.List (number)??
me.Preview.Caption = Me.ListBox1.List (number)
End Sub

Open in new window

The various posts use some form of setting or figuring out the text height to calculate which line we're on, or another API called LBItemFromPt, but I couldn't get either to work.   I think I just need to see how it all fits together.

One important consideration is that my listbox is long and has a vertical scrollbar, so we may sometimes be looking at the bottom half of the list.  I assume ListBox1.TopIndex might help us figure this out, but before I spend the time to reinvent the wheel I wanted to see if someone has an approach to this.

Thanks!
Avatar of Jamie Garroch (MVP)
Jamie Garroch (MVP)
Flag of United Kingdom of Great Britain and Northern Ireland image

There's several examples using VB or VB.NEt that use the LBItemFromPt API and although I think that could work, this might be an easier way:

    Private Sub ListBox1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
      Dim ItemHeight As Single
      Dim TopItem As Long
      Dim CurItem As Long
      
      ItemHeight = ListBox1.Font.Size * 1.2
        
      TopItem = ListBox1.TopIndex
      
      CurItem = Int(Y / ItemHeight + TopItem)
    End Sub

Open in new window

SOLUTION
Avatar of irudyk
irudyk
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Bryce Bassett

ASKER

Thanks, both!  Very elegant solution... works great.  I much prefer this approach that does not rely on API!  

Hope somebody else will also find this useful.