Threads : exemple avec un chronomètre

Description

Suite à une demande sur le forum, voici une application de chronomètrage précise au millième de secondes. Pour le fun, j'ai ajouté l'utilisation d'un thread d'éxécution.

Source / Exemple :


//
// Auteur        : Delphiprog
// Email         : delphi@delphiprog.fr.fm
// Web           : http://www.delphiprog.fr.fm
// Date création : 29/05/2002
// Date révision : 31/08/2003
{  Objet         : Afficher un chronomètre ayant une précision de
                   l'ordre du millième de seconde avec un seul bouton
                   déclenchant les opérations de marche/arrêt.
}
{  remarques     : illustration de l'utilisation d'un thread
                   Ce dernier aurait pu être évité dans cet exemple sauf que,
                   pour ne pas bloquer le processus du chronomètre, il valait
                   mieux utiliser cette méthode.
                   A noter que le calcul continue de se faire même quand
                   la fiche est déplacée ou redimensionnée, contrairement
                   à une application mono thread.
}
unit UChronoFrm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
const
  BtnStartCaption: array[boolean] of ShortString =
  ('Démarrer le chronomètre', 'Arrêter le chronomètre');

type
  //Thread chargé des calculs et de l'affichage
  //du temps écoulé
  TChronoThread = class(TThread)
  private
    { Déclarations privées }
    FDepart: TDateTime;
  protected
    constructor Create(CreateSuspended: Boolean);
    procedure Execute; override;
    procedure AfficherDuree;
  end;

  TChronoForm = class(TForm)
    lblElapsedTime: TLabel;
    btnStart: TButton;
    Label2: TLabel;
    procedure btnStartClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  end;

var
  ChronoForm: TChronoForm;
  ChronoThread: TChronoThread;

implementation

{$R *.DFM}
var
  Stop: boolean = True;

procedure TChronoForm.btnStartClick(Sender: TObject);
begin
  btnStart.Caption := BtnStartCaption[Stop];
  Stop := not Stop;
  if not Stop then
  begin
    //Réinitialisation de l'affichage
    lblElapsedTime.Caption := '00:00:00.000';
    //Lancement du thread en mode suspendu
    ChronoThread := TChronoThread.Create(True);
  end
  else
    //Demander au thread de s'arrêter
    ChronoThread.Terminate;
end;

procedure TChronoForm.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  //Détruire le thread s'il a été créé et s'il
  //est actif au moment de la fermeture de l'application
  if Assigned(Chronothread) then
    if not ChronoThread.Terminated then
      ChronoThread.Terminate;
end;

{ TChronoThread }

constructor TChronoThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  //Détruire à la sortie
  FreeOnTerminate := True;
  //Initialisation de la valeur de départ
  //du chronomètre
  FDepart := Now; 
  //Détermination de la priorité du thread
  Priority := tpNormal;
  //Si le thread est en attente, le démarrer
  if CreateSuspended then
    Resume;
end;

procedure TChronoThread.Execute;
begin
  //Boucler tant que l'utilisateur n'a pas
  //demandé de stopper
  while not Terminated do
    Synchronize(AfficherDuree);
end;

procedure TChronoThread.AfficherDuree;
begin
  ChronoForm.lblElapsedTime.Caption :=
    FormatDateTime('hh:mm:ss.zzz', Now - FDepart);
end;

end.

Conclusion :


Je ne dis pas que c'est hyper précis, mais çà peut donner des idées.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.