Консультация № 138649
30.05.2008, 12:28
0.00 руб.
0 1 1
Подскажите пожалуйста как организовать ТОЧНЫЙ секундомер? TTimer не устраивает, так как очень большая погрешность 1минута=42секундам. 18 секунд погрешность это много.

Обсуждение

Неизвестный
30.05.2008, 14:12
общий
это ответ
Здравствуйте, Владик!

Вот найдено на просторах инета http://z-oleg.com/delphi/systimer.htm

модуль mmsystem:

Функция имеет вид:
MMRESULT timeSetEvent(
UINT uDelay, // Задержка в мс
UINT uResolution, // Разрешающая способность
LPTIMECALLBACK lpTimeProc, // Указатель на процедуру-обработчик
DWORD dwUser, // Параметр разработчика
UINT fuEvent // Тип события
);

Приложение:
Рассмотрим учебный пример, демонстрирующий особенности работы обычного таймер и мультимедиа-таймера: unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, mmsystem, ExtCtrls;type TForm1 = class(TForm) Memo1: TMemo; Timer1: TTimer; Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public MMTimer1 : integer; // Код мультимедийного таймера end;var Form1: TForm1; Cnt1, Cnt2 : integer;implementation{$R *.dfm}procedure MyTimerCallBackProg(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD); stdcall;begin Inc(Cnt1); // Счетчик срабатывания мультимедиа таймераend;procedure TForm1.FormCreate(Sender: TObject);begin MMTimer1 := timeSetEvent(1,1,@MyTimerCallBackProg,100,TIME_PERIODIC);end;procedure TForm1.FormDestroy(Sender: TObject);begin // Удаление таймера при завершении программы timeKillEvent(MMTimer1);end;procedure TForm1.Timer1Timer(Sender: TObject);begin inc(Cnt2); // Счетчик срабатывания обычного таймераend;procedure TForm1.Button1Click(Sender: TObject);var t : integer;begin Memo1.Lines.Clear; Memo1.Lines.Add(‘Опыт 1 - Sleep на 5 секунд‘); Cnt1 := 0; Cnt2 := 0; Sleep(5000); Memo1.Lines.Add(‘Число срабатываний мультимедиа таймера = ‘+IntToStr(Cnt1)); Memo1.Lines.Add(‘Число срабатываний TTimer c Interval=1 = ‘+IntToStr(Cnt2)); Memo1.Lines.Add(‘Опыт 2 - Цикл ожидания с Application.ProcessMessages‘); Cnt1 := 0; Cnt2 := 0; t := GetTickCount; while GetTickCount - t < 5000 do Application.ProcessMessages; Memo1.Lines.Add(‘Число срабатываний мультимедиа таймера = ‘+IntToStr(Cnt1)); Memo1.Lines.Add(‘Число срабатываний TTimer c Interval=1 = ‘+IntToStr(Cnt2));end;end.На форме необходимо разместить Memo1 типа TMemo и таймер типа TTimer с интервалом 1 и обрабочтчиком Timer1Timer.В этом примере очень хорошо видно, что на время Sleep обычный таймер не действует (т.к. он основан на сообщениях). Кроме того, очень наглядна разница в точности - мультимедийный таймер срабатывает примерно 5000 раз за 5 секунд (как и положено по его настройке). Обычный таймер в первом опыте не срабатывает вообще, во втором опыте срабатывает примерно 320 раз (т.е. примерно один раз в 15 мс)
Форма ответа