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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.12.2012, 23:55   #1
darkleo
Пользователь
 
Регистрация: 11.12.2012
Сообщений: 20
По умолчанию Мультимедийный таймер в Дельфи

Приветствую

Вот обозначилась проблема.
Работаю с мультимедийным таймером.

Задается так:

TimeFinished:=false;
MMTimer1 := timeSetEvent(timer*1000,0,@MyTimerC allBackProg,100,TIME_ONESHOT);

Тело функции
Procedure MyTimerCallBackProg(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD); stdcall;
begin

Timefinished:=true;
end;

Суть в том что, в процессе работы таймера по определенному условию надо остановить и убить таймер, и запустить его внось с другим значением timer

Все компилится.
Но проблема в том что после повторного попадания на mmtimer1:=timesetevent....
и после выполнения данной функции переменная Timefinished сразу становиться True хотя перед повторным запуском таймера переменная принудительно делается False
Может я неправильно убиваю\останавливаю таймер?
Помогите пожалуйста советом.
darkleo вне форума Ответить с цитированием
Старый 27.12.2012, 01:15   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

KillTimer(MMTimer1) в конце.
Человек_Борща вне форума Ответить с цитированием
Старый 27.12.2012, 01:29   #3
darkleo
Пользователь
 
Регистрация: 11.12.2012
Сообщений: 20
По умолчанию

Именно.
После killtimer у меня идет возврат на
Timefinished:=false;
timesetevent(...)

далее while timefinished=false do
.......

так вот уже на while переменная timefinished стоит как true
такое впечатление что киллтаймером не убил таймер а остановил и когда его снова запускаю, он не сначала работает а дорабатывает первый цикл....=(
darkleo вне форума Ответить с цитированием
Старый 27.12.2012, 01:35   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

покажите весь код.
Человек_Борща вне форума Ответить с цитированием
Старый 27.12.2012, 02:24   #5
darkleo
Пользователь
 
Регистрация: 11.12.2012
Сообщений: 20
По умолчанию

Работа с портом юсб на предмет данных в нем
Вот коллектор данных с порта
Цитата:
loop_78:
timeBeginPeriod(1);
TimeFinished:=false;
MMTimer1 := timeSetEvent(timer*1000,0,@MyTimerC allBackProg,100,TIME_ONESHOT);

listen:

x:=0;
ZeroMemory(@in_buffer,sizeof(in_buf fer));
offset:=0;
in_bytes:=0;
while TimeFinished=false do //пока таймер не изменил переменную на True читаем порт
begin
count:=Read_USB_Device_Buffer(130);
if count<>0 then
begin
move(ft_in_buffer[0],in_buffer[offset],count); //собираем данныее
offset:=offset+count;
in_bytes:=in_bytes+count;
end;
if (count=0) and (in_bytes>12) then Timefinished:=true; //выход с таймера если данных с порта больше нет, но до этого они были и собраны

end;
timeendPeriod(1);
Дальше идет парсер буффера.. тут пока все отлично работает.
И в итоге попадаем на код:

Цитата:
if (in_buffer[x+6]=$7F) and (in_buffer[x+8]=$78) then
begin
if in_buffer[x+13]<>0 then
begin
x:=x+13;
goto retry;
end;


timekillevent(mmtimer1);
timer:=7; //новое время для таймера (переменная timer приходит из вне)
goto loop_78; //прыгаем на начало где запуск таймера

end;
Вот от сюда после попадания на старт таймера и присвоени переменной Timefinished:=false для таймера
и его запуска в начале посредством timesetevent
переменная Timefinished тут же становится True и все ломается, потому что у меня сбор данных идет пока timefinished не станет True, а по замыслу он должен становиться тру либо по таймеру либо по окончании данных приходящих с юсб.
код обработчика

Цитата:
Procedure MyTimerCallBackProg(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD); stdcall;
begin

Timefinished:=true;

end;
darkleo вне форума Ответить с цитированием
Старый 27.12.2012, 02:32   #6
darkleo
Пользователь
 
Регистрация: 11.12.2012
Сообщений: 20
По умолчанию

Да. Забыл добавить что все это работает в потоке. Но не думаю что здесь проблемы с синхронизацией
darkleo вне форума Ответить с цитированием
Старый 27.12.2012, 02:34   #7
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Как-то 1 раз написал и пользуюсь =)
Код:
unit clMMTimer;

interface

uses
  Winapi.Windows,
  System.Classes,
  Winapi.MMSystem;

type
  TMMTimer = class
  private
    FInterval: integer;
    fId: UINT;
    FOnTimer: TNotifyEvent;
    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 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, 0, @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.
Цитата:
переменная Timefinished тут же становится True и все ломается, потому что у меня сбор данных идет пока timefinished не станет True, а по замыслу он должен становиться тру либо по таймеру либо по окончании данных приходящих с юсб.
Вам не BOOL нужно, вам нужно TEvent + WaitForSingleObject
Человек_Борща вне форума Ответить с цитированием
Старый 27.12.2012, 02:52   #8
darkleo
Пользователь
 
Регистрация: 11.12.2012
Сообщений: 20
По умолчанию

А можно у Вас попросить простой пример использования и вашего класса и связки TEvent и WaitForSingleObject
Я просто не все еще оч хорошо понимаю.... вникаю.
Спасибо за помощь =)
darkleo вне форума Ответить с цитированием
Старый 28.12.2012, 02:25   #9
darkleo
Пользователь
 
Регистрация: 11.12.2012
Сообщений: 20
По умолчанию

Победил. Своими же средствами=) Глупая ошибка как всегда.
В моей процедуре опроса в теле while все работало отлично. Но закралась маленькая ошибка.
Идентификатор таймера я убивал практически в конце процедуры, и в итоге по определенным условиям, я запускал еще один таймер, с другим идентификатором, но с той же процедурой обработчиком. В итоге и получилось глупое наложение.

Установка timekillevent сразу после тела while сразу решила проблему. Таймер стал прекрасно и останавливаться и перезапускаться как мне надо.

Спасибо за помощь и интересный вариант таймера "Человек Борща"
darkleo вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
таблицы подстановок в дельфи(базы данных в дельфи) ManiagoZ БД в Delphi 0 15.05.2011 15:07
Мультимедийный конспект TMAX Помощь студентам 3 08.11.2009 12:10
не могу запустить мультимедийный курс vasypupkin Общие вопросы по Java, Java SE, Kotlin 6 16.05.2009 20:54
Мультимедийный Обучающий Курс TeachPro Java Для Начинающих mihali4 Общие вопросы по Java, Java SE, Kotlin 3 04.11.2008 05:39