Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Listbox.List only takes integer but listbox can have more items

133 views
Skip to first unread message

Thomas Schoch

unread,
Nov 9, 1999, 3:00:00 AM11/9/99
to
I have added 100'000 items to a listbox but can only retrieve up to
listindex 32767.
How can I retrieve the other items?
Seems strange that I can add more entry than I can retrieve!

Thomas

Timo Jokinen

unread,
Nov 9, 1999, 3:00:00 AM11/9/99
to
standard listbox cannot hold 100 000 items..

u can test it with this code snippet:

Private Sub Command1_Click()
Dim i As Long
On Error GoTo out
For i = 1 To 40000
List1.AddItem "Rivi " & i
Next
Exit Sub

out:
MsgBox "Last item added was " & i - 1 & vbCrLf & Error$ & vbCrLf &
"Error # " & Err

End Sub

Propably u have a third part listbox -control or then your code have
something like "On Error Resume Next" ;)

tim

Thomas Schoch

unread,
Nov 9, 1999, 3:00:00 AM11/9/99
to
Your certainly can add 100'000 items to a listbox in VB6.
ListCount then returns something like -31072.

Thomas Schoch

On Tue, 09 Nov 1999 08:02:42 GMT, Timo Jokinen <timo.j...@posti.fi>
wrote:

Timo Jokinen

unread,
Nov 10, 1999, 3:00:00 AM11/10/99
to
Can u post a piece of your code where u add 100'000 items
to listbox -control. I cannot do it myself with VB6.0 Professional

Tim

Thomas Schoch

unread,
Nov 10, 1999, 3:00:00 AM11/10/99
to
No problem, here it is:

Dim lngAdd As Long

MousePointer = vbHourglass
For lngAdd = 1 To 100000
List1.AddItem CStr(lngAdd)
Next
MousePointer = vbDefault

Thomas Schoch


On Wed, 10 Nov 1999 10:22:37 GMT, Timo Jokinen <timo.j...@posti.fi>

Peter Mundy

unread,
Nov 10, 1999, 3:00:00 AM11/10/99
to
Visual Basic Enterprise 6.0 SP3, Windows 95:

MousePointer = vbHourglass
List1.Clear


For lngAdd = 1 To 100000
List1.AddItem CStr(lngAdd)
Next
MousePointer = vbDefault

As expected, Run-time error '5': Invalid procedure call or argument. lngAdd
= 32,768.


Read the Microsoft documentation:

LB_INSERTSTRING

wParam = (WPARAM) index; // item index
lParam = (LPARAM) (LPCTSTR) lpsz; // address of string to insert

Parameters

index

Value of wParam. Specifies the zero-based index of the position at which to
insert the string. If this parameter is -1, the string is added to the end
of the list.

Windows 95/98: 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.


Peter


Thomas Schoch <to...@elephant.ch> wrote in message
news:382b8774....@msnews.microsoft.com...

Thomas Schoch

unread,
Nov 11, 1999, 3:00:00 AM11/11/99
to
You're correct when looking at Win95/98. I've always tested this on a
NT machine.

Thomas

Peter Mundy

unread,
Nov 11, 1999, 3:00:00 AM11/11/99
to
Take a look at the ListBox in the Microsoft Visual Basic 6.0 SP3 Object
Browser:

Class ListBox
Member of VB
Displays a list of items from which the user can select one or more.

Property Index As Integer
read-only
Member of VB.ListBox
Returns/sets the number identifying a control in a control array.

Property ListCount As Integer
read-only
Member of VB.ListBox
Returns the number of items in the list portion of a control.

Property ListIndex As Integer
Member of VB.ListBox
Returns/sets the index of the currently selected item in the control.

Property NewIndex As Integer
read-only
Member of VB.ListBox
Returns the index of the item most recently added to a control.

Property SelCount As Integer
read-only
Member of VB.ListBox
Returns the number of selected items in a ListBox control.

Property TopIndex As Integer
Member of VB.ListBox
Returns/sets which item in a control is displayed in the topmost
position.


And, read the Microsoft Visual Basic 6.0 documentation:

Integer Data Type

Integer variables are stored as 16-bit (2-byte) numbers ranging in value
from -32,768 to 32,767.


Now, let's go back to two of your earlier messages:

> I have added 100'000 items to a listbox but can only retrieve up to
> listindex 32767.
> How can I retrieve the other items?
> Seems strange that I can add more entry than I can retrieve!

and

> Your certainly can add 100'000 items to a listbox in VB6.
> ListCount then returns something like -31072.

It never worked in Visual Basic 6.0 under NT either!


In computer programming, it's fallacious to assume that if no error is
thrown then something worked.

Peter


Thomas Schoch <to...@elephant.ch> wrote in message

news:382d6c45....@msnews.microsoft.com...

