Results 1 to 13 of 13

Thread: How do I add combobox items more quickly?

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2017
    Posts
    344

    How do I add combobox items more quickly?

    Hello!

    I need to fill a combobox with 400 items.

    I use

    Me.cboTest.AddItem sSomeString

    Adding a single item takes 1 ms.

    So filling the combobox with 400 items takes 400 ms.

    This is a drastic delay as the form that shows this combobox appears with a delay of 400 ms.

    Is there perhaps an API call to populate a combobox more quickly?

    Or can I prevent it from redrawing? I have tried .Enabled = false and .Locked = true, but that wouldn't change anything.

    Thank you!
    Last edited by tmighty2; Nov 18th, 2021 at 09:16 PM.

  2. #2
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    14,205

    Re: How do I add combobox items more quickly?

    Setting .Visible=False while loading items then back to true once all are loaded should help to some extent.

    Edit: My mistake. No increase on the combo box speed using this trick, likely because the drop down part is not visible until you click on it anyway.

    The 400ms for 400 items seems pretty slow. I wonder what kind of system it is running on and what else if anythign it is doing to get the string that is added that might make it slower. In a test I ran here it easily loads 1000 strings in ~250ms
    Last edited by DataMiser; Nov 18th, 2021 at 09:41 PM.

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2017
    Posts
    344

    Re: How do I add combobox items more quickly?

    Thank you, but it doesn't have any effect for me.
    I have found a replacement for the combobox, so if nothing helps, I can use this one. It's pretty fast.

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: How do I add combobox items more quickly?

    I've never had a problem with AddItem, but here's a way to do it with API calls. There's not going to be anything faster than that.

    EDIT: I just tested that Nirsoft code, and I'm getting about .6 seconds with the VB6 AddItem method and about .4 seconds with the API method. It's a bit better but nothing huge. And again, it's not going to get any better because going to the API is as good as it gets.
    Last edited by Elroy; Nov 18th, 2021 at 09:44 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    14,205

    Re: How do I add combobox items more quickly?

    I edited my post above ^ after testing it here I saw that there was no increase in speed.

  6. #6
    PowerPoster SamOscarBrown's Avatar
    Join Date
    Aug 2012
    Location
    NC, USA
    Posts
    9,145

    Re: How do I add combobox items more quickly?

    Do you REALLY need to put 400 items into a combobox????? I'd hate to be the user who had to scroll to #399!!! There MUST BE some other method to display those items and be made available for selection. Maybe they are numerical, or alphabetical? Then you could simply 'replace' the items in a combobox or listbox or listview as one scrolls the control. Would be a lot faster, I do believe. But even then, 400??? Can you break it down into 'subsections', where maybe something like 10 or 20 items are scrollable in a text box based upon some 'identifier' that could be in a combobox or listbox?
    I've been a software designer, coder AND tester (the latter many years more than the former). In my dealings with software developers, I always look at it from a user's point of view...what makes sense? Is it right? Does it LOOK good? Do I have to jump through hoops to get a simple task done. I definitely would not be pleased if someone gave ME a combobox with 400 items in it. Anyway....if you continue in this vein and can't speed up your process, present something else to the user while your combobox is loading...to the user, then, that loading process is never even noticed. Just a thought.
    Sam I am (as well as Confused at times).

  7. #7
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: How do I add combobox items more quickly?

    So maybe something like:

    Code:
    Option Explicit
    
    Private Const ITEM_COUNT As Long = 1000
    
    Private Const CB_ADDSTRING As Long = &H143&
    Private Const CB_INSERTSTRING As Long = &H14A&
    Private Const CB_INITSTORAGE As Long = &H161&
    
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
        ByVal hWnd As Long, _
        ByVal wMsg As Long, _
        ByVal wParam As Long, _
        ByVal lParam As Long) As Long
    
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" ( _
        ByRef Frequency As Currency) As Long
    Private Declare Function QueryPerformanceCounter Lib "kernel32" ( _
        ByRef PerformanceCount As Currency) As Long
    
    Private mFrequency As Currency
    
    Private Function GetTicks() As Double
        'Returns a time in seconds.
        Dim PerformanceCount As Currency
    
        If mFrequency < 0 Then
            'Not supported, substitute:
            GetTicks = CDbl(GetTickCount()) / 1000
        Else
            QueryPerformanceCounter PerformanceCount
            GetTicks = CDbl(PerformanceCount) / mFrequency
        End If
    End Function
    
    Private Sub TicksInit()
        If mFrequency = 0 Then If QueryPerformanceFrequency(mFrequency) = 0 Then mFrequency = -1
    End Sub
    
    Private Sub Form_Load()
        Dim Items() As String
        Dim I As Long
        Dim SpaceReqd As Long
        Dim Secs As Double
    
        'Make up some text to squirt into Combo1's item list.
        'We store preconverted ANSI here to save time:
        ReDim Items(ITEM_COUNT - 1)
        For I = 0 To ITEM_COUNT - 1
            Items(I) = StrConv(Format$(I, "0000 ") _
                             & MonthName(I Mod 12 + 1) & " " _
                             & CStr(Rnd() * 10000&), _
                               vbFromUnicode)
            SpaceReqd = SpaceReqd + LenB(Items(I)) + 1
        Next
    
        TicksInit
        Secs = GetTicks()
        SendMessage Combo1.hWnd, CB_INITSTORAGE, ITEM_COUNT, SpaceReqd
        For I = 0 To ITEM_COUNT - 1
            SendMessage Combo1.hWnd, CB_INSERTSTRING, I, StrPtr(Items(I))
            'Or if Combo1.Sorted = True then use:
            'SendMessage Combo1.hWnd, CB_ADDSTRING, 0, StrPtr(Items(I))
        Next
        Secs = GetTicks() - Secs
    
        MsgBox "Items: " & Format$(ITEM_COUNT, "#,##0") _
             & vbNewLine & vbNewLine _
             & "Total: " & Format$(Secs, "#,##0.000000") _
             & vbNewLine & vbNewLine _
             & "Per item: " & Format$(Secs / ITEM_COUNT, "#,##0.000000")
    End Sub
    My results, IDE run, fairly slow PC by current standards:

    Code:
    ---------------------------
    Project1
    ---------------------------
    Items: 1,000
    
    Total: 0.084233
    
    Per item: 0.000084
    ---------------------------
    OK   
    ---------------------------

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: How do I add combobox items more quickly?

    I also went back and added CB_SETITEMDATA messages to populate ItemData. Hardly increased the time much at all.

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2017
    Posts
    344

    Re: How do I add combobox items more quickly?

    I have found the perfect solution:

    http://www.vbaccelerator.com/home/VB...x/article.html

    It is ultra fast (500 items took 9 ms), and its methods and properties are just like the standard VB6 combobox.

  10. #10
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: How do I add combobox items more quickly?

    I went back once more and replaced the SendMessageA() by SendMessageW() calls and passed in Unicode text.

    Slightly slower letting the conversion happen in the control itself, but still not bad.

  11. #11
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: How do I add combobox items more quickly?

    I decided to dig into this a little. I started by adding 40000 items to a ComboBox in VB6. This takes almost 6 seconds. I then decided to do the same test in VB.Net which also took around 6 seconds. However, in .Net the ComboBox's Items property has an AddRange method which allows you to add multiple items at once using an array. Surprisingly when I used AddRange, it took around 1.5 seconds, that's around 4 times faster! I then decided to dig deeper by looking at the source code for the AddRange method in the .Net Framework. I noticed a call to BeginUpdate before the items were added and a call to EndUpdate after the items were added. When I dug deeper, I found calls to SendMessage that prevented redrawing of the ComboBox while items were being added. I decided to do the same thing in VB6 and it boosted the performance by a factor of 3!

    Here is the full VB6 code:-
    Code:
    Const WM_SETREDRAW = &HB
    
    Private Declare Function SendMessageW Lib "User32.dll" (ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    Private g_items() As String
    
    Const ITEMCOUNT = 40000
    Private Sub Form_Load()
        g_items = CreateItems
        
        
        TestNormal
        TestRedrawOff
    End Sub
    
    Private Sub TestNormal()
        Combo1.Clear
    
        t = Timer
        
        For i = LBound(g_items) To UBound(g_items)
            Combo1.AddItem g_items(i)
        Next
        
        Debug.Print "With redraw on: " & CStr(Timer - t)
    End Sub
    
    Private Sub TestRedrawOff()
        Combo1.Clear
        
        t = Timer
        
        BeginUpdate
        
        For i = LBound(g_items) To UBound(g_items)
            Combo1.AddItem g_items(i)
        Next
        EndUpdate
        
        Debug.Print "With redraw off: " & CStr(Timer - t)
    End Sub
    
    Private Sub BeginUpdate()
        SendMessageW Combo1.hWnd, WM_SETREDRAW, 0, 0
    End Sub
    Private Sub EndUpdate()
        SendMessageW Combo1.hWnd, WM_SETREDRAW, -1, 0
    End Sub
    
    Private Function CreateItems() As String()
        
        Dim items(1 To ITEMCOUNT) As String
        
        For i = 1 To ITEMCOUNT
            items(i) = "Item " & CStr(i)
        Next
        
        CreateItems = items
    End Function
    The above produces the following output for time measurements on my PC:-
    Code:
    With redraw on: 5.410156
    With redraw off: 1.847656
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2017
    Posts
    344

    Re: How do I add combobox items more quickly?

    Nice find, thank you!

  13. #13
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,997

    Re: How do I add combobox items more quickly?

    Quote Originally Posted by tmighty2 View Post
    Nice find, thank you!
    Yep

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width