Um modo melhor de levantar os itens selecionados numa listbox de múltipla seleção

Normalmente, o que se faz para levantar os itens de uma listbox de múltipla seleção é percorrer um a um todos os seus itens e testar pelo valor da propriedade Selected de cada um deles. Como uma forma mais rápida e elegante de realizar esta tarefa, você pode usar a função SendMessage da API.

Declare-a da seguinte forma em um módulo padrão:

Public Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg _
As Long, ByVal wParam As Long, lParam As Any) As Long
 

Para enviar uma mensagem que nos retorne todos os itens selecionados de uma listbox precisaremos declarar o identificador da mensagem que usaremos para isto:

Public Const LB_GETSELITEMS = &H191

Em essência, a mensagem LB_GETSELITEMS preenche uma matriz com todos os índices dos itens selecionados na listbox para a qual a mensagem é enviada. Para enviar a mensagem, você precisa passar mais dois argumentos em SendMessage. Um para o número máximo de itens selecionados. Passe o valor da propriedade ListCount do listbox. O outro é a variável matriz que será preenchida com os números de índice dos itens selecionados. Veja abaixo um exemplo de como fazer isto:

Dim ItemIndexes() As Long, x As Integer, iNumItems As Integer
iNumItems = ThisBox.SelCount
If iNumItems Then
    ReDim ItemIndexes(iNumItems - 1)
    SendMessage ListBox1.hwnd, LB_GETSELITEMS, iNumItems, _
    ItemIndexes(0)
End If
For x = 0 To iNumItems - 1
    MsgBox ListBox1.List(ItemIndexes(x))
Next x

Após ter sido passada para a função SendMessage, a variável iNumItems contém o número total de itens selecionados e a a matriz ItemIndexes contém os índices dos itens selecionados. Note que você precisa passar um ponteiro para a matriz ItemIndexes e não a matriz em si. Assim, você passa ItemIndexes(0) na função SendMessage, não ItemIndexes(). O endereço do primeiro elemento de uma matriz é sempre o endereço da matriz.