Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
_N6_.doc
Скачиваний:
0
Добавлен:
24.04.2019
Размер:
166.91 Кб
Скачать

1.2 Распознавание источника события, нажатых кнопок и клавиш, координат курсора

Во все обработчики событий, связанных с манипуляциями мыши (как и во все другие обработчики) передается параметр Sender типа TObject. Этот параметр содержит указатель на компонент, в котором произошло событие. Он не требуется, если пишется обработчик события для одного конкретного компонента. Однако часто один обработчик применяется для нескольких компонентов. При этом какие-то операции могут быть общими для любых источников события, а какие-то требовать специфических действий. Тогда Sender можно использовать для распознания источника события. Правда, поскольку тип TObject не имеет никаких полезных для пользователя свойств и методов, то объект Sender следует рассматривать как объект одного из производных от TObject типов. Например, если требуется распознать только тип объекта, можно использовать опрацию is. Так оператор

if (Sender is TListBox) then ...

проверяет, не является ли источник события компонентом типа TListBox.

Если требуется распознать объект по имени или другому свойству, можно использовать операцию as. Например, оператор

if (Sender as TControl).Name = 'Editl' then ...

проверяет, не является ли этот компонент компонентом с именем Editl. Впрочем, в данном случае можно было бы просто определить, не является ли Sender объектом Editl:

if (Sender = Editl) then ...

Операцию as можно также использовать, если надо применить к источнику события некоторый метод. Например, оператор

(Sender as TWinControl).ScaleBy(11,10);

увеличивает на 10% размер любого оконного компонента, в котором произошло обрабатываемое событие.

Помимо параметра Sender в обработчики событий OnMouseDown и OnMouseUp передаются параметры, позволяющие распознать нажатую кнопку, нажатые при этом вспомогательные клавиши, а также определить координаты курсора мыши. Заголовок обработчика события OnMouseDown или OnMouseUp может иметь, например, следующий вид:

procedure TForml.EditlMouseDown(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,

ssMiddle, ssDouble);

Элементы этого множества соответствуют нажатию клавиш Shift (ssShift), Alt (ssAlt), Ctrl (ssCtrl), а также кнопок: левой (ssLeft), правой (ssRight), средней (ssMiddle). Информация о нажатых кнопках в параметрах 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)...

Аналогичные параметры Button и Shift передается и в обработчик события OnMouseUp. Отличие только в том, что параметр Button соответствует не нажимаемой в данный момент, а отпускаемой кнопке. Параметр Shift передается также в обработчик события OnMouseMove, так что и в этом обработчике можно определить, какие клавиши и кнопки нажаты.

Во все события, связанные с мышью, передаются также координаты курсора X и Y. Эти параметры определяют координаты курсора в клиентской области компонента. Благодаря этому можно обеспечить различную реакцию в зависимости от того, в какой части клиентской области расположен курсор. Пусть, например, у вас в приложении имеется компонент Image1, содержащий некоторое изображение, и вы хотите обеспечить пользователя соответствующими пояснениями в зави­симости от того, на какую часть изображения он покажет мышью. Это можно сделать, например, следующим образом

Для перехода в режим получения информации можно предусмотреть на форме кнопку или раздел меню, при выборе которых параметру Cursor задается значение crHelp (это соответствует изображению курсора с вопросительным знаком):

procedure TForml.SpeedButton1Click(Sender : TObject);

begin

Cursor := crHelp;

end;

Для отображения информации надо предусмотреть на форме окно редактирования, например, Memo1. В событие OnMouseDown компонента Image1 и формы можно ввести обработчик вида:

procedure TForml.ImagelMouseDown(Sender: TObject;

Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if ((Sender as TControl).Name <> 'Image1') then Cursor := crDefault;

if (Cursor <> crHelp) then exit;

Memol.Lines.Clear;

if (Y < 120)then if (X < 160) then

Memol.Lines.Add('...')

else

if (X < 270) then Cursor := crDefault;

end;

Первые операторы этого обработчика обеспечивают выход из процедуры, если вид курсора не crHelp или щелчок произведен не на изображении. Следующий оператор очищает окно редактирования от прошлой информации, а затем структура if анализирует координаты курсора и в соответствии с областью, в которой находится курсор, отображает ту или иную информацию о частях изображения.

Рассмотрим теперь события OnMouseWheel, OnMouseWheelUp и OnMouseWheelDown, которые введены только в Delphi 5. Эти события связаны с вращением колесика, которое появилось в современных вариантах мыши. Заголовок обработчика события OnMouseWheel имеет вид:

procedure TForml.FormMouseWheel(Sender: TObject;

Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;

var Handled: Boolean);

Параметры Sender и Shift не отличаются от рассмотренных ранее. Параметр WheelDelta показывает, сколько раз повернулось колесико. Это положительное число при вращении вверх и отрицательное — при вращении вниз. Параметр MousePos типа TPoint определяет позицию курсора мыши. А передаваемый по ссылке параметр Handled указывает, завершена ли обработка события.

Если обработчик события OnMouseWheel отсутствует или если в нем задано Handled = false, то, в зависимости от направления вращения колесика, наступает событие OnMouseWheelUp или OnMouseWheelDown. Заголовки обработчиков этих событий одинаковы и имеют вид:

procedure TForml.FormMouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

Они отличаются от обработчика OnMouseWheel только отсутствием параметра WheelDelta.

Многие оконные компоненты — многострочные окна редактирования, списки и т.п. имеют обработчики вращений колесика по умолчанию. Это относится к Memo, RichEdit, ListBox, TrackBar и многим другим. Правда, в некоторых из них, например, в Memo, эти обрабочики по умолчанию будут срабатывать только в том случае, если в компоненте заданы полосы прокрутки (собственно, это обработчики не самих элементов, а полос -прокрутки).

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

procedure TForml.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;

MousePos: TPoint; var Handled: Boolean)

begin -

ScaleBy(100,101)

end;

procedure TForml.FormMouseWheelUp(Sender: TObject;

Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);

begin

ScaleBy(101,100);

end;

то при вращении колесика размеры всех компонентов формы будут плавно умень­шаться или увеличиваться.