На этом шаге мы продолжим рассматривать события, связанные с мышью.
Во все обработчики событий, связанных с манипуляциями мыши (как и во все другие обработчики) передается параметр Sender типа TObject. Этот параметр содержит указатель на компонент, в котором произошло событие. Он не требуется, если пишется обработчик события для одного конкретного компонента. Однако часто один обработчик применяется для нескольких компонентов. При этом какие-то операции могут быть общими для любых источников события, а какие-то требовать специфических действий. Тогда Sender можно использовать для распознавания источника события. Правда, поскольку тип TObject не имеет никаких полезных свойств и методов, то объект Sender следует рассматривать как объект одного из производных от TObject типов. Например, если требуется распознать только тип объекта, можно использовать опрацию is. Так оператор:
if (Sender is TListBox) then ...
Если требуется распознать объект по имени или другому свойству, можно использовать операцию as. Например, оператор:
if (Sender as TControl).Name = 'Edit1' then ...
if (Sender = 'Edit1') then ...
Операцию as можно также использовать, если надо применить к источнику события некоторый метод. Например, оператор:
(Sender as TWinControl).ScaleBy(11,10);
увеличивает на 10% размер любого оконного компонента, в котором произошло обрабатываемое событие.
Помимо параметра Sender в обработчики событий OnMouseDown и OnMouseUp передаются параметры, позволяющие распознать нажатую кнопку, нажатые при этом вспомогательные клавиши, а также определить координаты курсора мыши. Заголовок обработчика события OnMouseDown или OnMouseUp может иметь, например, следующий вид:
procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Помимо уже рассмотренного параметра Sender в обработчик передаются параметры Button, Shift, X и Y.
Параметр Button типа TMouseButton определяет нажатую в этот момент кнопку мыши. Тип TMouseButton - перечислимый тип, определяемый следующим образом:
TMouseButton = (mbLeft, mbRight, mbMiddle);
Значение mbLeft соответствует нажатию левой кнопки мыши, значение mbRight - правой, а значение mbMiddle - средней. Например, если вы хотите, чтобы обработчик реагировал на нажатие только левой кнопки, вы можете его первым оператором написать:
if (Button <> mbLeft) then exit;
Тогда, если значение Button не равно mbLeft, т.е. нажата не левая кнопка, выполнение обработчика прервется.
Параметр Shift типа TShiftState определяет, какие вспомогательные клавиши на клавиатуре нажаты в момент нажатия кнопки мыши. Тип TShiftState - множество, определенное следующим образом:
TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight,
ssMiddie, ssDouble);
Элементы этого множества соответствуют нажатию:
Информация о нажатых кнопках в параметрах Button и Shift имеет различный смысл. Параметр Button соответствует кнопке, нажимаемой в данный момент, а параметр Shift содержит информацию о том, какие кнопки были нажаты; включая и те, которые были нажаты ранее. Например, если пользователь нажмет левую кнопку мыши, а затем, не отпуская ее, нажмет правую, то после первого нажатия множество Shift будет равно [ssLeft], а после второго - [ssLeft, ssRight]. Если до этого пользователь нажал и не отпустил какие-то вспомогательные клавиши, то информация о них также будет присутствовать в множестве Shift.
Поскольку Shift является множеством, проверять наличие в нем тех или иных элементов надо операцией in. Например, если вы хотите прореагировать на событие, заключающееся в нажатии левой кнопки мыши при нажатой клавише Alt, можно использовать оператор:
if (Button = mbLeft) and (ssAlt in Shift) then ...
В приведенной структуре if первое условие (Button = mbLeft) можно заменить эквивалентным ему условием, проверяющим параметр Shift:
if (ssLeft in Shift) then . . . ;
Аналогичные параметры Button и Shift передаются и в обработчик события OnMouseUp. Отличие только в том, что параметр Button соответствует не нажимаемой в данный момент, а отпускаемой кнопке. Параметр Shift передается также в обработчик события OnMouseMove, так что и в этом обработчике можно определить, какие клавиши и кнопки нажаты.
Во все события, связанные с мышью, передаются также координаты курсора X и Y. Эти параметры определяют координаты курсора в клиентской области компонента. Благодаря этому можно обеспечить различную реакцию в зависимости от того, в какой части клиентской области расположен курсор. Пусть, например, у вас в приложении имеется компонент Image1, содержащий некоторое изображение, и вы хотите обеспечить пользователя соответствующими пояснениями в зависимости от того, на какую часть изображения он покажет мышью. Это можно сделать, например, следующим образом (рисунок 1).
Рис.1. Пример приложения, использующего координаты
мыши
Для перехода в режим получения информации можно предусмотреть на форме кнопку или раздел меню, при выборе которых параметру Cursor задается значение crHelp (это соответствует изображению курсора с вопросительным знаком):
procedure TForm1.Button1Click(Sender: TObject); begin Cursor:=crHelp; end;
Для отображения информации надо предусмотреть на форме окно редактирования, например, Memo1. В событие OnMouseDown компонента Image1 и формы можно ввести обработчик вида:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin //Если это не рисунок, то вернуть курсору обычный вид. if ((Sender as TControl).Name <> 'Image1') then Cursor:=crDefault; //Выйти, если не включен режим помощи. if (Cursor <> crHelp) then exit; Memo1.Lines.Clear; //Очистить Memo-поле. //Вывод соответствующего комментария, если //курсор находится в заданной области рисунка. if (X in [8..89]) and (Y in [3..85]) then Memo1.Lines.Add('База данных приложения.') else if (X in [151..232]) and (Y in [22..68]) then Memo1.Lines.Add('BDE - машина доступа к базе данных фирмы Borland.') else if (X in [114..231]) and (Y in [101..172]) then Memo1.Lines.Add('Приложение, использующее базу данных.'); //Вернуть курсору обычный вид. Cursor:=crDefault; end;
Первые операторы этого обработчика обеспечивают выход из процедуры, если вид курсора не crHelp или щелчок произведен не на изображении. Следующий оператор очищает окно редактирования от прошлой информации, а затем структуpa if анализирует координаты курсора и в соответствии с областью, в которой находится курсор, отображает ту или иную информацию о частях изображения.
На следующем шаге мы рассмотрим события, связанные с клавиатурой.