Delphi par l'exemple

 

Retour accueil

Part 1 Part2 Partie 3 : utilisation d'un thread

 

Pour cet exercice nous avons besoin des composants suivants :

- un éditeur de texte
- un mémo

- deux boutons pour lancer et arrêter la lecture

Code source de l'unité :

{ documentation :
http://www.delphifr.com/codes/THREADS-EXEMPLE-AVEC-CHRONOMETRE_11948.aspx }

unit u_Thread;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  { le Thread chargé de la lecture du gps }
  TThreadTrame = class(TThread)
  private
    { Déclarations privées }
  protected
    constructor Create(CreateSuspended: Boolean);
    procedure Execute; override;
    procedure LireTrame;
  end;

  { programme principal }
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    RMCEdit: TEdit;         // affichage de la trame RMC
    TrameMemo: TMemo;       // affichage de toutes les trames reçues
    Label2: TLabel;

    procedure Button1Click(Sender: TObject);   // lancer la lecture du GPS
    procedure Button2Click(Sender: TObject);   // arrêter la lecture du GPS
    procedure AfficherTrame(p_Ligne: String);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
    ThreadTrame: TThreadTrame;
    { g_OK = vrai -> lecture   g_OK = faux -> pas de lecture }
    g_OK: boolean;      // doit être obligatoirement dans TForm1
  end;

var
  Form1: TForm1;
  g_Ligne: String;
  g_Serial: TFILEStream;
  g_Buff: Byte;


implementation

{$R *.DFM}

{----------------------}
{ procédures de TForm1 }
{----------------------}
procedure TForm1.Button1Click(Sender: TObject);
begin
  g_OK := true;
  g_Serial := TFileStream.Create('COM4', fmOpenRead);
  ThreadTrame := TThreadTrame.Create(true);
  while g_OK do begin
    Application.ProcessMessages;
    AfficherTrame(g_Ligne)
  end
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  g_OK := false;
  ThreadTrame.Terminate;
  g_Serial.Free;
end;

procedure TForm1.AfficherTrame(p_Ligne: String);
begin
  ThreadTrame.Suspend;

   { affichage de la trame RMC }
  if Copy(p_Ligne, 4, 3) = 'RMC' then
    Form1.RMCEdit.Text := g_Ligne;
  { affichage des trames dans le mémo }
  { le caractères RC de p_Ligne est supprimé pour ne pas cumuler }
  { les retours de ligne }
  Form1.TrameMemo.Lines.Add(Copy(p_Ligne, 1, Length(p_Ligne)-1));

  ThreadTrame.Resume
end;

{----------------------------}
{ procédures de TThreadTrame }
{----------------------------}
constructor TThreadTrame.Create(CreateSuspended: Boolean);
begin
  Inherited Create(CreateSuspended);
  FreeOnTerminate := true;
  Priority := tpNormal;
  if CreateSuspended then
    Resume
end;

procedure TThreadTrame.Execute;
begin
  while Form1.g_OK do
    Synchronize(LireTrame)
end;

procedure TThreadTrame.LireTrame;
begin
  { lecture de la trame }
  try
    g_Ligne := '';
    try
      repeat
        g_Serial.Read(g_Buff, 1)
      until
        Chr(g_Buff) = '$';
      g_Ligne := g_Ligne + Chr(g_Buff);
      while g_Buff <> 10 do begin
        g_Serial.Read(g_Buff, 1);
        g_Ligne := g_Ligne + Chr(g_Buff)
      end
    except
      MessageDlg('Erreur de communication !', mtError, [mbOK], 0);
    end
  finally

  end;
end; { TThreadTrame.LireTrame }

end. 

Nous obtenons le même résultat que précédemment, mais en utilisant cette fois un thread.

Je recommande au lecteur de lire attentivement l'aide de Delphi sur les threads. Nous n'avons pas utilisé d'unité pour le thread, mais cela est possible comme dans les exemples donnés.

Les procédures de Form1 se réduisent aux procédures ButtonClick.
La procédure Button1Click ouvre la lecture du port COM et crée le Thread ;
la procédure Button2Click termine le Thread et libère le port COM.

Remarque :
au départ, j'avais déclaré la variable g_OK dans la partie var de l'interface et alors une erreur se produisait quand je cliquais qur le bouton Stop (Button2).
Si j'avais relu l'aide de Delphi j'aurais gagné du temps dans la recherche de la cause de ce disfonctionnement.

(à suivre)

Fichiers source thread.zip

Retour accueil

Part 1 Part2