Главная » Delphi » Определение свойств событий

0

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

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

Код компонента TddgHalfMinute приведен в листинге 11.7 и призван  проиллю

стрировать способы определения собственных событий.

Листинг 11.7. Создание события TddgHalfMiute

unit halfmin;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs, ExtCtrls;

type

{ Определить процедуру для обработчика события. Свойство-событие

будет иметь тот процедурный тип, который предусматривает

передачу двух параметров – генерирующего событие объекта и

значения TDataTime, фиксирующего время генерации события.

В данном случае это событие будет происходить каждые

полминуты. }

TTimeEvent = procedure(Sender: TObject;

TheTime: TDateTime) of object;

TddgHalfMinute = class(TComponent)

private

FTimer: TTimer;

{ Определить поле, которое будет хранить ссылку на обработчик

события пользователя. Предоставленный пользователем

обработчик события должен иметь процедурный тип TTimeEvent.}

FOnHalfMinute: TTimeEvent;

FOldSecond, FSecond: Word; // Переменные, используемые в коде

{ Определяем процедуру FTimerTimer, которая будет связана со

свойством-событием FTimer.OnClick. Эта процедура должна

иметь тип TNotifyEvent, как и само

свойство-событие TTimer.OnClick. }

procedure FTimerTimer(Sender: TObject);

protected

{ Определение метода диспетчеризации события OnHalfMinute. }

procedure DoHalfMinute(TheTime: TDateTime); dynamic;

public

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

published

{ Определить реальное свойство, отображаемое в окне инспектора

объектов. }

property OnHalfMinute: TTimeEvent read FOnHalfMinute

write FOnHalfMinute;

end;

implementation

constructor TddgHalfMinute.Create(AOwner: TComponent);

{ Конструктор Create создает экземпляр компонента TTimer по имени

FTimer, а затем задает различные свойства экземпляра FTimer,

в том числе его обработчик события OnTimer, являющийся методом

FTimerTimer() компонента TddgHalfMinute. Заметьте, что свойство

FTimer.Enabled устанавливается равным значению true при

выполнении программы и значению false, если компонент находится

в режиме разработки. }

begin

inherited Create(AOwner);

{ Если компонент находится в режиме разработки, FTimer не

активизируется. }

if not (csDesigning in ComponentState) then begin

FTimer := TTimer.Create(self);

FTimer.Enabled := True;

{ Установить остальные свойства, включая обработчик

события FTimer.OnTimer.}

FTimer.Interval := 500;

FTimer.OnTimer := FTimerTimer;

end;

end;

destructor TddgHalfMinute.Destroy;

begin

FTimer.Free;

inherited Destroy;

end;

procedure TddgHalfMinute.FTimerTimer(Sender: TObject);

{ Этот метод служит обработчиком события FTimer.OnTimer. Он

назначается свойству FTimer.OnTimer динамически в конструкторе

TddgHalfMinute. Данный метод считывает системное время и

проверяет, не кратно ли оно 30 секундам. Если это условие

выполняется, то он вызывает метод диспетчеризации DoHalfMinute

события OnHalfMinute. }

var

DT: TDateTime;

Temp: Word;

begin

DT := Now; // Получить системное время

FOldSecond := FSecond; // Сохранить старое значение секунд

// Получить значение секундной составляющей системного времени.

DecodeTime(DT, Temp, Temp, FSecond, Temp);

{ Если текущее время не совпадает со временем последнего вызова метода и оно кратно 30 секундам, вызывается

метод DoOnHalfMinute. }

if FSecond <> FOldSecond then

if ((FSecond = 30) or (FSecond = 0)) then

DoHalfMinute(DT)

end;procedure TddgHalfMinute.DoHalfMinute(TheTime: TDateTime);

begin

if Assigned(FOnHalfMinute) then

FOnHalfMinute(Self, TheTime);

end;

end.При  создании собственного события необходимо решить, какую именно инфор мацию  следует  передавать пользователям данного компонента в качестве параметра обработчика события. Например, при создании обработчика события TEdit.OnKey- Press его код может выглядеть следующим образом:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);

begin

end;

В этом случае передается не только  ссылка на объект, ответственный за возникно вение  события, но и параметр Char, определяющий нажатую клавишу. В недрах  под программ библиотеки VCL данное  событие возникает в результате поступления со общения Win32 WM_CHAR, содержащего дополнительную информацию о нажатой кла више. Delphi извлекает из этого  сообщения необходимые данные  и делает  их доступными пользователям компонента в качестве параметров обработчика события. Такая  схема взаимодействия позволяет разработчику компонента преобразовывать слишком  сложную  информацию и делать  ее доступной пользователям компонента в простом и понятном виде.

Обратите внимание на  передаваемый по  ссылке  параметр в методе  Edit1Key- Press(). Может вызвать интерес тот факт,  что этот метод был объявлен процедурой, а не функцией, возвращающей значение Char. Хотя  методы  могут быть  функциями, не следует объявлять как функции события, поскольку  это внесет  дополнительную пу таницу: обращаясь к указателю метода  функции, нельзя быть уверенным, ссылается ли он на результат функции или является указателем  функции. Между прочим, одно  со бытие, представляющее собой  функцию, все  же  уцелело  со  времен первых версий Delphi  — это событие TApplication.OnHelp.

Просмотрев листинг 11.7, можно  заметить, что процедурный тип TOnHalfMinute

определен следующим образом:

TTimeEvent = procedure(Sender: TObject;

TheTime: TDateTime) of object;

Этот   процедурный  тип   определяет  тип   обработчика  события  OnHalfMinute. Здесь  пользователь передает ссылку на объект, вызывающий событие, и значение времени TDataTime, когда это событие произошло.

Поле хранения FOnHalfMinute ссылается на пользовательский обработчик собы

тия и отображается в окне инспектора объектов на этапе проектирования как свойст

во OnHalfMinute.

Основным назначением компонента, использующего объект TTimer, является оп

ределение секундной составляющей времени через каждые полсекунды. Если это зна

чение равно  0 или 30, вызывается метод  DoHalfMinute(), отвечающий за проверкусуществования обработчика события и последующий его вызов. Прочтите коммента

рии,  приведенные в коде программы, — они содержат много полезной информации.

Установив компонент в палитру  компонентов Delphi, можно  будет помещать его в форму и добавлять следующий обработчик события OnHalfMinute:

procedure TForm1.ddgHalfMinuteHalfMinute(Sender: TObject; TheTime: TDateTime);

begin

ShowMessage(‘The Time is ‘+TimeToStr(TheTime));

end;

Этот код демонстрирует, как новый  тип события получает свой обработчик.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии