Связь и интернет Архив Программирование
   
Сделать стартовойСделать закладку            
   ПОИСК  
   
Главная / Pascal и Delphi / Иллюстрированный самоучитель по Delphi 6 / Часть III. Компоненты и программы / Использование компонентов общего назначения / Компоненты страницы System /
8  Perl
8  PHP
8  JavaScript
8  HTML
8  DHTML
8  XML
8  CSS
8  C / C++
8  Pascal и Delphi
8  Турбо Ассемблер
8  MySQL
8  CASE-технологии
8  Алгоритмы
8  Python
8  Обратная связь
8  Гостевая книга
Новости о мире


Мультимедийный таймер - Программирование от RIN.RU
Мультимедийный таймер

В ряде практически важных применений (при разработке игр, в системах реального времени для управления внешними устройствам и т. п.) интервал 55 мс может оказаться слишком велик. Современный ПК имеет мультимедийный таймер, период срабатывания которого может быть от 1 мс и выше. Однако этот таймер не имеет компонентного воплощения, поэтому для доступа к нему приходится использовать функции API.


Общая схема его использования такова. Сначала готовится процедура обратного вызова (call back) с таким заголовком:


procedure TimeProc(uID, uMsg: UINT; dwUser, dwi, dw2: DWORD); stdcall;


Здесь uID - идентификатор события таймера (см. ниже); uMsg - не используется; dwuser - произвольное число, передаваемое процедуре в момент запуска таймера; dwi, dw2 - не используются. Запуск таймера реализуется функцией


function timeSetEnet(uDelay, uResolution: UINT;
IpTimeProc:Pointer;
dwUser: DWORD;
fuEvent: UINT): UINT;
stdcall;
external 'winmm.dll';


Здесь uDelay - требуемый период срабатывания таймера (в мс);
uResolution - разрешение таймера; значение 0 означает, что события срабатывания таймера будут возникать с максимально возможной частотой; в целях снижения нагрузки на систему вы можете увеличить это значение; IpTimeProc - адрес процедуры обратного вызова; dwUser - произвольное число, которое передается процедуре обратного вызова и которым программист может распоряжаться по своему усмотрению; fuEvent - параметр, управляющий периодичностью возникновения события таймера: time_oneshot (0) - событие возникает только один раз через uDelay мс; time_periodic (1) - события возникают периодически каждые uDelay мс. При успешном обращении функция возвращает идентификатор события таймера или 0, если обращение было ошибочным.


Таймер останавливается, и связанные с ним системные ресурсы освобождаются функцией


function timeKillEvent(uID: UINT): UINT; stdcall; external 'winmm.dll';


Здесь uID - идентификатор события таймера, полученный с помощью timeSetEvent.


В следующем примере иллюстрируется особенность использования мультимедийного таймера.


unit Unit1;


interface


uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls;


type
TfmExample = class(TForm)
Panell: TPanel;
bbRun: TBitBtn;
bbClose: TBitBtn;
edinput: TEdit;
IbOutput: TLabel;
mmOutput: TMemo;
procedure bbRunClick(Sender: TObject);
procedure FormActivate(Sender: TObject);


private
{ Private declarations }
public
{ Public declarations
end;


var
fmExample: TfmExample;


implementation
{$R *.DFM} // Объявление экспортируемых функций:


function timeSetEvent(uDelay, uReolution: UINT;
IpTimeProc: 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, dwi, 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,О,1);
if uEventID=0 then
ShowMessage('Ошибка запуска таймера ' )
end;


procedure TfmExample.FormActivate(Sender: TObject);
begin
edinput.SetFocus
end;
end.




 8  Комментарии к статье  8 8  Обсудить в чате

 
  
  
    Copyright ©  RIN 2003 - 2004      * Обратная связь