Создание событий компонента

Стандартные события компонентов CLX Kylix мы с вами уже рассматривали в предыдущих главах. В настоящий момент нам предстоит дать четкое определение событию, а также обработчику события.

Итак, событие — это любое действие, произошедшее благодаря операционной системе, действиям пользователя, работе программы.

Событие можно "перехватить" и обработать с помощью программы-обработчика события. Связь между событием и программой-обработчиком называется свойством-событием. Таким образом, когда происходит какое-либо событие компонента, он может обработать данное событие. Для этого сначала проверяется наличие кода обработки события. Если такой код есть — он выполняется.

Рассмотрим в качестве примера такое часто возникающее событие, как нажатие левой кнопки мыши OnClick. Данное событие, как и многие другие, имеет так называемые методы диспетчеризации событий (event-dispatching methods). Такие методы нужны для того, чтобы определять, создан ли код обработки данного события для данного компонента. Эти методы объявляются как защищенные (protected). Таким образом, для свойства OnClick определен метод диспетчеризации события Click (листинг 19.12).

Листинг 19.12. Метод диспетчеризации события

TControl = class (TComponent) 
private
FOnClick: TNotifyEvent; protected
procedure Click; dynamic;
property OnClick: TNotifyEvent read FOnClick write FOnClick; end;
implementation
procedure TControl.Click; begin
if Assigned (FOnClick) then FOnClick (Self); end;

Обратите внимание: свойство OnClick имеет тип TNotifyEvent, который представляет собой процедуру с одним параметром Sender типа TObject:

TNotifyEvent = procedure (Sender: TObject) of object;

Иначе говоря, когда происходит вызов метода Click, осуществляется проверка, ссылается ли FOnClick на какой-либо метод, и если ссылается, то происходит вызов этого метода.

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

При возникновении какого-либо события операционная система передает приложению не только информацию о наступлении данного события, но и некоторую дополнительную информацию. В нашем примере при обработке события нажатия левой кнопки мыши в приложение поступает информация о координатах внутри клиентской части компонента, в которых произошло нажатие левой кнопки мыши. Например, код, приведенный в листинге 19.13, выводит при наступлении события нажатия левой кнопки мыши на форме координаты указателя мыши.

Листинг 19.13.Пример обработки события нажатия кнопки мыши

procedure TForm1. FormMouseDown (Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); begin
Canvas.TextOut(X, Y, '('+IntToStr(X) +', '+IntToStr(Y) + ')'); end;

Данный код мы вписали в обработчик события OnMouseDown формы Form1. Если теперь запустить программу на исполнение и пощелкать мышкой в разных частях формы, в тех местах формы, где происходит щелчок мыши, будут выведены координаты этих точек. Рис. 19.7 наглядно демонстрирует результат работы вышеприведенной программы.

19-10-1.jpg

Рис. 19.7. Результат обработки события OnMouseDown

Пример создания нового события компонента

Попробуем теперь создать собственное событие. Для этого нужно сначала убедиться, что такого события нет в CLX Kylix. Предположим, возникла необходимость создания события, которое генерируется каждые 30 секунд. Естественно, для такого случая можно воспользоваться компонентом Timer, который расположен на вкладке System палитры компонентов Kylix. Но допустим, что наш компонент должен иметь такое событие для удобства работы с ним. Код для создания такого события представлен в листинге 19.14.

Листинг 19.14.Пример создания нового события

unit halfmin; 


interface
uses
SysUtils, Types, Classes, QGraphics, QControls, QForms, QDialogs;
type
TTimeEvent - procedure (Sender: TObject; TheTime: TDateTime) of object;
THalfMinute = class (TComponent)
private
FTimer: TTimer;
FOnHalfMinute: TTimeEvent;
FOldSecond, FSecond: Word; procedure FTimerTimer (Sender: TObject); protected
procedure DoHalfMinute (TheTime: TDateTime); dynamic; public
constructor Create (AOwner: TComponent); override;
destructor Destroy; override; published
property OnHalfMinute: TTimeEvent read FOnHalfMinute write FOnHalf- Minute;
end;
implementation constructor THalfMinute.Create (AOwner: TComponent);
begin inherited Create (AOwner); if not (csDesigning in ComponentState) then begin FTimer:=TTimer.Create(self); FTimer.Enabled:= True; FTimer..Interval:= 500; FTimer.OnTimer:=FTimerTimer; end; end;
destructor THalfMinute.Destroy; begin
FTimer.Free;
inherited Destroy; end;
procedure THalfMinute.FTimerTimer (Sender: TObject); var
DT: TDateTime; Temp: Word; begin
DT:=Now;
FOldSecond:=FSecond;
DecodeTime (DT,Temp,Temp,FSecond,Temp);
if FSecond <> TOldSecond then
if ((FSecond=30) or (FSecond=0)) then
DoHalfMinute (DT); end;
procedure THalfMinute.DoHalfMinute(TheTime: TDateTime); begin
if Assigned (FOnHalfMinute) then FOnHalfMinute (Self, TheTime); end;
end.

Для проверки работоспособности вышеприведенного кода вы можете добавить еще одну процедуру для регистрации нового компонента с именем ThalfMinute, предварительно расположив в interface часть программы строку:

procedure Register;

Ниже представлен код для регистрации компонента:

procedure Register; 
begin
RegisterComponents('Samples', [THalfMinute]}; end;

Для просмотра работоспособности нового компонента, после его регистрации создадим новую форму и разместим на ней новый компонент. Добавим на форму компонент Tedit, а затем — обработчик события OnHalfMinute для формы (листинг 19.15).

Листинг 19.15.Обработчик нового события

procedure TForm1.HalfMinutelHalfMinute(Sender: TObject;
TheTime: TDateTime); begin
Edit1.Text:=('Время '+TimeToStr(TheTime));
Edit1.Refresh; end;

В результате работы данной программы в компоненте Edit1 каждые 30 секунд будет выводиться текущее время.

Hosted by uCoz