|
Der Visual Basic-ListBox fehlt eine Möglichkeit festzustellen, welcher Listeneintrag sich gerade unter dem Mauszeiger befindet. Die über die API-Funktion SendMessage an die ListBox gesendete Nachricht LB_ITEMFROMPOINT liefert Ihnen aber die gewünschte Information. Da die Übergabe der Koordinaten und die Auswertung des Rückgabewertes nicht ganz Visual Basic-konform sind, packen wir den Aufruf in die Hilfsfunktion ListBoxHitTest. Sie übergeben dieser Funktion die betreffende ListBox und die X- und Y-Koordinaten, wie sie Ihnen von den Maus-Ereignissen der ListBox (MouseDown, MouseMove und MouseUp) geliefert werden. Sie gibt Ihnen den Index des Listeneintrags zurück, der sich unter dem Mauszeiger befindet, oder den Wert -1, wenn sich der Mauszeiger über leerem Raum in der ListBox befindet.
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
Public Function ListBoxHitTest(ListBox As ListBox, _
ByVal X As Single, ByVal Y As Single) As Long
Dim nIndex As Long
Const LB_ITEMFROMPOINT = &H1A9
nIndex = SendMessage(ListBox.hWnd, LB_ITEMFROMPOINT, 0, _
(Y \ Screen.TwipsPerPixelY) * 65536 + (X \ Screen.TwipsPerPixelX))
If (nIndex And &H10000) = &H10000 Then
ListBoxHitTest = -1
Else
ListBoxHitTest = nIndex
End If
End Function
In einem der Mausereignisse prüfen Sie dann nur noch, ob -1 oder ein gültiger Index zurückgegeben wurde. Anhand des Index-Wertes können Sie nun wie gewohnt den betreffenden Listeneintrag ermitteln:
Private Sub List1_MouseMove(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
Dim nIndex As Long
nIndex = ListBoxHitTest(List1, X, Y)
If nIndex >= 0 Then
Debug.Print List1.List(nIndex)
End If
End Sub
Da die FileListBox eigentlich nichts anderes als eine ListBox ist, können Sie die gleiche Funktion im Prinzip auch für diese verwenden. Sie brauchen lediglich den Datentyp zur Übergabe der FileListBox anzupassen:
Public Function FileListBoxHitTest(FileListBox As FileListBox, _
ByVal X As Single, ByVal Y As Single) As Long
Dim nIndex As Long
nIndex = SendMessage(FileListBox.hWnd, LB_ITEMFROMPOINT, 0, _
(Y \ Screen.TwipsPerPixelY) * 65536 + (X \ Screen.TwipsPerPixelX))
If (nIndex And &H10000) = &H10000 Then
FileListBoxHitTest = -1
Else
FileListBoxHitTest = nIndex
End If
End Function
|