IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Création de thread [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut Création de thread
    bonjour a tous !!

    bon voila je vous explique rapidement mon soucis, j'ai réalisé une application (merci parhelie d'ailleur) permettant de connecter, configurer et receptionner les trames d'un port série.
    voila le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
     
     
    unit UnitMain;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
      StdCtrls, synaser, ExtCtrls,Windows;
     
    type
     
      { TFrmMain }
     
      TFrmMain = class(TForm)
        BtnDetectionPort: TButton;
        BTOuvrir: TButton;
        BTFermer: TButton;
        cbChoixPort: TComboBox;
        cbVitessedetransfert: TComboBox;
        cbBitsdedonnees: TComboBox;
        cbParite: TComboBox;
        cbBitdarret: TComboBox;
        chkHardflow: TCheckBox;
        chkSoftflow: TCheckBox;
        DPS: TImage;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        Label6: TLabel;
        MemoMain: TMemo;
        procedure BTFermerClick(Sender: TObject);
        procedure BtnDetectionPortClick(Sender: TObject);
        procedure BTOuvrirClick(Sender: TObject);
        procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
        procedure FormCreate(Sender: TObject);
         private
        { private declarations }
      public
        { public declarations }
        procedure DetectPortCOM;
      end; 
     
    var
      FrmMain: TFrmMain;
      ser:TBlockSerial;
      stop : boolean;
     
    implementation
     
    { TFrmMain }
     
    //Etape 1 Détection du port COM
     
    procedure TFrmMain.FormCreate(Sender: TObject);
    begin
      //----- creation du port
      ser := TBlockSerial.Create;
      DetectPortCom;
    end;
     
    procedure TFrmMain.BtnDetectionPortClick(Sender: TObject);
    begin
    DetectPortCOm;
    end;
     
      // ----- détection des port COM linux Win32
     
    procedure TFrmMain.DetectPortCOM;
    var
      l: string;
      p: integer;
     
    begin
         cbChoixPort.Clear;
     
    {$IFDEF WIN32}
          l := GetSerialPortNames;
     
         if l >'' then repeat
           begin
              p :=  pos(',',l);
              if p > 0 then
                begin
                  cbChoixPort.Items.Add(copy(L,1,p-1));
                  delete(L,1,p);
                end
              else
                cbChoixPort.Items.Add(L);
            end;
          until p = 0;
    {$ENDIF}
    {$ifdef linux}
     If FileExists('/dev/ttyUSB0') then cbChoixPort.Items.Add('/dev/ttyUSB0');
     If FileExists('/dev/ttyUSB1') then cbChoixPort.Items.Add('/dev/ttyUSB1');
    {$ENDIF}
    end;
     
    //Etape 2 Configuration du port COM
     
    procedure TFrmMain.BTOuvrirClick(Sender: TObject);
    var
      port : string;
      bauds, databit, stopbit: integer;
      parity : char;
      hardflow, softflow : boolean;
     
    begin
      // ----- évite la modification de la configuration du port lors de son fonctionnement
      cbChoixPort.Enabled:=false;
      cbVitessedetransfert.Enabled:=false;
      cbBitsdedonnees.Enabled:=false;
      cbParite.Enabled:=false;
      cbBitdarret.Enabled:=false;
      chkHardflow.Enabled:=false;
      chkSoftflow.Enabled:=false;
      BTOuvrir.enabled:=false;
     
     
      //----- ouverture du port
      port := cbChoixPort.Items[cbChoixPort.itemIndex];
      ser.Connect(port);
      //ser.RaiseExcept:=true;
      //----- parametrage du port
      case cbVitessedeTransfert.itemindex of
           0 : bauds := 9600;
           1 : bauds := 19200;
           2 : bauds := 38400;
           3 : bauds := 57600;
           4 : bauds := 115200;
      end;
     
      case cbBitsdeDonnees.Itemindex of
           0 : databit := 4;
           1 : databit := 5;
           2 : databit := 6;
           3 : databit := 7;
           4 : databit := 8;
      end;
     
      case cbParite.Itemindex of
           0 : parity := 'N';
           1 : parity := 'O';
           2 : parity := 'E';
           3 : parity := 'M';
           4 : parity := 'S';
      end;
     
      case cbBitdarret.itemindex of
           0 : stopbit := SB1;
           1 : stopbit := SB1andHalf;
           2 : stopbit := SB2;
      end;
     
      softflow := chkSoftflow.checked;
      hardflow := chkHardflow.checked;
     
     
      ser.Config(bauds,databit,parity,stopbit,softflow,hardflow);
     
      // ----- Lancement de l'acquisition des trames
     
    stop := false;
      repeat
         memomain.Lines.Add(ser.RecvTerminated(1000,#13#10));
         Application.ProcessMessages;
      until  stop = true;
    end;
     
     
     
    procedure TFrmMain.BTFermerClick(Sender: TObject);
    begin
      // ----- permet la modification de la configuration du port, une fois fermer
      cbChoixPort.Enabled:=true;
      cbVitessedetransfert.Enabled:=true;
      cbBitsdedonnees.Enabled:=true;
      cbParite.Enabled:=true;
      cbBitdarret.Enabled:=true;
      chkHardflow.Enabled:=true;
      chkSoftflow.Enabled:=true;
      BTOuvrir.enabled:=true;
      // ----- fermeture du port COM
      stop := true;
      ser.CloseSocket;
    end;
     
    procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: boolean);
    begin
      //libérer le port
      ser.CloseSocket;
      ser.Free;
    end;
     
    initialization
      {$I unitmain.lrs}
     
    end.
    le code marche parfaitement mais je voudrais juste remplacer la fonction repeat until qui forme une boucle permettant de receptionner les trames par un thread !!
    donc voilà si quelqu'un pouvait m'expliquer comment je peut faire !!
    j'ai déja était voir les pages concernant les thread sur le site mais je saisi pas tout, je débute en programmation !!

    merci d'avance pour votre aide !!

  2. #2
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Points : 2 501
    Points
    2 501
    Par défaut
    Le meiux est de nous dire ce que tu ne comprend pas pour la mise en oeuvre des threads ou, ce qui te bloques.

    Par exemple je trouve les explications données au lien suivant assez claires :
    http://wiki.lazarus.freepascal.org/M...ation_Tutorial

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    merci pour le lien !!

    alors pour commencer est ce que j'ai besoin de rajouter un classe via l'inspecteur de projet !!

    et est que je doit créer une nouvelle unit pour y mettre mon thread ou puis je l'insérer dans mon unit main ?

  4. #4
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Points : 2 501
    Points
    2 501
    Par défaut
    Je crois que c'est mieux de faire une unité à part pour ton thread, ceci pour la lisibilité et la maintenance du code. Mais tu peux toujours tout mettre ensemble si tu veux avoir un programme touffu.

    Tiens nous au courant de la progression.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    ok je pense que je vais tout mettre ensemble si cela ne pose pas de problème car ensuite je ne me servirai plus du code j'utiliserai que les exécutables, et tu n'aurais pas des exemples un peu plus concret que ceux de ton lien ??
    parce que je peine à comprendre sur les exemples données.

    Je souhaite avoir un fonctionnement du genre j'appui sur ouvrir il me lance le thread qui me permet d'acquérir les trames et ensuite le bouton fermer arrête l'acquisition des trames.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    salut darrylsite !

    sur le lien que tu m'as donné, j'ai un petit problème avec la classe TThread quand je compile

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
      procedure TMyThread.Execute;
      var
        newStatus : string;
      begin
        fStatusText := 'TMyThread Starting...';
        Synchronize(@Showstatus);
        fStatusText := 'TMyThread Running...';
        while (not Terminated) and ([any condition required]) do
          begin
            ...
            [here goes the code of the main thread loop]
            ...
            if NewStatus <> fStatusText then
              begin
                fStatusText := newStatus;
                Synchronize(@Showstatus);
              end;
          end;
      end;
    voila l'erreur :
    Fatal: Syntax error, "]" expected but "identifier CONDITION" found

  7. #7
    Membre averti

    Profil pro
    dirlo
    Inscrit en
    Février 2008
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : dirlo

    Informations forums :
    Inscription : Février 2008
    Messages : 83
    Points : 404
    Points
    404
    Par défaut
    [any condition required]

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    [any condition required]
    c'est à dire ?

  9. #9
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Points : 2 501
    Points
    2 501
    Par défaut
    le probleme vient evidemment de là. [any condition required] doit etre remplacer par une expression boolenne.
    ça pourra te servir d'arreter la lecture des trames.
    Si tu definis la classe comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    type TMyThread = class(TThread)
       private
         lecture : boolean;
       public
         function getLectureState() : boolean;
         procedure stopLecture();
     
    ...
     
    //le code du thread
       while (not Terminated) and (lecture) do
          begin
     
           // code à executer       
              end;
          end;
    Le thread sera arreter quand on va appeler la methode stopLecture() qui se contente de mettre lecture à false.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    Ok merci bien, dans mon cas le code à exécuter sera juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memomain.Lines.Add(ser.RecvTerminated(1000,#13#10));

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    voilà ce que j'ai fait pour l'instant :

    unit main
    pour rappel BTOUVRIR doit lancer le thread et BTFERMER doit arrêter le thread

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
     
    unit UnitMain;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
      StdCtrls, synaser, ExtCtrls, unitthread;
     
    type
     
      { TFrmMain }
     
      TFrmMain = class(TForm)
        BtnDetectionPort: TButton;
        BTOuvrir: TButton;
        BTFermer: TButton;
        cbChoixPort: TComboBox;
        cbVitessedetransfert: TComboBox;
        cbBitsdedonnees: TComboBox;
        cbParite: TComboBox;
        cbBitdarret: TComboBox;
        chkHardflow: TCheckBox;
        chkSoftflow: TCheckBox;
        DPS: TImage;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        Label6: TLabel;
        MemoMain: TMemo;
        procedure BTFermerClick(Sender: TObject);
        procedure BtnDetectionPortClick(Sender: TObject);
        procedure BTOuvrirClick(Sender: TObject);
        procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
        procedure FormCreate(Sender: TObject);
      private
        { private declarations }
         MyThread: TMyThread;
         procedure ShowStatus(Status: string);
      public
        { public declarations }
        procedure DetectPortCOM;
      end; 
     
    var
      FrmMain: TFrmMain;
      ser:TBlockSerial;
     
    implementation
     
    { TFrmMain }
     
    //Etape 1 Détection du port COM
     
    procedure TFrmMain.FormCreate(Sender: TObject);
    begin
      //----- creation du port
      ser := TBlockSerial.Create;
      DetectPortCom;
      inherited;
        MyThread := TMyThread.Create(true);
        MyThread.OnShowStatus := @ShowStatus;
     
    end;
     
    procedure TFrmMain.BtnDetectionPortClick(Sender: TObject);
    begin
    DetectPortCOm;
    end;
     
      // ----- détection des port COM linux Win32
     
    procedure TFrmMain.DetectPortCOM;
    var
      l: string;
      p: integer;
     
    begin
         cbChoixPort.Clear;
     
    {$IFDEF WIN32}
          l := GetSerialPortNames;
     
         if l >'' then repeat
           begin
              p :=  pos(',',l);
              if p > 0 then
                begin
                  cbChoixPort.Items.Add(copy(L,1,p-1));
                  delete(L,1,p);
                end
              else
                cbChoixPort.Items.Add(L);
            end;
          until p = 0;
    {$ENDIF}
    {$ifdef linux}
     If FileExists('/dev/ttyUSB0') then cbChoixPort.Items.Add('/dev/ttyUSB0');
     If FileExists('/dev/ttyUSB1') then cbChoixPort.Items.Add('/dev/ttyUSB1');
    {$ENDIF}
    end;
     
    //Etape 2 Configuration du port COM
     
    procedure TFrmMain.BTOuvrirClick(Sender: TObject);
    var
      port : string;
      bauds, databit, stopbit: integer;
      parity : char;
      hardflow, softflow : boolean;
     
    begin
      // ----- évite la modification de la configuration du port lors de son fonctionnement
      cbChoixPort.Enabled:=false;
      cbVitessedetransfert.Enabled:=false;
      cbBitsdedonnees.Enabled:=false;
      cbParite.Enabled:=false;
      cbBitdarret.Enabled:=false;
      chkHardflow.Enabled:=false;
      chkSoftflow.Enabled:=false;
      BTOuvrir.enabled:=false;
     
     
      //----- ouverture du port
      port := cbChoixPort.Items[cbChoixPort.itemIndex];
      ser.Connect(port);
     
      //----- parametrage du port
      case cbVitessedeTransfert.itemindex of
           0 : bauds := 9600;
           1 : bauds := 19200;
           2 : bauds := 38400;
           3 : bauds := 57600;
           4 : bauds := 115200;
      end;
     
      case cbBitsdeDonnees.Itemindex of
           0 : databit := 4;
           1 : databit := 5;
           2 : databit := 6;
           3 : databit := 7;
           4 : databit := 8;
      end;
     
      case cbParite.Itemindex of
           0 : parity := 'N';
           1 : parity := 'O';
           2 : parity := 'E';
           3 : parity := 'M';
           4 : parity := 'S';
      end;
     
      case cbBitdarret.itemindex of
           0 : stopbit := SB1;
           1 : stopbit := SB1andHalf;
           2 : stopbit := SB2;
      end;
     
      softflow := chkSoftflow.checked;
      hardflow := chkHardflow.checked;
     
     
      ser.Config(bauds,databit,parity,stopbit,softflow,hardflow);
     
      // ----- Lancement de l'acquisition des trames
     
      MyThread.Resume;
    end;
     
    procedure TFrmMain.ShowStatus(Status: string);
       begin
       MemoMain.Caption := Status;
       end;
     
     
    procedure TFrmMain.BTFermerClick(Sender: TObject);
    begin
      // ----- permet la modification de la configuration du port, une fois fermer
      cbChoixPort.Enabled:=true;
      cbVitessedetransfert.Enabled:=true;
      cbBitsdedonnees.Enabled:=true;
      cbParite.Enabled:=true;
      cbBitdarret.Enabled:=true;
      chkHardflow.Enabled:=true;
      chkSoftflow.Enabled:=true;
      BTOuvrir.enabled:=true;
      // ----- fermeture du port COM
      ser.CloseSocket;
      ser.Free;
      // ----- fermer le thread
      MyThread.Terminate;
      //MyThread.Free;
      inherited;
    end;
     
    procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: boolean);
    begin
      //libérer le port
      ser.CloseSocket;
      ser.Free;
    end;
     
    initialization
      {$I unitmain.lrs}
     
    end.
    unit thread
    doit éxecuter l'acquisition des trames

    unitThread

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    unit UnitThread;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, unitmain;
     
    Type
        TShowStatusEvent = procedure(Status: String) of Object;
        TMyThread = class(TThread)
        private
          MyThread: TMyThread;
          lecture : boolean;
          fStatusText : string;
          FOnShowStatus: TShowStatusEvent;
          procedure ShowStatus;
        protected
          procedure Execute; override;
        public
          //function getLectureState(): boolean;
          //procedure stopLecture();
          Constructor Create(CreateSuspended : boolean);
          property OnShowStatus: TShowStatusEvent read FOnShowStatus write FOnShowStatus;
        end;
     
     
    implementation
     
     constructor TMyThread.Create(CreateSuspended : boolean);
      begin
        FreeOnTerminate := true;
        inherited Create(CreateSuspended);
      end;
     
     
     procedure TMyThread.ShowStatus;
      // this method is executed by the mainthread and can therefore access all GUI elements.
      begin
        if Assigned(FOnShowStatus) then
        begin
          FOnShowStatus(fStatusText);
        end;
      end;
     
     
    procedure TMyThread.Execute;
      var
      newStatus : string;
      begin
        fStatusText := 'TMyThread starting...';
        Synchronize(@Showstatus);
        fStatusText := 'TMyThread Running...';
        while (not Terminated) and (lecture) do
          begin
            //...
            //[code à exécuter]
            //...
            if NewStatus <> fStatusText then
              begin
                fStatusText := newStatus;
                Synchronize(@Showstatus);
              end;
          end;
      end;
     
     
    initialization
     
     
    end.
    quand j'utilise le code memomain.lines.add(ser.RecvTerminated(1000,#13#10)); dans mon unit Thread il me met une erreur Identifier not found "memomain" alors que j'utilise bien unitmain.

  12. #12
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Points : 2 501
    Points
    2 501
    Par défaut
    C'est tout à fait normal puisque memomain est un attribut d'une classe de type TFrmMain.
    Un moyen de regler ça est d'ajouter un attribut memomain dans la classe du thread, que tu initialisera par TFrmMain.memomain . Pour celà, tu crée une methode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure setMemo(Memo: TMemo)
    begin
     MemoMain:=memo;
    end;
    dans la classe etendant le tthread. et appeler cette methode lors de l'initialisation du thread.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure TFrmMain.FormCreate(Sender: TObject);
    begin
      //----- creation du port
      ser := TBlockSerial.Create;
      DetectPortCom;
      inherited;
        MyThread := TMyThread.Create(true);
        MyThread.OnShowStatus := @ShowStatus;
        MyThread.setMemo(MemoMain);
     
    end;

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    j'ai fait la modification mais j'obtient une erreur: Identifier not Found "TMemo"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    unit UnitThread;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, synaser;
     
    Type
        TShowStatusEvent = procedure(Status: String) of Object;
        TMyThread = class(TThread)
        private
          ser: TBlockSerial;
          MyThread: TMyThread;
          lecture : boolean;
          fStatusText : string;
          FOnShowStatus: TShowStatusEvent;
          procedure ShowStatus;
        protected
          procedure Execute; override;
        public
          //function getLectureState(): boolean;
          //procedure stopLecture();
          procedure setMemo(Memo: TMemo);
          Constructor Create(CreateSuspended : boolean);
          property OnShowStatus: TShowStatusEvent read FOnShowStatus write FOnShowStatus;
        end;
     
     
    implementation
     
     constructor TMyThread.Create(CreateSuspended : boolean);
      begin
        FreeOnTerminate := true;
        inherited Create(CreateSuspended);
      end;
     
     
     procedure TMyThread.ShowStatus;
      // this method is executed by the mainthread and can therefore access all GUI elements.
      begin
        if Assigned(FOnShowStatus) then
        begin
          FOnShowStatus(fStatusText);
        end;
      end;
     
     
    procedure TMyThread.setMemo(Memo: Tmemo);
    begin
     MemoMain:=Memo;
    end;
     
    procedure TMyThread.Execute;
      var
      newStatus : string;
      begin
        fStatusText := 'TMyThread starting...';
        Synchronize(@Showstatus);
        fStatusText := 'TMyThread Running...';
        while (not Terminated) and (lecture) do
          begin
            //...
            //[code à exécuter]
            MemoMain.lines.add(ser.RecvTerminated(1000,#13#10));
            //...
            if NewStatus <> fStatusText then
              begin
                fStatusText := newStatus;
                Synchronize(@Showstatus);
              end;
          end;
      end;
     
     
    initialization
     
     
    end.
    et pour les procedures stopLecture et getLectureState je met juste respectivement lecture:=false; et lecture:=true;

  14. #14
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Points : 2 501
    Points
    2 501
    Par défaut
    je crois que c'est un probleme d'unité. Puisque tu l'as utilisé dans unitmain. Je ne sais de quelle unité il s'agit, mais tu peux facilement le savoir en essayant d'ajouter un à un les unité utilisées dans unitmain
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    uses
     Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
      StdCtrls, synaser, ExtCtrls, unitthread;
    .
    pour les procedures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function TMyThread.getLectureState() :boolean;
    begin
     //cette fonction te donne l'etat de la variable lecture
     getLectureState: lecture;
    end.
    //--------------------------
    procedure TMyThread.stopLecture() ;
    begin
     //cette fonction met lecture à false, ce qui revient 
     //à arreter la boucle du thread
     lecture:=false;
    end.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    en effet j'ai rajouté les unités et plus d'erreur sur "TMemo", mais il me remet maintenant erreur Identifier not Found "MemoMain" !!

    et pour remettre ma variable sur true il faut que je recrée une autre procédure car je veux pouvoir arrêter l'acquisition des trames et les relancer ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    unit UnitThread;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, LResources, Forms, Controls, Graphics, synaser, FileUtil, Dialogs,
      StdCtrls, ExtCtrls;
     
    Type
        TShowStatusEvent = procedure(Status: String) of Object;
        TMyThread = class(TThread)
        private
          ser: TBlockSerial;
          MyThread: TMyThread;
          lecture : boolean;
          fStatusText : string;
          FOnShowStatus: TShowStatusEvent;
          procedure ShowStatus;
        protected
          procedure Execute; override;
        public
          function getLectureState(): boolean;
          procedure stopLecture();
          procedure setMemo(Memo: TMemo);
          Constructor Create(CreateSuspended : boolean);
          property OnShowStatus: TShowStatusEvent read FOnShowStatus write FOnShowStatus;
        end;
     
     
    implementation
     
     constructor TMyThread.Create(CreateSuspended : boolean);
      begin
        FreeOnTerminate := true;
        inherited Create(CreateSuspended);
      end;
     
     
     procedure TMyThread.ShowStatus;
      // this method is executed by the mainthread and can therefore access all GUI elements.
      begin
        if Assigned(FOnShowStatus) then
        begin
          FOnShowStatus(fStatusText);
        end;
      end;
     
    function TMyThread.getLectureState(): boolean;
    begin
     getLectureState: lecture;
    end;
     
    procedure TMyThread.stopLecture();
    begin
    lecture:=false;
    end;
     
    procedure TMyThread.setMemo(Memo: Tmemo);
    begin
     MemoMain:=Memo;
    end;
     
    procedure TMyThread.Execute;
      var
      newStatus : string;
      begin
        fStatusText := 'TMyThread starting...';
        Synchronize(@Showstatus);
        fStatusText := 'TMyThread Running...';
        while (not Terminated) and (lecture) do
          begin
            //...
            //[code à exécuter]
            MemoMain.lines.add(ser.RecvTerminated(1000,#13#10));
            //...
            if NewStatus <> fStatusText then
              begin
                fStatusText := newStatus;
                Synchronize(@Showstatus);
              end;
          end;
      end;
     
     
    initialization
     
     
    end.

  16. #16
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Points : 2 501
    Points
    2 501
    Par défaut
    je t'avais dit de ajouter un attribut memoMain. A moins que tu ne sais pas ce que veut dire attribut d'un objet auquel, je te conseille de chercher un tutoriel sur la poo.
    Ajouter un attribut, revient à declarer une variable qui pourra etre utilisée dans toute la classe.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    TMyThread = class(TThread)
        private
         //liste des attributs
          ser: TBlockSerial;
          MyThread: TMyThread;
          lecture : boolean;
          fStatusText : string;
          FOnShowStatus: TShowStatusEvent;
          memoMain : TMemo; // notre attribut memoMain
    Si tu met lecture à false, tu arrete definitivement le thread, à moins de le relancer (methode resume je crois). Si tu veux, tu peux faire dormir le thread.

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    en effet je ne savais pas, la programmation n'étant pas du tout mon dommaine, j'ai commencé de programmer il y a trois semaine donc il est vrai que je ne comprend pas bien d'où viennent les erreurs.

    en tout cas le problème du mémo est passé maintenant le soucis c'est la procédure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function TMyThread.getLectureState(): boolean;
    begin
     getLectureState: lecture;
    end;
    j'ai l'erreur suivante: syntax error,";" expected but ":" found

  18. #18
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Euh, ca ne correspond à rien cette instruction... C'est une déclaration de variable (dans ce cas il faut mettre une clause var avant le begin) ? C'est une affectation (dans ce cas, il faut mettre :=) ? Où est la variable lecture ?
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  19. #19
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 44
    Points : 11
    Points
    11
    Par défaut
    la variable lecture est déjà déclaré regarde le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    unit UnitThread;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, LResources, Forms, Controls, Graphics, synaser, FileUtil, Dialogs,
      StdCtrls, ExtCtrls;
     
    Type
        TShowStatusEvent = procedure(Status: String) of Object;
        TMyThread = class(TThread)
        private
          ser: TBlockSerial;
          MyThread: TMyThread;
          lecture : boolean;
          fStatusText : string;
          FOnShowStatus: TShowStatusEvent;
          MemoMain : TMemo;
          procedure ShowStatus;
        protected
          procedure Execute; override;
        public
          function getLectureState(): boolean;
          procedure stopLecture();
          procedure setMemo(Memo: TMemo);
          Constructor Create(CreateSuspended : boolean);
          property OnShowStatus: TShowStatusEvent read FOnShowStatus write FOnShowStatus;
        end;
     
     
    implementation
     
     constructor TMyThread.Create(CreateSuspended : boolean);
      begin
        FreeOnTerminate := true;
        inherited Create(CreateSuspended);
      end;
     
     
     procedure TMyThread.ShowStatus;
      // this method is executed by the mainthread and can therefore access all GUI elements.
      begin
        if Assigned(FOnShowStatus) then
        begin
          FOnShowStatus(fStatusText);
        end;
      end;
     
    function TMyThread.getLectureState(): boolean;
    begin
     getLectureState: lecture;
    end;
     
    procedure TMyThread.stopLecture();
    begin
    lecture:=false;
    end;
     
    procedure TMyThread.setMemo(Memo: Tmemo);
    begin
     MemoMain:=Memo;
    end;
     
    procedure TMyThread.Execute;
      var
      newStatus : string;
      begin
        fStatusText := 'TMyThread starting...';
        Synchronize(@Showstatus);
        fStatusText := 'TMyThread Running...';
        while (not Terminated) and (lecture) do
          begin
     
            // -----  code à exécuter
            MemoMain.lines.add(ser.RecvTerminated(1000,#13#10));
     
            if NewStatus <> fStatusText then
              begin
                fStatusText := newStatus;
                Synchronize(@Showstatus);
              end;
          end;
      end;
     
     
    initialization
     
     
    end.
    lecture : boolean;

  20. #20
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Points : 2 501
    Points
    2 501
    Par défaut
    c'est une erreur de ma part.Mais ça devait rapidement etre corrigée puisque je veux que la fonction retourne la valeur de la variable lecture.
    C'est plutot une affectation := au lieu de =.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function TMyThread.getLectureState(): boolean;
    begin
     getLectureState:= lecture;
    end;

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Création de "thread" (?)
    Par Dom_the_quaker dans le forum Delphi
    Réponses: 1
    Dernier message: 03/01/2007, 16h49
  2. [c#] Création de Threads
    Par OtI$ dans le forum Windows Forms
    Réponses: 1
    Dernier message: 09/10/2006, 20h26
  3. erreur à la création de thread
    Par thony76 dans le forum Visual C++
    Réponses: 5
    Dernier message: 28/07/2006, 11h26
  4. Modélisation de création de thread
    Par GETah dans le forum UML
    Réponses: 1
    Dernier message: 22/07/2006, 10h10
  5. Problème de création de thread
    Par [Silk] dans le forum Langage
    Réponses: 2
    Dernier message: 31/01/2006, 21h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo