15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту




Как определить элементы списка по координатам

Есть необходимость дать возможность пользователю выделять каждый элемент в 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