views:

240

answers:

0

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.