I have a customer combobox that allows the programmer to set tooltips for the dropdown items at run time. It works great as long as the listing is from the dropdown (i.e. I press the down arrow.) However, I would like it to work for the "SuggestAppend" list as well, but it isn't.
I 'borrowed' the code from an online source (can't remember the source), and don't completely understand the mechanics of the control. The code I'm using overrides some properties, but I need to figure out what event is fired when the suggest list is displayed. I've included the source code for the control. It fires a custom DropdownItemSelected event in which the tooltip is loaded as each item is hovered over. But it does not work on the dropdown items that are generated (via suggestion/append using the listitems for thesource) when I try typing into the text portion of the combobox.
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class ExtComboBox
Inherits ComboBox
Private mDropdown As DropdownWindow
Public Delegate Sub DropdownItemSelectedEventHandler(ByVal sender As Object, ByVal e As DropdownItemSelectedEventArgs)
Public Event DropdownItemSelected As DropdownItemSelectedEventHandler
Protected Overloads Overrides Sub OnDropDown(ByVal e As EventArgs)
' Install wrapper
MyBase.OnDropDown(e)
' Retrieve handle to dropdown list
Dim info As New COMBOBOXINFO()
info.cbSize = Marshal.SizeOf(info)
SendMessageCb(Me.Handle, &H164, IntPtr.Zero, info)
mDropdown = New DropdownWindow(Me)
mDropdown.AssignHandle(info.hwndList)
End Sub
Protected Overloads Overrides Sub OnDropDownClosed(ByVal e As EventArgs)
' Remove wrapper
mDropdown.ReleaseHandle()
mDropdown = Nothing
MyBase.OnDropDownClosed(e)
OnSelect(-1, Rectangle.Empty, True)
End Sub
Friend Sub OnSelect(ByVal item As Integer, ByVal pos As Rectangle, ByVal scroll As Boolean)
'If Me.DropdownItemSelected IsNot Nothing Then
pos = Me.RectangleToClient(pos)
RaiseEvent DropdownItemSelected(Me, New DropdownItemSelectedEventArgs(item, pos, scroll))
'End If
End Sub
' Event handler arguments
Public Class DropdownItemSelectedEventArgs
Inherits EventArgs
Private mItem As Integer
Private mPos As Rectangle
Private mScroll As Boolean
Public Sub New(ByVal item As Integer, ByVal pos As Rectangle, ByVal scroll As Boolean)
mItem = item
mPos = pos
mScroll = scroll
End Sub
Public ReadOnly Property SelectedItem() As Integer
Get
Return mItem
End Get
End Property
Public ReadOnly Property Bounds() As Rectangle
Get
Return mPos
End Get
End Property
Public ReadOnly Property Scrolled() As Boolean
Get
Return mScroll
End Get
End Property
End Class
' Wrapper for combobox dropdown list
Private Class DropdownWindow
Inherits NativeWindow
Private mParent As ExtComboBox
Private mItem As Integer
Public Sub New(ByVal parent As ExtComboBox)
mParent = parent
mItem = -1
End Sub
Protected Overloads Overrides Sub WndProc(ByRef m As Message)
' All we're getting here is WM_MOUSEMOVE, ask list for current selection for LB_GETCURSEL
Console.WriteLine(m.ToString())
MyBase.WndProc(m)
If m.Msg = &H200 Then
Dim item As Integer = CInt(SendMessage(Me.Handle, &H188, IntPtr.Zero, IntPtr.Zero))
If item <> mItem Then
mItem = item
OnSelect(False)
End If
End If
If m.Msg = &H115 Then
' List scrolled, item position would change
OnSelect(True)
End If
End Sub
Private Sub OnSelect(ByVal scroll As Boolean)
Dim rc As New RECT()
'SendMessageRc(Me.Handle, &H198, CType(mItem, IntPtr), rc)
SendMessageRc(Me.Handle, &H198, CType(mItem, IntPtr), rc)
MapWindowPoints(Me.Handle, IntPtr.Zero, rc, 2)
mParent.OnSelect(mItem, Rectangle.FromLTRB(rc.Left, rc.Top, rc.Right, rc.Bottom), scroll)
End Sub
End Class
' P/Invoke declarations
Private Structure COMBOBOXINFO
Public cbSize As Int32
Public rcItem As RECT
Public rcButton As RECT
Public buttonState As Integer
Public hwndCombo As IntPtr
Public hwndEdit As IntPtr
Public hwndList As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
<DllImport("user32.dll", EntryPoint:="SendMessageW", CharSet:=CharSet.Unicode)> _
Private Shared Function SendMessageCb(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wp As IntPtr, ByRef lp As COMBOBOXINFO) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="SendMessageW", CharSet:=CharSet.Unicode)> _
Private Shared Function SendMessageRc(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wp As IntPtr, ByRef lp As RECT) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wp As IntPtr, ByVal lp As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function MapWindowPoints(ByVal hWndFrom As IntPtr, ByVal hWndTo As IntPtr, <[In](), Out()> ByRef rc As RECT, ByVal points As Integer) As Integer
End Function
End Class
This bit goes in the event handler for DropdownItemSelected:
Private Sub cboxCustomerName_DropdownItemSelected(ByVal sender As Object, ByVal e As ExtComboBox.DropdownItemSelectedEventArgs) _
Handles cboxCustomerName.DropdownItemSelected
If e.SelectedItem < 0 OrElse e.Scrolled Then
ttpToolTip1.Hide(cboxCustomerName)
Else
Dim strToolTip As New StringBuilder
With cboxCustomerName.DataSource
If .ITEM(e.SelectedItem)("CustomerID") IsNot DBNull.Value Then _
strToolTip.AppendLine(.ITEM(e.SelectedItem)("CustomerID"))
If .ITEM(e.SelectedItem)("Customer_Name") IsNot DBNull.Value Then _
strToolTip.AppendLine(.ITEM(e.SelectedItem)("Customer_Name"))
If .ITEM(e.SelectedItem)("Address1") IsNot DBNull.Value Then _
strToolTip.AppendLine(.ITEM(e.SelectedItem)("Address1"))
If .ITEM(e.SelectedItem)("Address2") IsNot DBNull.Value Then _
strToolTip.AppendLine(.ITEM(e.SelectedItem)("Address2"))
If .ITEM(e.SelectedItem)("City") IsNot DBNull.Value _
And .ITEM(e.SelectedItem)("State") IsNot DBNull.Value Then
strToolTip.AppendLine(String.Format("{0}, {1}", .ITEM(e.SelectedItem)("City"), .ITEM( _
e.SelectedItem)("State")))
ElseIf .ITEM(e.SelectedItem)("City") IsNot DBNull.Value Then
strToolTip.AppendLine(String.Format("{0}", .ITEM(e.SelectedItem)("City")))
Else
strToolTip.AppendLine(String.Format("{0}", .ITEM(e.SelectedItem)("State")))
End If
End With
Dim Loc As New Point(e.Bounds.Location.X, e.Bounds.Y + e.Bounds.Height)
ttpToolTip1.Show(strToolTip.ToString, cboxCustomerName, Loc, 2000)
End If
End Sub
Can someone give me any pointers, as in which events do I need to trap for this?
Thanks.