Good day to everybody!

I just want to know on is there any function/solution in vb6 that offers the best/most fastest way to autocomplete listview when type in a textbox.The data should be from SQL Server using ADO connection...Ive seen this function(I've not tested it yet) from
http://www.vbforums.com/showthread.php?t=438622.

Private Sub Text1_Change()
On Error GoTo ErrMsg

Dim LstItm As ListItem
Dim Strt as Integer

    ListView1.FindItem(Text1.Text, , , 1).Selected = True
       
    'If something was chosen then we get the rest of it
    strt = Len(Text1.Text)
    Text1.Text = ListView1.SelectedItem.Text
    Text1.SelStart = strt
    Text1.SelLength = Len(Text1.Text) - strt
    
Exit Sub
ErrMsg:
    ListView1.SelectedItem.Selected = False
End Sub

Anybody can help to make this the most fastest or is this the most fastest way of autocompleting? Im pulling a large data from SQL Server and will be filtered via autocomplete function then display it in a listview.

Thank you for helping!

Recommended Answers

All 6 Replies

Private Sub Text1_Change()
    On Error GoTo ErrMsg
     
    Dim LstItm As ListItem
    Dim Strt as Integer
    With ListView1
        .FindItem(Text1.Text, , , 1).Selected = True
        'If something was chosen then we get the rest of it
        strt = Len(Text1.Text)
        
        Text1.Text = .SelectedItem.Text
        Text1.SelStart = strt
        Text1.SelLength = Len(Text1.Text) - strt
        
    End With 
    Exit Sub
    ErrMsg:
    ListView1.SelectedItem.Selected = False
    End Sub

You can use With and End With to marginally speed up the process. Not much of a savings here, but some. Or try With .. End With around the Text1. .... statements. But I would say that the ListView Control has more overhead than the TextBox Control. So, you might be further ahead to use the With / End With around the ListView. Any time you can use With and End with, you prevent the program from having to reload an object. So try to use these whenever you can to improve program efficiency.

Other than that, you could call Windows API's for the ListView Control, and allocate memory on the heap bypassing VB6's ListView control.

Thank you!..

Ive been searcing for the API you have mentioned and I think here it is:

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const LB_FINDSTRING = &H18F

But how to incorporate this to the function above?

Thank you!

No, the SendMessage API is used to send a message to the Windows Procedure of a window. In VB6, you're kind of limited as to what messages you receive unless you subclass the window procedure, which is probably something you don't want to get into. It's not too stable in the VB6 environment. But to use that you need to use the GetWindowLong API to obtain an address to the Window Procedure, and then you have to intercept the messages in your own window procedure, transfer the messages back to the orignal procedure, etc.

In the process, your VB6 environment crashes 10 or 20 times before it starts to work. And then maybe it works. Maybe. But if does start to work, then .............

But The SHAutoComplete API mentioned in the link you gave is for filesystems and URL's and is found in the shlwapi dynamic link library. But you want auto completion to work based on a result from a SQL search into a recordset.


But what you're asking for is something that you have not supplied any attempted code for.

Let's see what you've got.

Well, maybe that SendMessage will work. A listview is a window. And it looks like someone has figured out how to use it in VB6 on that link.

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const LB_FINDSTRING = &H18F
Private Sub Text1_Change()
    'Retrieve the item's listindex
    List1.ListIndex = SendMessage(List1.hwnd, LB_FINDSTRING, -1, ByVal CStr(Text1.Text))
   
    'If something was chosen then we get the rest of it
    If List1.ListIndex <> -1 Then
        strt = Len(Text1.Text)
        Text1.Text = List1.List(List1.ListIndex)
        Text1.SelStart = strt
        Text1.SelLength = Len(Text1.Text) - strt
    End If
End Sub

Doing it the way illustrated at the link you mentioned, you'll first need to populate a list box. Or whatever control you want that can handle lists. And then you just need to send it a string parameter telling it what item to show up in the list control. But you still have to supply some code for how that's done.

Thank you!

But how to do this using listview?..However, Is this the fastest way to autocomplete listview items via the user entry in a textbox??

Well, you have to understand the LB_FINDSTRING is a constant that applies to a listbox control. So, you can send that message to a listbox control and it should work.

But you want something that works with a listview control:

More than likely this is the constant you are looking for:
LVM_FINDITEM SendMessage(ListView1.hWnd, LVM_FINDITEM, -1, ByVal(Cstr(Text1.Text)) The 1st parameter asks for the handle of the window, the second the message constant, and the third asks for what position to start at(-1 means the beginning), and the fourth is the text you want to search for).

You can find a list of messages that apply to the ListView from the Current Platform SDK. You can do a search in the MSDN Library with the following words: List View Messages (Windows).

There are about 49 or 50 messages you can send to a ListView control. They all start with LVM_--which is probably an acronym for List View Message.

And you will need to define the value of the LVM_FINDITEM or the constant you want to use. You can use a text editor to search for the value: open up the commctrl.h header file found in the include directory of the Platform SDK, or you can find that file in the VC\Inlcude directory, if you have a copy of VC++ installed somewhere. They usually list the values for the constants inside these header files.

Something like #define LVM_FINDITEM 0x00008000 Which means it has a hexadecimal value of &h8000& in VB6 language. Const LVM_FINDITEM = &h8000& That's just an example. I don't know what the value is. You'll have to look it up.

Well, you have to understand the LB_FINDSTRING is a constant that applies to a listbox control. So, you can send that message to a listbox control and it should work.

But you want something that works with a listview control:

More than likely this is the constant you are looking for:
LVM_FINDITEM SendMessage(ListView1.hWnd, LVM_FINDITEM, -1, ByVal(Cstr(Text1.Text)) The 1st parameter asks for the handle of the window, the second the message constant, and the third asks for what position to start at(-1 means the beginning), and the fourth is the text you want to search for).

You can find a list of messages that apply to the ListView from the Current Platform SDK. You can do a search in the MSDN Library with the following words: List View Messages (Windows).

There are about 49 or 50 messages you can send to a ListView control. They all start with LVM_--which is probably an acronym for List View Message.

And you will need to define the value of the LVM_FINDITEM or the constant you want to use. You can use a text editor to search for the value: open up the commctrl.h header file found in the include directory of the Platform SDK, or you can find that file in the VC\Inlcude directory, if you have a copy of VC++ installed somewhere. They usually list the values for the constants inside these header files.

Something like #define LVM_FINDITEM 0x00008000 Which means it has a hexadecimal value of &h8000& in VB6 language. Const LVM_FINDITEM = &h8000& That's just an example. I don't know what the value is. You'll have to look it up.

Thank you for this solution..It should work..I'll post the result here after the test..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.