A user's selection choices in a MultiSelect listbox can be retrieved by iterating through the list's
Selected property. But
when the list contains a large number of items, or doing so must be
done frequently or repeatedly, an applications performance may degrade
when its time is spent looping through the Selected items array.SendMessage
to the rescue! By passing each of two separate messages - LB_GETSELCOUNT and
LB_GETSELITEMS - SendMessage will return an array of Longs populated
with the indices corresponding to the selected items. Looping through this much smaller
array is
considerably faster than going through the entire list and testing each
item's Selected property.
As
usual, the demo comments and debug code below is greater than the
actual routine to this page is demonstrating!. |
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
' applications, but you may not reproduce
' or publish this code on any web site,
' online service, or distribute as source
' on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Const LB_GETSELCOUNT = &H190
Private Const LB_GETSELITEMS = &H191
Private Sub Form_Load()
Dim cnt As Long
For cnt = 0 To 20
List1.AddItem "List item no" & Str$(cnt)
Next
End Sub
Private Sub Command2_Click()
Unload Me
End Sub
Private Sub Command1_Click()
Dim numSelected As Long
Dim cnt As Long
'get the number of items selected.
'If the listbox is single-select style,
'numSelected will return -1 (LB_ERR).
'If the listbox is multiselect style,
'and nothing is selected, numSelected
'returns 0. Otherwise, numSelected returns
'the number selected (ala List1.SelCount)
numSelected = SendMessage(List1.hwnd, _
LB_GETSELCOUNT, _
0&, ByVal 0&)
'debug ...
Picture1.Print numSelected; " items selected:"
Picture1.Print "index", "item"
If numSelected > 0 Then
'dim an array large enough to hold
'the indexes of the selected items
ReDim sSelected(1 To numSelected) As Long
'pass the array so Sendmessage can fill
'it with the selected item indexes
Call SendMessage(List1.hwnd, _
LB_GETSELITEMS, _
numSelected, _
sSelected(1))
'debug ...
'print out the items selected.
'Note that their index is 0-based
For cnt = 1 To numSelected
Picture1.Print sSelected(cnt), List1.List(sSelected(cnt))
Next
End If
End Sub |
With the comments and extraneous code removed, this is the actual call:
Private Sub Command1_Click()
Dim numSelected As Long
Dim cnt As Long
numSelected = SendMessage(List1.hwnd, _
LB_GETSELCOUNT, _
0&, ByVal 0&)
If numSelected > 0 Then
ReDim sSelected(1 To numSelected) As Long
Call SendMessage(List1.hwnd, _
LB_GETSELITEMS, _
numSelected, _
sSelected(1))
For cnt = 1 To numSelected
Debug.Print List1.List(sSelected(cnt))
Next
End If
End Sub |