Randy Birch

unread,
Nov 12, 1999, 3:00:00 AM11/12/99
to
Sorry .. you can add 100k items to a VB listbox on NT.

item 32768, listindex = 32767
item 32769, listindex = -32768

item 65536, listindex = -1
item 65537, listindex = 0
item 65538, listindex = 1

item 100000, listindex = -31073

Actually, i just added half a million items to the VB listbox using the code
below, no problem other than the time it took.

Option Explicit

Private Sub Command1_Click()

Dim i As Long

List1.Visible = False

For i = 1 To 500000


List1.AddItem "Rivi " & i
Next

List1.Visible = True

End Sub

Private Sub Command2_Click()
Form1.Cls
End Sub

Private Sub List1_Click()

Print List1.ListIndex

End Sub

--

Randy Birch, MVP Visual Basic

http://www.mvps.org/vbnet/
http://www.mvps.org/ccrp/
news:/news.mvps.org/

Please correspond only using the newsgroups so all can benefit.


Peter Mundy <pmu...@pipeline.com> wrote in message
news:80efer$t8$1...@nntp4.atl.mindspring.net...

Jim Deutch

unread,
Nov 12, 1999, 3:00:00 AM11/12/99
to
Randy Birch wrote in message ...

>Sorry .. you can add 100k items to a VB listbox on NT.
>
>item 32768, listindex = 32767
>item 32769, listindex = -32768
>
>item 65536, listindex = -1
>item 65537, listindex = 0
>item 65538, listindex = 1


Hmm, I could deal with negative numbers, but those last three lines kinda
present a problem, don't they? <g>

Jim Deutch
MS Dev MVP

Peter Mundy

unread,
Nov 12, 1999, 3:00:00 AM11/12/99
to
Randy Birch, MVP Visual Basic:


In your empirical test you actually disproved your case.


To understand what is going on, we have to understand at least a little
about hardware, assembly language, C or C++, operating system design,
implementation and programming, programming language design and
implementation, and compiler design, implementation and programming. While
Microsoft does not make it's source code generally available, using the
literature and widely available source code from other operating systems,
languages, and compilers, we can make some reasonable inferences as to how
Microsoft Visual Basic is implemented.


Mathematically, a sixteen digit binary number can represent (2 ^ 16) or
65,536 distinct values. In a digital computer, there are several ways we can
use the 65,536 distinct values represented by sixteen bits. We could choose
to represent zero and a subset of positive integers, commonly unsigned
16-bit integers from zero to (2 ^ 16 - 1) or +65,535. We could also choose
to represent zero and a subset of positive and negative integers, commonly
signed 16-bit integers from -(2 ^ !5) or -32,768 to +(2 ^ 15 -1) or +32,767
and typically implemented using the high order bit as a sign bit and two's
complement binary arithmetic. In both these cases, there is a one to one
mapping between the range of integers and the distinct values represented by
16-bits.

We can apply the same reasoning to 32-bit integers, commonly unsigned zero
to (2 ^ 32 - 1) and signed -(2 ^ 31) to +(2 ^ 31 - 1).

The distinct values can also be used in other ways, for example floating
point. In floating point arithmetic we increase the range of numbers
represented but, since there are the same number of distinct values, we have
to sacrifice something i.e. accuracy. There is now a many to one mapping
between the values in the range represented and the actual bit
representation.


If you carefully read through my two earlier messages (embedded in this
message) you will see that the Visual Basic Listbox object model defines
index values a sixteen bit signed integers for both Windows 9x and NT.


The Microsoft Visual Basic documentation for the ListBox AddItem method that
you used.to "add" 500,000 items:

AddItem Method

Adds an item to a ListBox control.

Syntax

object.AddItem item, index

index Optional. Integer specifying the position within the object where the
new item or row is placed. For the first item in a ListBox control, index is
0.

Remarks

If you supply a valid value for index, item is placed at that position
within the object. If index is omitted, item is added at the proper sorted
position (if the Sorted property is set to True) or to the end of the list
(if Sorted is set to False).


You used the statement:

List1.AddItem "Rivi " & i

to add items to your list. Since you didn't specify an index, the ListBox
relies on the Windows API for the ListBox to assign the index value. From my
earlier messages, you can see that that's unlikely to cause a problem for
NT. Whether it uses a signed or unsigned 32-bit integer for the index value,
500,000 is not going to cause a problem. Your test would also have been more
interesting if you had provided an index value and also taken a look at
the ListBox NewIndex value . It would also have been more convenient to
interpret your output if you had started your loop at zero to match the
lower bound of index values.


You did, however give us the ListBox ListIndex values for some values i.e.

item 32768, listindex = 32767
item 32769, listindex = -32768
item 65536, listindex = -1
item 65537, listindex = 0
item 65538, listindex = 1

item 100000, listindex = -31073

Now let's draw on our knowledge and experience of writing operating system
components, compilers, etc and we can easily see a pattern. Unlike the
Visual Basic conversions, by design, C and C++ are more flexible and
tolerant of variations in hardware arithmetic implementations and data type
coercion. Item string "Rivi 32769" with an index of 32768 (your string index
starts at one but the ListBox index starts at zero) gives a ListIndex value
of -32768. Consider a 32-bit integer value of 32,768 which gives us the bit
pattern in hexadecimal of &H00008000. If we copy that value to a 16-bit
signed integer without type checking, the bit pattern is interpreted as
&H8000 or -32,768. Similarly, Item string "Rivi 65536" with an index of
65535 is &H0000FFFF which is converted to &HFFFF or -1. And for Item string
"Rivi 65537" with an index of 65536 is &H00010000 which is converted to
&H0000 or 0. And for Item string "Rivi 100000" with an index of 999999 is
&H001869F which is converted to &H869F or -31,073.


But you exclaim, I've still stuffed 100,000 items into a ListBox using
Visual Basic 6.0 and Windows NT, so what's the problem!


To write zero-defect programs we use various software engineering
techniques, including proofs of correctness. It's easy to see what the
problem is. From the Visual Basic 6.0 ListBox object model (embedded in this
message) and your empirical tests, the methods and properties used to
reference and count items in the list use a 16-bit integer data type which
contains, at most, 65,536 distinct values. 65,536 is less than 500,000.
Therefore, we will have no unique references to items in the list and counts
will be unreliable. The index and count values are ambiguous.

In addition, once we exceed 32,768 items in the list, the ListBox API
(embedded in this message) and empirical tests prove that the program is no
longer portable amongst the Windows 32-bit family of operating systems.


To summarize. Even if it "works", what use is it? Why would you want to
exploit anomalies in the current version of an operating system or language
implementation for temporary gain and long term pain? As Steve Ballmer
recently said, Microsoft is suffering real pain from their retreat from
sound software engineering principles. We don't have to follow Microsoft
like lemmings over a cliff.


Peter


Randy Birch <r...@mvps.org> wrote in message
news:OWjwC4NL$GA.251@cppssbbsa04...


> Sorry .. you can add 100k items to a VB listbox on NT.
>
> item 32768, listindex = 32767
> item 32769, listindex = -32768
>
> item 65536, listindex = -1
> item 65537, listindex = 0
> item 65538, listindex = 1
>

Randy Birch

unread,
Nov 12, 1999, 3:00:00 AM11/12/99
to
You are correct on all accounts regarding the numeric representations etc of
the listindex. And it did rightly blow up at 32k+1 when attempting to use
the newindex property to assign itemdata.

My reply was simply in response to these lines:

>> Your certainly can add 100'000 items to a listbox in VB6.
>> ListCount then returns something like -31072.

>It never worked in Visual Basic 6.0 under NT either!

This implied to me that you were stating that it was not possible to add
over 32k items to the listbox under NT, which is wrong from the pure "can it
do it" aspect, but correct from the "is there any point" aspect. Whether or
not the listindex provides any meaningful information was not the issue; the
table I added proved this was in fact the case.

Anthony Jones

unread,
Nov 13, 1999, 3:00:00 AM11/13/99
to
This reply contains nothing useful, sorry. :-)

>To understand what is going on, we have to understand at least a >little
about hardware, assembly language, C or C++, operating >system design,
implementation and programming, programming >language design and
implementation, and compiler design, >implementation and programming.

Yikes, frightening.

>Mathematically, a sixteen digit binary number can represent (2 ^ 16) >or
65,536 distinct values. In a digital computer, there are several >ways we
can use the 65,536 distinct values represented by sixteen >bits. We could
choose to represent zero and a subset of positive >integers, commonly
unsigned 16-bit integers from zero to (2 ^ 16 - 1) >or +65,535. We could
also choose to represent zero and a subset of >positive and negative
integers, commonly signed 16-bit integers from >-(2 ^ !5) or -32,768 to +(2
^ 15 -1) or +32,767 and typically >implemented using the high order bit as
a sign bit and two's
>complement binary arithmetic. In both these cases, there is a one to >one
mapping between the range of integers and the distinct values >represented
by 16-bits.

I'm in awe.

>We can apply the same reasoning to 32-bit integers, commonly >unsigned
zero to (2 ^ 32 - 1) and signed -(2 ^ 31) to +(2 ^ 31 - 1).

Deep stuff, hey Randy did you know that!


No offence Peter but don't you think you ought to give the readers of this
newsgroup a little more credit?

--
Anthony Jones
Secta Group Ltd
Anthon...@msn.com

0 new messages