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

    На этом шаге мы продолжим рассматривать события, связанные с мышью.

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

   if (Sender  is  TListBox) then ...
проверяет, не является ли источник события компонентом типа TListBox.

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

   if (Sender as  TControl).Name  =  'Edit1' then ...
проверяет, не является ли этот компонент компонентом с именем Edit1. Впрочем, в данном случае можно было бы просто определить, не является ли Sender объектом Edit1:

   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 анализирует координаты курсора и в соответствии с областью, в которой находится курсор, отображает ту или иную информацию о частях изображения.

    На следующем шаге мы рассмотрим события, связанные с клавиатурой.




Предыдущий шаг Содержание Следующий шаг