Ricardo César Cardoso wrote:

> Boa tarde João! Vc já está começando a salvar a minha pele...

Opa. Por nada. Agora vamos terminar de descascar esse abacaxi.

> Ainda estou com umas dúvidas aqui no procedimento que vc passou:
> 
> Tentei seguir o que vc sugeriu, mas ainda estou tendo problemas. Agora quando 
> aciono o botão do dispositivo, normal, inicia a execução do timer, porém 
> quando eu solto o botão do dispositivo que fica enviando pulsos o timer não 
> para a contagem.

Vamos lá:

1. Dentro do evento do Timer você precisa setar a sua thread com
Started := False; ou você precisa que a thread leia o 'Iniciado' ao 
invés de ler um membro privado; (mais comentários abaixo)

2. Você está destruindo o timer mas não está recriando. Seguinte: o 
timer é usado para encerrar a thread e a contagem, então cada vez que 
você recebe um sinal que _não é_ o _primeiro sinal_, você tem que 
resetar o timer. Você o destruiu, mas esqueceu de recria-lo;

       if Assigned(aTimer) then
         aTimer.Free; // ou seria melhor aTimer.Destroy ?

Basta escrever assim:

     ATimer.Free;
     ATimer := CriaTimer;  // aqui dentro você cria um timer,
                           // seta o intervalo e o evento.

Quanto a thread:

       // Código de criação da Thread - Como Fazer?
       // Seria assim?
       with TThreadMonitora.Create(True) do
       begin
         Priority  := tpLower;
         StartTime := HoraIni;
         Started   := Iniciado;
         Resume;
       end;

Tá perfeita. Agora eu tô entendendo o que você tentou fazer com o 
'Iniciado' Você tem que definir Started como um ponteiro para Boolean:

     Started: ^Boolean;

gravar o conteúdo assim:

     Started := @Iniciado;

e consultar o conteúdo assim:

     while Started^ do

senão você terá dois endereços de memória e a coisa não vai funcionar 
nem nunca.

às ordens,

--
João Morais



> Acredito que o problema seja o ComPort, pq ele também usa Threads para 
> monitorar os eventos da porta. Estou anexando o código da thread que eu criei 
> de acordo com o que compreendi das suas orientações iniciais e a 
> implementação das chamadas do s/w.
> 
> Será que vc ou alguma outra alma caridosa poderiam me ajudar?
> 
> (************************** Unit Cronômetro (principal) 
> *******************************)
> {...}
>   public
>     { Public declarations }
>     Iniciado : Boolean;   // Flag do primeiro sinal da porta
>     HoraIni : TDateTime; // Data e hora do recebimento do primeiro sinal
>   end;
> {...}
> 
> {...}
> implementation
> 
> {$R *.dfm}
> 
> uses ThreadMonitora;
> {...}
> 
> {...}
> Procedure TfrmCrometro.ComPort1Error(Sender: TObject; Errors: TComErrors);
> // Este evento se repete enquanto o botão do hardware está acionado
> // ele fica mandando pulsos para o computador a cada 1ms
>  Var
>    aTimer : TTimer;
> 
>  Begin
>    if not Iniciado then
>    begin
>      HoraIni := Now; // implementei a inicialização dentro de um TButtom
>      Iniciado := True; // Esse seria o flag da recepção do primeiro evento.
> 
>      // Criação do Timer dinâmico
>      aTimer := TTimer.Create(Self);
>      with aTimer do
>      begin
>        Interval := 2000;
>        Name     := 'DynaTimer';
>        OnTimer  := FinalizaCronometro;
>      end;
> 
>      // Código de criação da Thread - Como Fazer?
>      // Seria assim?
>      with TThreadMonitora.Create(True) do
>      begin
>        Priority  := tpLower;
>        StartTime := HoraIni;
>        Started   := Iniciado;
>        Resume;
>      end;
>    end
>    else
>    begin
>      if Assigned(aTimer) then
>        aTimer.Free; // ou seria melhor aTimer.Destroy ?
>    end;
> 
>  End;
> 
> Procedure TfrmCrometro.FinalizaCronometro(Sender: TObject);
>  Begin
>    Iniciado := False; 
>    Label1.Caption := FormatDateTime('hh:mm:ss:zzz', Now - HoraIni);
>  End;
> {...}
> (********************************************************************************************)
> 
> (********************************* Thread de Monitoração 
> *******************************)
> (*** Está numa unit a parte *****)
> unit ThreadMonitora;
> 
> interface
> 
> uses
>   Classes, SysUtils, Windows;
> 
> type
>   TThreadMonitora = class(TThread)
>   private
>     { Private declarations }
>     FStartTime : TDateTime;
>     FStarted   : Boolean;
>   protected
>     procedure Execute; override;
>     procedure AtualizaLabel;
> 
>   public
>     property StartTime: TDateTime read FStartTime write FStartTime;
>     property Started  : Boolean   read FStarted   write FStarted;
>   end;
> 
> implementation
> 
> uses uCronometro;
> { Important: Methods and properties of objects in visual components can only 
> be
>   used in a method called using Synchronize, for example,
> 
>       Synchronize(UpdateCaption);
> 
>   and UpdateCaption could look like,
> 
>     procedure TThreadMonitora.UpdateCaption;
>     begin
>       Form1.Caption := 'Updated in a thread';
>     end; }
> 
> { TThreadMonitora }
> 
> Procedure TThreadMonitora.AtualizaLabel;
>  Begin
>    frmCrometro.Label1.Caption := FormatDateTime('hh:mm:ss:zzz', Now - 
> StartTime);
>  End;
> 
> Procedure TThreadMonitora.Execute;
>  Begin
>   { Place thread code here }
>   while Started do
>     Synchronize(AtualizaLabel);
>  End;
> 
> END.
> (*********************************************************************************************)
> 
> []'s
>  Ricardo.
>  

Responder a