Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.02.2017, 08:02   #11
_Dmitry
Участник клуба
 
Аватар для _Dmitry
 
Регистрация: 02.09.2007
Сообщений: 1,193
По умолчанию

Когда-то давно анализировали работу таймеров: http://www.programmersforum.ru/showthread.php?t=12132

Даже программу делали для сравнения: http://www.programmersforum.ru/attac...9&d=1199691941
_Dmitry вне форума Ответить с цитированием
Старый 03.02.2017, 09:23   #12
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Поддерживаю Pavia
Цитата:
Для игр стоит использовать мультимедийный таймер. Он уже будет гарантированно работать с точностью 15,16 мс. И при настройке системы 1 мс.
timeGetTime, timeKillEvent, and timeSetEvent
Я тоже использую этот таймер и пока он меня лично устраивает почитать можно здесь
высокоточный таймер http://www.webdelphi.ru/2009/08/vyso...svoimi-rukami/

Код:
uses
MMSystem, .......



var
TimerID: Dword;
TimeStart: TDateTime;
Freq, Coun1, Coun2: int64;

// минимальный период таймера
function timeGetMinPeriod(): DWORD;
var  time: TTimeCaps;
begin
  timeGetDevCaps(Addr(time), SizeOf(time));
  timeGetMinPeriod := time.wPeriodMin;
end;

//максимальный период таймера
function timeGetMaxPeriod(): Cardinal;
var time: TTimeCaps;
begin
  timeGetDevCaps(Addr(time), SizeOf(time));
  timeGetMaxPeriod := time.wPeriodMax;
end;

procedure TimerProc(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD) stdcall;
begin
 QueryPerformanceCounter(Coun2);
  TForm1(dwUser).Memo1.Lines.Add(Format('%8.3f c (%6.3f мс)',[(Coun2-Coun1)/Freq,1000*(Coun2-Coun1)/Freq]));
//TForm1(dwUser).Memo1.Lines.Add(FormatDateTime('hh:mm:ss:ms', Now - TimeStart));
QueryPerformanceCounter(Coun1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(Coun1);
//TimeStart := Now;
// запуск с минимальным периодом
TimerID:= timeSetEvent(1, timeGetMinPeriod, TimerProc, Dword(Form1), TIME_CALLBACK_FUNCTION or TIME_PERIODIC);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
timeKillEvent(TimerID);
end;

Последний раз редактировалось Aliens_wolfs; 03.02.2017 в 09:47.
Aliens_wolfs вне форума Ответить с цитированием
Старый 06.02.2017, 09:10   #13
fanlis
Пользователь
 
Регистрация: 13.05.2007
Сообщений: 60
По умолчанию

Да, я почитал про мультимедийный таймер, нашел вот такой вариант:
Код:
unit clMMTimer;

interface

uses
  Windows, Classes, MMSystem;

type
  TMMTimer = class
  private
    FInterval: integer;
    fId: UINT;
    FOnTimer: TNotifyEvent;
    fTag: integer;
    function GetEnabled: boolean;
    procedure SetEnabled(Value: boolean);
    procedure SetInterval(Value: integer);
  protected
    procedure DoTimer; virtual;
  public
    property Interval: integer read FInterval write SetInterval;
    property Enabled: boolean read GetEnabled write SetEnabled;
    property Tag: integer read fTag write fTag;
    property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
    destructor Destroy; override;
  end;

implementation

{ TMMTimer }

procedure MMCallBack(uTimerID, uMsg: UINT; dwUser, dw1, dw2: DWORD); stdcall;
begin
  if dwUser <> 0 then
    TMMTimer(dwUser).DoTimer;
end;

destructor TMMTimer.Destroy;
begin
  if Enabled then
  begin
    if (fId <> 0) then
    begin
      timeKillEvent(fId);
      fId := 0;
    end
  end;
  inherited;
end;

procedure TMMTimer.DoTimer;
begin
  if Assigned(FOnTimer) then
    FOnTimer(Self);
end;

function TMMTimer.GetEnabled: boolean;
begin
  Result := fId <> 0;
end;

procedure TMMTimer.SetEnabled(Value: boolean);
begin
  if Enabled <> Value then
  begin
    if fId <> 0 then
    begin
      timeKillEvent(fId);
      fId := 0;
    end
    else
    begin
      fId := timeSetEvent(FInterval, 1, @MMCallBack, DWORD(Self),
        TIME_CALLBACK_FUNCTION or TIME_PERIODIC{ or TIME_KILL_SYNCHRONOUS});
    end;
  end;
end;

procedure TMMTimer.SetInterval(Value: integer);
var
  oldEnabled: boolean;
begin
  if FInterval <> Value then
  begin
    oldEnabled := Enabled;
    Enabled := false;
    FInterval := Value;
    Enabled := oldEnabled;
  end;
end;

end.
Работаю как с обычным таймером:
Код:
var
  Timer1: TMMTimer;
begin
  Timer1:=TMMTimer.Create;
  Timer1.Interval:=20;
  Timer1.OnTimer:=Timer1Timer;
  Timer1.Enabled:=true;

Немножко подкорректировал.
В общем использовал я этот таймер и 3-й вариант, как описывал в начале и теперь просто счастлив! Теперь в программе все просто и понятно, я бы даже сказал изящно. Таймер выполняет задержку 20 мс с погрешностью десятые доли мс.
fanlis вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программа неправильно работает HaKeRR Помощь студентам 1 05.12.2014 23:51
Неправильно работает таймер Юшков Компоненты Delphi 9 07.11.2011 14:42
TextRect работает неправильно bbk_serg БД в Delphi 16 10.08.2010 21:11
Скрипт неправильно работает aleksa76 JavaScript, Ajax 4 21.05.2008 17:47
Запрос неправильно работает... yulia БД в Delphi 0 27.05.2007 20:41