JPro
JPro

Reputation: 6546

vb.net listbox exception

I am getting an exception when trying to run the below code in vb.net 2005

 Public Class Form1
    Public Declare Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hWnd As Long, _
    ByVal wMsg As Long, ByVal wParam As Long, _
    ByVal lParam As String) As Long
    Public Const LB_FINDSTRING = &H18F
    Dim listBoxHandle As IntPtr

    Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp
        listBoxHandle = ListBox1.Handle
        ListBox1.SelectedIndex = SendMessage(listBoxHandle, LB_FINDSTRING, -1, Int(TextBox1.Text))

    End Sub

End Class

Upvotes: 1

Views: 593

Answers (3)

Hans Passant
Hans Passant

Reputation: 941485

Your P/Invoke declaration is wrong, it dates back to the VB6 era. Use pinvoke.net to find the VB.NET equivalents. But first take a look at the MSDN Library, .NET has vastly improved beyond what VB6 provided. You don't have to resort to these kind of tricks anymore:

  Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
    ListBox1.SelectedIndex = ListBox1.FindString(TextBox1.Text)
  End Sub

Upvotes: 2

Chris Haas
Chris Haas

Reputation: 55427

Assuming your ListBox has only String objects you can use this for the KeyUp() function

Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp
    ListBox1.SelectedItem = TextBox1.Text
End Sub

It will only work if the entire text is found in the ListBox, though. If you want to get partial matches you'll have to write your own function and handle duplicates.

Also, as a rule, P/Invoke should be used as a last resort. If you find yourself using the DllImport or DECLARE syntax you should stop right there. There are definitely times for using it, but 99.999% of the time you can get away without.

Upvotes: 0

Daniel A. White
Daniel A. White

Reputation: 190945

You are sending this to an ANSI function. A .NET String is unicode.

You need to update the referenced P/Invoke.

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger,_
    ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

End Function 

And at the top of your code file

Import System.Runtime.InteropServices

Here is some more information on SendMessage - http://www.pinvoke.net/default.aspx/user32.SendMessage

Upvotes: 1

Related Questions