Visual Basic 6. Руководство разработчика


Использование метода


HitTest

Для работы с различными элементами управления можно использовать метод HitTest, который позволяет обнаруживать объект, заданный координатами точки. Этот метод использовался в проекте LVWDemo (см. гл. 8). Сейчас же рассмотрим метод HitTest подробнее, чтобы увидеть, как он использован совместно с функцией GetCursorPos().

Метод HitTest применяется только по отношению к некоторым элементам управления, являющимся контейнерами. Например, объект

ListView может содер­жать несколько объектов Listltem. Когда пользователь выполняет двойной щелчок в окне объекта ListView, вызывается событие DblClick,

но с его помощью нельзя определить место, где был выполнен щелчок. Чтобы выяснять, на каком именно объекте был выполнен двойной щелчок, следует использовать функцию GetCursorPos(). Она позволяет определить координаты указателя и передать их методу HitTest, который возвратит ссылку на объект, расположенный в указанном месте.

Вернемся к проекту LVWDemo и рассмотрим обработчик события DblClick в объекте ListView. Окно объекта ListView заполнено названиями компаний и связанными с ними данными. Поскольку эти объекты отображаются в виде значков (рис. 13.6), то нужно определить, на каком именно значке был выполнен щелчок (или двойной щелчок). Об отслеживании одиночного щелчка "беспокоится" обработчик события ItemClick,

генерирующий соответствующее сообщение. Обра­ботчик события ItemClick объявляется следующим образом.

Private Sub ListViewl_ItemClick(ByVal Item As ComctLib.Listltem)

Однако обработчик события ItemDblClick отсутствует, вместо него объявлен обработчик события DblClick.

Private Sub ListViewl_DblClick()

Хотя обработчик события DblClick не позволяет получить сообщение об объекте, на котором он выполнен, обычной практикой является использование элемента управления ListView для реакции на двойной щелчок. При этом программа может косвенно обнаруживать объект, на котором выполнен двойной щелчок с помощью функции GetCursorPos() и метода HitTest. Чтобы определить координаты точки, в которой был выполнен двойной щелчок, выполните следующее.






Рис. 13.6. Приложение LVWDemo использование функции GetCursorPos() для получения информации об объекте, на котором выполнен щелчок.

Сначала объявите в модуле функцию GetCursorPos() и структуру данных POINTAPI.

Type POINTAPI

х As Long

у As Long

End Type

Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" _

(IpPoint As POINTAPI) As Long

В обработчике события DblClick необходимо организовать вызов функции GetCursorPosQ, чтобы выяснить координаты указателя в момент выполнения двой­ного щелчка.

GetCursorPos dPoint

Членами структуры dPoint являются координаты Х и Y указателя мыши, выраженные в пикселях в системе координат экрана. Другими словами, если функция GetCursorPosQ вызывается из обработчика события DblClick элемента управления ListView, то в результате она возвращает пару координат. Если после этого пользователь переместит форму (приложение) в другое место экрана, а затем выполнит двойной щелчок на том же значке, то координаты точки, в которой выполняется щелчок, изменятся. Следовательно, необходимо предусмотреть проце­дуру преобразования координат экрана в координаты окна приложения. Для этого нужно вычесть значения свойств Left и Тор окна приложения и элемента управления ListView в этом окне из значений соответствующих координат, возвращаемых функцией GetCursorPos().

X = dPoint.X - Me.Left – ListViewl.Left

Y = dPoint Y - Me.Top – ListViewl.Top

Однако данные действия не вполне корректны, поскольку координаты dPoint. Х и dPoint.Y заданы в пикселях, а все остальные координаты - в твипах (twips). Перед нахождением разности все координаты необходимо преобразовать в пиксели с помощью методов ScaleX и ScaleY. Ниже приведены выражения, позволяющие преобразовать экранные координаты во внутренние координаты элемента управ­ления ListView

Х = dPoint.X - ScaleX(Me.Left + ListViewl.Left,

vbTwips, vbPixels) Y = dPoint.

Y = ScaleY(Me.Top + ListViewl.Top, _

vbTwips, vbPixels)

где Х и Y - координаты указателя в пикселях в момент выполнения двойного щелчка. Координаты (0, 0) соответствуют левому верхнему углу окна приложения. Значения переменных Х и Y должны быть переданы методу HitTest, возвращаю­щему ссылку на объект, на котором выполнен двойной щелчок. Однако для обра­щения к методу HitTest требуется, чтобы координаты были определены в твипах. Вызов метода HitTest показан ниже.



Set LItem = ListViewl.HitTest(ScaleX(X, vbPixels, vbTwips),

ScaleY(Y, vbPixels, vbTwips))

Значения переменных Х и Y сначала преобразуются в твипы, а затем переда­ются методу HitTest. В результате возвращается хранящаяся в переменной LItem ссылка на объект, на котором выполнен двойной щелчок. Эта переменная объяв­ляется как Listitem.

Dim LItem As Listltem

Используя переменную LItem, можно получить доступ к свойствам объекта, на котором был выполнен двойной щелчок. Например, можно организовать подсветку этого элемента непосредственно из программы

LItem.Selected = True

или организовать чтение элементов нижнего уровня как членов семейства.

LItem.ListSubItems

Если двойной щелчок выполнен в пределах элемента управления ListView в месте, не содержащем объектов, то переменная LItem получит значение Nothing. В этом случае попытка обратиться к свойствам элемента управления приведет к ошибке выполнения. Чтобы избежать этого, используйте оператор

On Error Resume Next

и организуйте проверку значения переменной LItem.

On Error Resume Next

Set LItem = ListViewl.HitTest(ScaleX(X, vbPixels, vbTwips), _

ScaleY(Y, vbPixels, vbTwips))

If LItem Is Nothing Then Exit Sub

(набор операторов, обеспечивающих доступ к значениям свойств LItem)

Ниже приведен текст программы обработчика события

DblClick элемента управ­ления ListView. Этот фрагмент программы (без операторов, с помощью которых выполняется обработка членов переменной LItem} можно использовать непосред­ственно в пользовательской программе, если требуется организовать реагирование программы на двойной щелчок на ListView.

Программа 13.8. Обработчик события DblClick элемента управления ListView

Private Sub ListViewl_DblClick()

Dim dPoint As POINTAPI

Dim LItem As Listltem

GetCursorPos dPoint

X = dPoint.X - ScaleX(Me.Left + ListViewl.Left, vbTwips,

vbPixels)

Y = dPoint.Y - ScaleY(Me.Top + ListViewl.Top, vbTwips, vbPixels)

On Error Resume Next

Set LItem = ListViewl.HitTest(ScaleX(X, vbPixels, vbTwips),     _



ScaleY(Y, vbPixels, vbTwips))

If LItem Is Nothing Then Exit Sub

If ListViewl.View = Ivwicon Or ListViewl.View = IvwSmalllcon Then

LItem.Selected = True

msg = LItem.Text & vbCrLf

For i = 1 To LItem.ListSubItems.Count

msg = msg & "   " & LItem.ListSubItems(i).Text & vbCrLf

Next

MsgBox msg

End If

End Sub

Приведенный пример — не единственный способ использования метода HitTest (и даже не самый типичный). Впрочем, этот пример нетривиален, именно поэтому он столь подробно рассматривался. Этот метод был разработан в основном для обработки события DragDrop. Обработчик события DragDrop сообщает координаты точки, в которую помещен объект. Если объект операции перенести-и-оставить (drag-and-drop) находится в окнах элементов управления типа ListView или TreeView, то требуется знать элемент управления, на который был перемещен объект Ниже приведено объявление обработчика события DragDrop.

Private Sub TreeViewl _ DragDrop(Source As Control, x As Single,_

у As Single)

Поскольку координаты точки, в которую перенесен объект, известны, их можно передать в метод HitTest. чтобы выяснить, на какой из элементов управления был перенесен объект. Заметьте: при этом не требуется преобразовывать или пересчи­тывать значения координат, поскольку обработчик события DragDrop возвращает их значения, выраженные во внутренней системе координат (в твипах).


Содержание раздела