How to calculate Listbox limits?

Hi, I am using a listbox in my program to show a lot of strings so of course I would like to know about the limits of a listbox.

Now I already searched around for it (the number of rows it can have and the width of the strings that are added to each row) but I couldn't find anything helpful.
However I read once or twice that a listbox has no fixed limits but is somehow calculated with the length of each row and all rows together, is that true?

If yes I would like to know how to find out these limits because I am adding for example once or twice a string to my listbox that is about 8100 chars long but it doest show up when I send the post message to the listbox so I guess its over the limit.
So I would like to split that string in two or more parts so the whole string can be displayed again and for that I need to know the maximum width of course.

The rows could also become a problem in the future (but so far everthing works here) so I wouldn't hurt if I knew the row limit too so I can delete the first messages again (since they are not that important to keep).
I don't know the limits and I don't recall seeing them in MSDN Online, Windows Controls, Control Library section. But it shouldn't be too hard to make a program to find out.

1. Create a new window or dialog box.
2. Add a list box.
3. To find the maximum number of strings add a FOR loop from 0 to std::numeric_limits<unsigned int>::max() - 1 (#include <limits> to use this) that in turn adds one string per loop. Check the return value of the function SetDlgItemText() or whatever function you use to add the string. If it fails, stop the loop and report the number. If it doesn't fail then you could try a bigger loop, say one from 0 to std::numeric_limits<long long int>::max() - 1. I suspect, however, that the latter will fail for sure. Also note that in Visual studio you might need to change long long int to _int64. Not sure.
4. Repeat the above with another string of different size to see if the number is affected. I am guessing it is not.
5. To find out the maximum string value, use a similar FOR loop, but instead of adding multiple strings, each loop iteration will remove the previous string and then will add a new, larger string. The string would increase one character per iteration until it fails or the loop completes.
6. Repeat the above with a variable number of lines to see if that affects the maximum string length.
Ok I will try that.

However if the limits are really a combination of the number of rows and the string width then will this help me in any way? Because then I would only know the maximum number of rows for a minimal string width and the maximum string width for a minimal number of rows.

Also I found out something interesting:
I previously said that when I add a long string (8100 chars) to the listbox it doesn't get displayed so I automatically assumed it was exceeding the limits of the listbox.
(btw I am using SendMessage(listBoxWnd, LB_ADDSTRING, NULL, (LPARAM)msg) to send the string to the listbox)
Now if you take a look into MSDN at the LB_ADDSTRING message (http://msdn.microsoft.com/en-us/library/windows/desktop/bb775181%28v=vs.85%29.aspx) it clearly says:
The return value is the zero-based index of the string in the list box. If an error occurs, the return value is LB_ERR. If there is insufficient space to store the new string, the return value is LB_ERRSPACE.

So if there is really a problem with the limits, SendMessage would return either one of those messages, right? (probably the latter one)
But this isn't the case, after I sent the string the return value is still the index number of the listbox.

So this leads me to the question, is this even a listbox problem?
If not then whats the problem here?
Show the definition of the variable 'msg' and how you fill that variable with the text.
msg is defined as char* msg as a parameter of a function. The creation of the message is rather extensive so I would rather not try to post it here.

Just a quick insertion here: I am always automatically selecting the next added string in the listbox so he would automatically scroll down as more messages appear.

So I found out another thing:
I tried limiting the string to a certain length and he showed it again with an approximate length of 4800 chars. But as I tried a little higher values he sometimes showed the string and sometimes not.
After some more inspection it seems to me that he doesnt display the string when the message LB_ADDSTRING took too long and LB_SETCURSEL has been called in the meantime (this selects the posted string).

So I think I have two options here:
- I read about LB_INITSTORAGE to allocate some memory so the listbox loads the elements faster (http://msdn.microsoft.com/en-us/library/windows/desktop/bb761319%28v=vs.85%29.aspx). But would this help here? I dont even know if this is also meant to be used for strings (though characters are also elements that are added to the listbox so I guess yes).
Btw there is also an interesting mention about the listbox limits
Windows 95/Windows 98/Windows Millennium Edition (Windows Me) : The wParam parameter is limited to 16-bit values. This means list boxes cannot contain more than 32,767 items. Although the number of items is restricted, the total size in bytes of the items in a list box is limited only by available memory.
So I guess in newer System wParam is limited to 32bit or higher so the number of items would be (2^32)/2 items?

- cut off the strings in some parts so they are displayed again without any time delay


I will try LB_INITSTORAGE first but I am unsure about the size I should allocate. What would be a good value to start with?
Last edited on
Most likely the current limit of entries is 232 -1 if you use an unsigned integer.

I have never used LB_INITSTORAGE so I don't know if it helps. Try it out. I don't have a good estimate for you to start testing, though.

But there is something that confuses me: You keep saying you "post the message", and that in programming has a very specific meaning: You are sending the message and forgetting about it, usually meaning you are either sending the message in a different thread or using PostMessage(). You said you use SendMessage(), so my question would be: Are you using multiple threads? The use of multiple threads is tricky and I don't know if you know how to properly use threads. For example, the data used in SendMessage() in a separate thread must have available all data during the course of the thread execution, including the contents of msg. I wonder if your inconsistent results are because sometimes when the time comes to add the string, some other thread has deleted the memory allocated for msg.
Actually I am using two threads that (I think^^) are moreless independent from each other (at least in terms of posting messages to the listbox).
I am using the listbox for logging so whenever something specific happens in a thread I define the message in the thread and pass it to the function that sends the message to the listbox window.

To be honest I really dont have much experience with threads but so far everything works as expected. I know that I shouldn't really use threads if I dont know much about them but I also can't really learn anything thread related if I keep ignoring them.

Anyway, thanks (again) for your help.
Last edited on
I see. Your description then sounds like you may sometimes have a race condition. Use PostMessage() instead of SendMessage() but you must make sure that the memory allocated for msg remains valid until the message is processed by the GUI thread, or continue your use of SendMessage but use a CRITICAL_SECTION or semaphore synchronization object to serialize the threads when the time comes to send the message.
Topic archived. No new replies allowed.