5. События в компонентах Мы уже знаем, что для того, чтобы сгенерировать событие, надо объявить свойство, которое будет иметь тип процедуры. До этого мы использовали свойство TNotifyEvent. Теперь мы улучшим наши часы и добавим возможность передачи в обработчик события определенного значения и заодно более подробно разберемся с событиями. Откройте файл, в котором у вас находится исходный код для работы часов. Первое, что мы сделаем, - объявим новый тип события с именем TClockNotifyEvent в разделе type: TClockNotifyEvent = procedure(Sender: TObject; TimeParam: Integer) of object; В этом типе уже два параметра: - указатель на компонент, который сгенерировал событие; - через этот параметр мы будем передавать обработчику значение времени. Этот тип события мы назначим всем переменным FOnSecond, FOnMinute и FOnHour. Для этого найдите следующую строку в объявлении нашего компонента: FOnSecond, FOnMinute, FOnHour: TNotifyEvent; Здесь нужно изменить тип TNotifyEvent на TClockNotifyEvent. To же самое нужно сделать и в следующих строках: property OnSecond: TClockNotifyEvent read FOnSecond write FOnSecond; property OnMinute: TClockNotifyEvent read FOnMinute write FOnMinute; property OnHour : TClockNotifyEvent read FOnHour write FOnHour; Теперь события имеют новый тип и два параметра. Через второй мы будем передавать текущее значение часов, минут или секунд. Далее найдем процедуру TickerCall и изменим в ней генерацию события таким образом, как это показано в листинге 1.5. Листинг 1.5. Генерация события procedure TGraphicClock.TickerCall(Sender: TObject); var H, M, S, Hp, Mp, Sp: word; begin if csDesigning in ComponentState then exit; DecodeCTime( Time, H, M, S); DecodeCTime( PrevTime, Hp, Mp, Sp); if Assigned( FOnSecond) then FOnSecond(Self, s); if Assigned( FOnMinute) AND (Mp < M) then FOnMinute(Self, m) ; if Assignedf FOnHour) AND (Hp < H) then FOnHour(Self, s); PrevTime := Time; if ( NOT ShowSecondArrow) AND (Sp <= S) then exit; DrawArrows; end; Теперь наш компонент генерирует события следующим образом: if Assigned( FOnSecond) then FOnSecond(Self, s); Сначала мы проверяем, если программа назначила обработчик события Assigned (FOnSecond), то он вызывается и ему передаются значения. В качестве первого параметра передается указатель на себя - Self, а в качестве параметра передается значение, в данном случае — количество секунд. Перекомпилируйте пакет, в который вы добавили компонент. Для этого его нужно открыть и нажать кнопку Compile. Создайте новое приложение и поместите в главное окно наш компонент. Выделите его и в объектном инспекторе перейдите на вкладку Events. Создайте обработчик события для любого из событий, и Delphi вам создаст примерно следующую заготовку: procedure TForml.GraphicClocklHour(Sender: TObject; TimeParam: Integer); begin end; Как видите, здесь два параметра, и они именно такие, как и в созданном нами типе события. Вот теперь можно сказать, что мы знаем о событиях практически все, что необходимо. Примечание Зайдите на сайт www.torry.net и посмотрите раздел VCL. Тут целое множество компонентов, написанных разными программистами-одиночками и маленькими фирмами. Некоторые даже зарабатывают этим деньги. Вы можете создать свои компоненты, похожие на те, что видите на палитре компонентов, и потом многократно использовать написанный там код. Если сделаете так, то в будущем достаточно будет только установить свой компонент на форму, и его можно будет использовать точно так же, как и любой другой стандартный компонент Delphi.