Как определить элементы списка по координатам
Есть необходимость дать возможность
пользователю выделять каждый элемент в list box
правым кликом. Однако, правый клик не выделяет
автоматически элемент, поэтому необходим другой
способ. Простое считывание значения Y из события
MouseDown и преобразование этого значение в номер
строки работает до тех пор, пока пользователь не
проскроллирует список. Поэтому была
использована API функция SendMessage, которая может
получить информацию из контролов. Итак, давайте
посмотрим на код:
'Declarations section
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
Const LB_GETITEMHEIGHT = &H1A1
'значение высоты одной строки в listbox
'код listbox
Private Sub List1_MouseDown(Button As Integer, Shift As _
Integer, X As Single, Y As Single)
Dim msg As String
Dim TopIndex As Long
Dim CharHeight As Long
Dim CurIndex As Long
With List1
'находим высоту строки в listbox
CharHeight = SendMessage(.hWnd, LB_GETITEMHEIGHT, _
0, 0)
'функция возвращает высоту в пикселях, поэтому конвертируем twips
CharHeight = CharHeight * Screen.TwipsPerPixelY
If Button = 2 Then 'right click
'находим номер элемента, на котором сделали правый клик
CurIndex = Y \ CharHeight + .TopIndex
'если получился допустимый номер, то отображаем информацию
If CurIndex < .ListCount Then
'Code to retrieve and display item definition
'goes here. Mine looks like this.
msg = GetMessage(.List(CurIndex))
frmInfo.Label1.Caption = msg
frmInfo.Show
End If
End If
End With
End Sub
Если элементы списка всегда отображаются в том
же самом порядке, и не происходит удаления, то
всё, что Вам понадобится, это массив определений,
который соответствует каждому элементу в списке.
Чтобы отыскивать соответствующее определение,
используйте следующий код:
msg = DefinitionArray(CurIndex)
После отображения определения в окне, Вам нужен
для события MouseUp в списке:
If Button = 2 Then frmInfo.Hide
|