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. >