[ главная ]   [ рейтинг статей ]   [ справочник радиолюбителя ]   [ новости мира ИТ ]



Ответов: 0
25-02-12 07:01







   Web - программирование
PHP


ASP






XML



CSS

SSI





   Программирование под ОС











   Web - технологии








   Базы Данных









   Графика






Данные




Программирование под ОС / Pascal - Delphi /

Работа с мультимедийным таймером на Win API



Мы уже знакомы с системным таймером, сегодня познакомимся с мультимедийным, основное отличие которого, более высокая скорость (точность) работы. Мультимедийный таймер способен работать с интервалом вплоть до 1 ms, в то время как, интервалы работы системного таймера больше, и зависят от версии ОС. Для Windows95/98 интервал составляет ~50 ms, в Windows2000/XP интервал может быть меньше (у меня он равен ~10 ms).

Сейчас мы убедимся в этом на примере, для чего создадим два таймера: системный и мультимедийный. Оба таймера будут показывать, сколько раз в секунду им удалось сработать.


const
  IDTimer1 = 1;
  IDLabelTimer = 2;
  IDLabelMMTimer = 3;

var
  Wc: TWndClassEx;
  Wnd: HWND;
  Msg: TMsg;
  LabelTimer: HWND;
  LabelMMTimer: HWND;

  TimerBegin: Cardinal;
  TimerCount: Cardinal = 0;
  TimerOld: Cardinal = 0;
  MMTimerID: Cardinal;
  MMTimerBegin: Cardinal;
  MMTimerCount: Cardinal = 0;
  MMTimerOld: Cardinal = 0;

В прошлом примере, для работы с системным таймером, нам приходилось обрабатывать сообщение WM_TIMER. Однако системный таймер никаких сообщений не генерирует, для работы с ним нужно использовать функцию обратного вызова (CallBack). Такую же функцию будем использовать для работы с системным таймером. Посмотрим их описание.


(* CallBack функция для системного таймера *)
procedure TimerProc( Wnd: HWND; uMsg: UINT; idEvent: UINT; dwTimer: UINT ); stdcall;

(* CallBack функция для мультимедийного таймера *)
procedure MMTimerProc( uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD ); stdcall;

Обратим внимание на то, что функция использует соглашение о передаче параметров stdcall.

Определим эти функции.


procedure TimerProc( Wnd: HWND; uMsg: UINT; idEvent: UINT; dwTimer: UINT ); stdcall;
var
 tmpTimer: string;
 tmpTimerCount: string;
begin
   Inc( TimerCount );
   Str( TimerOld, tmpTimer );
   Str( TimerCount, tmpTimerCount );
   SetWindowText( LabelTimer, PChar( 'Timer: ' + tmpTimerCount + '   [' + tmpTimer + ']' ) );
   if GetTickCount - TimerBegin >= 1000 then
   begin
      TimerOld := TimerCount;
      TimerBegin := GetTickCount;
      TimerCount := 0;
   end;
end;

procedure MMTimerProc( uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD ); stdcall;
var
 tmpMMTimer: string;
 tmpMMTimerCount: string;
begin
   Inc( MMTimerCount );
   Str( MMTimerOld, tmpMMTimer );
   Str( MMTimerCount, tmpMMTimerCount );
   SetWindowText( LabelMMTimer, PChar( 'MMTimer: ' + tmpMMTimerCount + '   [' + tmpMMTimer + ']' ) );
   if GetTickCount - MMTimerBegin >= 1000 then
   begin
      MMTimerOld := MMTimerCount;
      MMTimerBegin := GetTickCount;
      MMTimerCount := 0;
   end;
end;

Как видим, все просто. Каждый тик таймера мы увеличиваем на единицу переменную, которая показывает, сколько уже раз сработал таймер. Каждую секунду обнуляем счетчик, предварительно сохранив его значение (это значение мы будем показывать всю следующую секунду).

Перейдем к созданию таймеров.


SetTimer( Wnd, IDTimer1, 1, @TimerProc );
TimerBegin := GetTickCount;

MMTimerID := timeSetEvent( 1, 2, @MMTimerProc, 0, TIME_PERIODIC );
MMTimerBegin := TimerBegin;

С созданием системного таймера мы уже знакомы. Единственное отличие от предыдущего примера заключается в том, что в качестве последнего параметра мы вместо nil передаем указатель на CallBack функцию. Сразу после его создания запоминаем текущее время, от него начнем отсчет интервалов, длинной в секунду. Затем создаем мультимедийный таймер, для чего воспользуемся функцией timeSetEvent. Рассмотрим ее параметры. 1 - интервал таймера (в миллисекундах). 2 - разрешающая способность (количество миллисекунд, ограничивающее время на отработку каждого тика таймера). Если задать 0, точность будет максимальной. 3 - адрес CallBack функции. 4 - Параметр пользователя. Этот параметр передается в обработчик lpFunction и может использоваться по усмотрению программиста. 5 - одна из двух констант: TIME_ONESHOT (обработчик таймера вызывается один раз) или TIME_PERIODIC (обработчик таймера вызывается периодически).

Уничтожение таймеров выглядит следующим образом.


KillTimer( Wnd, IDTimer1 );
timeKillEvent( MMTimerID );

Пара слов о работе этих таймеров. Системный таймер: Если обработчик таймера не успевает закончить все действия в установленный интервал, то последующие вызовы этого обработчика становятся в очередь. Это приводит к тому, что на разных компьютерах приложение работает с разной скоростью. Сама же CallBack функция вызывается в контексте основного потока. Мультимедийный таймер: Если обработчик таймера не успевает закончить все действия в установленный интервал, то последующие вызовы накапливаться не будут. Сама же CallBack функция вызывается в контексте отдельного потока.

На сегодня это все, удачи в программировании.




Комментарии

 Ваш комментарий к данному материалу будет интересен нам и нашим читателям!



Последние статьи: Программирование под ОС / Pascal - Delphi /

Работа со шрифтами на Win API
06-06-2010   

Сегодня поговорим о шрифтах, и о том, каким образом работать с ними на Win API. Нам потребуется переменная типа HFONT. Изменить стиль шрифта можно у любого компонента, я покажу это на примере кнопки... подробнее

Кол. просмотров: общее - 3511 сегодня - 2

Работа с таймером на Win API
06-06-2010   

Таймер - вещь в хозяйстве очень полезная. Если некое действие нужно повторять с определенной периодичностью, то таймер, это как раз то, что нужно... подробнее

Кол. просмотров: общее - 3498 сегодня - 3

Работа с мультимедийным таймером на Win API
06-06-2010   

Мы уже знакомы с системным таймером, сегодня познакомимся с мультимедийным, основное отличие которого, более высокая скорость (точность) работы... подробнее

Кол. просмотров: общее - 3623 сегодня - 2

Создание CheckBoxов средствами Win API
06-06-2010   

Сегодня наша программа научится работать с CheckBoxами. CheckBox можно представить как флаг, который можно установить или сбросить, и в зависимости от его состояния выполнять определенные действия... подробнее

Кол. просмотров: общее - 3741 сегодня - 1

Создание группы RadioButton средствами Win API
06-06-2010   

В прошлый раз мы сделали несколько радио-кнопок, которые автоматически объединялись в одну группу. Сейчас рассмотрим, как создавать несколько независимых групп радио-кнопок... подробнее

Кол. просмотров: общее - 3567 сегодня - 3



  WWW.COMPROG.RU - 2009-2012 | Designed and Powered by Zaipov Renat | Projects