вторник, 11 ноября 2008 г.

Использование таймеров в Delphi

Использование таймеров в Delphi

Класс TTimer инкапсулирует свойства и методы для работы с таймером, позволяющем осуществлять отсчеты интервалов времени. Описание класса приводится в модуле ExtCtrls поэтому для его использования необходимо указать имя данного модуля в разделе uses.
Класс TTimer - невизуальный, это означает, что он не отображается на форме.
Данный класс имеет два свойства:

Property Enabled: Boolean;Устанавливается в значение True, если требуется, чтобы включился системный
генератор сообщений WM_Timer.
Property Interval: Cardinal;Задает промежуток времени в миллисекундах между приходом сообщений.

Данные свойства позволяют управлять компонентом. Свойство Interval задает
период срабатывания таймера. Через заданный интервал времени после предыдущего
срабатывания, или после программной установки свойства Interval, или после
запуска приложения, если значение Interval установлено во время проектирования,
таймер срабатывает, вызывая событие OnTimer. В обработчике этого события
записываются необходимые операции.

Если задать Interval = 0 или Enabled = False, то таймер перестает работать.
Чтобы запустить отсчет времени надо или задать Enabled = True, если установлено
положительное значение Interval, или задать положительное значение Interval,
если Enabled = False.

Если необходимо в некоторой процедуре запустить таймер, который отсчитал бы заданный
интервал, например, 5 секунд, после чего надо выполнить некоторые операции и отключить
таймер, это можно сделать следующим образом. При проектировании таймер делается
доступным (Enabled = True), но свойство Interval задается равным 0.
Таймер не будет работать, пока в момент, когда нужно запустить таймер, не выполнится
оператор
Timer1.Interval:=5000;

Через 5 секунд после этого наступит событие OnTimer. В его обработчике надо
задать оператор
Timer1.Interval:=0;

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


   
Другой эквивалентный способ решения задачи - использование свойства Enabled.
Во время проектирования задается значение Interval = 5000 и значение
Enabled = False. В момент, когда надо запустить таймер, выполняется оператор:

Timer1.Enabled:=True;

В обработчик события OnTimer, которое наступит через 5 секунд после запуска
таймера, можно вставить оператор
Timer1.Enabled:=False;

который отключит таймер.


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

type

TTimeredObject = class (TObject)
   procedure TimerEvent(Sender:Tobject);
end;

далее опишем саму процедуру TimerEvent которая сработает по окончанию интервала времени.

procedure TTimeredObject.TimerEvent(Sender:TObject);
begin
 TimeFinished:=true;
end;

Переменная  логического типа Finished должна быть объевлена как глобальная переменная, там же должна быть объявлена переменная Timer1:TTimer. Для этого в разделе interface модуля после ключевого слова var запишем

var
    TimeFinished:boolean;
    Timer1:TTimer;

В экспортируемой функции LEntry, которая собственно и реализует тот или иной метод, запишем следующие строки:

function LEntry (.....)
var TimeredObject:TTimeredObject;
begin

// устанавливаем свойство окончания цикла по времени false
TimeFinished:=false;
 
 // создаем таймер
Timer1:=TTimer.Create(nil);
// устанавливаем интервал
Timer1.Interval:=5000;

// создаем созданный нами вспомогательный объект
TimeredObject:=TTimeredObject.Create;



// присваиваем созданный нами обработчик методу OnClick таймера
Timer1.OnClick:=TimeredObject.TimerEvent;

// запускаем таймер и начинаем цикл
Timer1.Enabled:=true;

repeat


until Timefinished<>true;

end;

Кратко останавлюсь на том, почему потребовалась так присваивать обработчик методу OnClick. В описании класса TTimer метод описан следующим образом

property OnTimer:TNotifyEvent read FOnTimer write SetOnTimer;

Вообще свойство объекта обеспечивает и/или чтение и/или запись с помощью некоторых процедур в некоторое поле класса. В данном случае полем, с которым связано свойство, является поле FOnTimer. Чтение происходит непосредственно из поля, а вот для записи данных в поле применяется специальная процедура SetOnTimer.
Свойство (и естественно поле, связанное с данным свойством) имеет тип TNotifyEvent, который соотвествует наступлению некоторого события. Тип TNotifyEvent определен следующим образом:

TNotifyEvent = procedure (Sender:TObject) of object;

такая конструкция определяет тип данных - ссылка на процедуру принадлежащую некоторому объекту, то есть на метод объекта. Параметром процедуры является объект вызывающий данное событие.
Мы определили вспомогательный класс, содержащий метод, в точности совпадающий с типом TNotifyEvent. Следовательно, свойству OnTimer можно назначить обработчик события TimerEvent.

Комментариев нет: