О таймере
О таймере Компонент timer (таймер) служит для отсчета интервалов реального времени. Его свойство interval определяет интервал временив миллисекундах , который должен пройти от включения таймера до наступления события ontimer. Таймер включается при установке значения true в его свойство enabled. Единожды включенный таймер все время будет возбуждать события ontimer до тех пор, пока его свойство enabled не примет значения false. Следует учесть, что в силу специфики реализации стандартного аппаратного таймера ibm-совместимого компьютера минимальный реально достижимый интервал отсчета времени не может быть меньше 55 мс (этот интервал называется тиком), более того, любой интервал времени, отсчитываемый с помощью таймера, всегда кратен 55 мс. Чтобы убедиться в этом, проведите эксперимент, в котором подсчитывается среднее время между двумя срабатываниями таймера (timer.dpr): Начните новый проект с пустой формой и положите на нее компонент ttimer. Установите в свойство enabled таймера значение false. Напишите такой модуль главной формы (листинг 4): Листинг 4
interface
uses
windows, messages, sysutils, classes, graphics, controls, forms,
dialogs, stdctrls, buttons, extctrls;
type
tfmexample = class(tform)
panel1: tpanel;
bbrun: tbitbtn;
bbclose: tbitbtn;
edinput: tedit;
lboutput: tlabel;
mmoutput: tmemo;
timer1: ttimer;
procedure bbrunclick(sender: tobject);
procedure timer1timer(sender: tobject);
procedure formactivate(sender: tobject);
private
begtime: tdatetime; // Начальное время цикла
counter: integer; // Счетчик цикла
end;
var fmexample: tfmexample;
implementation
{$r *.dfm}
procedure tfmexample.bbrunclick(sender: tobject);
// Запускает таймер. edinput содержит период его срабатывания.
var delay: word;
begin
// Проверяем задание интервала
if edinput.text='' then exit;
try
delay := strtoint(edinput.text);
except
showmessage('Ошибка в записи числа');
edinput.selectall;
edinput.setfocus;
exit
end;
counter := 0; // Сбрасываем счетчик
timer1.interval := delay; // Устанавливаем интервал
begtime := time; // Засекаем время
timer1.enabled := true; // Пускаем таймер
screen.cursor := crhourglass
end;
procedure tfmexample.timer1timer(sender: tobject);
var h, m, s, ms: word; // Переменные для декодирования времени
const maxcount = 55; // Количество срабатываний таймера
begin
counter := counter + 1; // Наращиваем счетчик срабатываний
if counter=maxcount then // Конец цикла?
begin // - Да
timer1.enabled := false; // Останавливаем таймер
// Находим среднее время срабатывания:
decodetime((time-begtime)/maxcount, h, m, s, ms);
mmoutput.lines.add( // Выводим результат
format('Задано %s ms. Получено %d ms.', [edinput.text, ms]));
edinput.text := ''; // Готовим следующий запуск
edinput.setfocus;
screen.cursor := crdefault
end;
end;
procedure tfmexample.formactivate(sender: tobject);
begin
edinput.setfocus
end;
end.
interface
uses
windows, messages, sysutils, classes, graphics, controls, forms,
dialogs, stdctrls, buttons, extctrls;
type
tfmexample = class(tform)
panel1: tpanel;
bbrun: tbitbtn;
bbclose: tbitbtn;
edinput: tedit;
lboutput: tlabel;
mmoutput: tmemo;
procedure bbrunclick(sender: tobject);
procedure formactivate(sender: tobject);
end;
var fmexample: tfmexample;
implementation
{$r *.dfm}
// Объявление экспортируемых функций:
function timesetevent(udelay, ureolution: uint; lptimeproc: pointer;
dwuser: dword; fuevent: uint): integer; stdcall; external 'winmm';
function timekillevent(uid: uint): integer; stdcall; external 'winmm';
// Объявление глобальных переменных
var
ueventid: uint; // Идентификатор события таймера
begtime: tdatetime; // Засекаем время<
counter: integer; // Счетчик повторений
delay: word; // Период срабатывания
procedure proctime(uid, msg: uint; dwuse, dw1, dw2: dword); stdcall;
// Реакция на срабатывание таймера (процедура обратного вызова)
var h, m, s, ms: word; // Переменные для декодирования времени
const maxcount = 55; // Количество повторений
begin
timekillevent(ueventid); // Останавливаем таймер
counter := counter+1; // Наращиваем счетчик
if counter=maxcount then // Конец цикла?
begin // - Да: декодируем время
decodetime((time-begtime)/maxcount, h, m, s, ms);
fmexample.mmoutput.lines.add( // Сообщаем результат
format('Задано %s ms. Получено %d ms',
[fmexample.edinput.text,ms]));
fmexample.edinput.text := ''; // Готовим повторение
fmexample.edinput.setfocus
end
else // - Нет: вновь пускаем таймер
ueventid := timesetevent(delay,0,@proctime,0,1);
end;
procedure tfmexample.bbrunclick(sender: tobject);
// Запускает таймер. edinput содержит требуемый период.
begin
// Проверяем задание периода
if edinput.text='' then exit;
try
delay := strtoint(edinput.text)
except
showmessage('Ошибка ввода числа');
edinput.selectall;
edinput.setfocus;
exit
end;
counter := 0; // Сбрасываем счетчик
begtime := time; // Засекаем время
// Запускаем таймер:
ueventid := timesetevent(delay,0,@proctime,0,1);
if ueventid=0 then
showmessage('Ошибка запуска таймера')
end;
procedure tfmexample.formactivate(sender: tobject);
begin
edinput.setfocus
end;
end.
Отправить комментарий