Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

THREAD ET CRÉATION DYNAMIQUE DES COMPOSANTS


Information sur la source

Catégorie :Exécution Classé sous : thread, dynamique, threads, create, destroy Niveau : Débutant Date de création : 11/06/2006 Date de mise à jour : 12/06/2006 04:28:32 Vu / téléchargé: 3 719 / 819

Note :
9 / 10 - par 3 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (7)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
Ce code donne un exemple de la création d'un tprogressbar,tbutton et tcheckbox dynamiquement sur la fiche et son controle a travers un thread.
Ceci est mon premier code.
Il manque encore des commmentaires, mais ils seront bientôt.
Je voudrais que vous y jetez un coup d'oeil, corriger des fautes, donner des remarques .....
merci

 

Conclusion

Le button create permet de créer un nouveau thread, avec ses composants sur la fiche.
Le button Destroy permet de détruire les threads qui on le checkbox activé.
le zone d'edition contient le temps qui sera pris par chaque thread en millisecondes pour incrementer le progressbar.
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  • Project1.~dprTélécharger ce fichier [Réservé aux membres club]188 octets
  • Project1.cfgTélécharger ce fichier [Réservé aux membres club]Voir ce fichier434 octets
  • Project1.dofTélécharger ce fichier [Réservé aux membres club]Voir ce fichier2 015 octets
  • Project1.dprTélécharger ce fichier [Réservé aux membres club]Voir ce fichier219 octets
  • Project1.resTélécharger ce fichier [Réservé aux membres club]876 octets
  • UMaTache.~pasTélécharger ce fichier [Réservé aux membres club]1 851 octets
  • UMaTache.dcuTélécharger ce fichier [Réservé aux membres club]2 925 octets
  • UMaTache.pasTélécharger ce fichier [Réservé aux membres club]Voir ce fichier1 851 octets
  • Unit1.~ddpTélécharger ce fichier [Réservé aux membres club]51 octets
  • Unit1.~dfmTélécharger ce fichier [Réservé aux membres club]938 octets
  • Unit1.~pasTélécharger ce fichier [Réservé aux membres club]2 577 octets
  • Unit1.dcuTélécharger ce fichier [Réservé aux membres club]5 887 octets
  • Unit1.ddpTélécharger ce fichier [Réservé aux membres club]51 octets
  • Unit1.dfmTélécharger ce fichier [Réservé aux membres club]938 octets
  • Unit1.pasTélécharger ce fichier [Réservé aux membres club]Voir ce fichier2 578 octets

Télécharger le zip

Historique

12 juin 2006 04:28:32 :
Déclaration de la classe TMaThread dans un nouveau unité. Quelques autres corrections proposés par Delphiprog.

Commentaires et avis

signaler à un administrateur
Commentaire de bhmalek le 11/06/2006 11:24:03

J'attends vos remarques, je sais bien que mon travail est décevant, et c'est justement pourquoi je l'ai posté.
Je commence dans delphi et j'aimerai corriger mes fautes dés le debut, allez jetez pour une fois un coup d'oeil sur la source et dites moi quesque vous en pensez ...

signaler à un administrateur
Commentaire de John Dogget le 11/06/2006 17:18:02

Non, c'est pas decevant, je trouve ça pas mal ;-)
C'est une illustration de l'utilisation des thread et de la création de compo à la volée -> pas mal.

7/10 :)

signaler à un administrateur
Commentaire de Delphiprog le 11/06/2006 17:56:13 administrateur CS

Très bon travail, bien au contraire.

Voici quelques pistes d'améliorations :
- tu masques les problèmes de portée en déclarant la classe TMaTache dans la même unité que TForm1. En agissant ainsi, le constructeur que tu as déclaré en protected devient accessible.
Pour mieux structurer ton travail, je te recommande de déclarer TMaTache dans une autre unité comme ceci :

unit UMaTache;

interface

uses
  Classes, SysUtils, StdCtrls, ComCtrls, Controls;

type
  TMaTache = class(TThread)
  private
    barre: TProgressbar;
    button: TButton;
    vitesse: integer;
    pause: boolean;
  protected
    procedure buttonclick(Sender: TObject);
    procedure construire(parent: TWinControl; y: integer);
    procedure execute; override;
    procedure detruire(Sender: tobject);
  public
    boite: TCheckBox;
    constructor Create(parent: TWinControl; y, v: integer);
  end;

implementation

{ TMaTache }

procedure TMaTache.buttonclick(Sender: TObject);
begin
  if barre.position = barre.Max then
  begin
    barre.Position := 0;
    pause := false;
  end
  else
    Pause := not Pause;

  if pause then
    button.Caption := 'Continue'
  else
    button.Caption := 'Stop';
end;

procedure TMaTache.construire(parent: twincontrol; y: integer);
begin
  barre := tprogressbar.Create(parent);
  barre.Parent := parent;
  barre.SetBounds(30, y, 300, 20);

  boite := tcheckbox.Create(parent);
  boite.Parent := parent;
  boite.SetBounds(10, y, 14, 17);
  boite.checked := false;
  boite.Caption := '';

  button := tbutton.Create(parent);
  button.Parent := parent;
  button.SetBounds(340, y-5, 70, 30);
  button.Caption := 'Stop';
  button.OnClick := buttonclick;

  pause := false;
end;

constructor TMaTache.Create(parent: twincontrol; y, v: integer);
begin
  inherited create(false);
  FreeOnTerminate := true;
  construire(parent, y);
  vitesse := v;
  OnTerminate := detruire;
end;

procedure TMaTache.detruire(Sender: tobject);
begin
  barre.Free;
  button.Free;
  boite.Free;
  inherited terminate;
end;

procedure TMaTache.execute;
var
  i: integer;
begin
  repeat
    sleep(vitesse);
    i := barre.Position;
    if not pause then
      barre.Position := i + 1;
      
    if i = Barre.Max then
      button.Caption := 'Restart';
  until terminated;
end;

end.

Au passage, tu auras remarqué quelques restructurations, simplifications et optimisations du code :o).
En effet, à chaque fois que tu modifies les propriétés Top, Left, Height ou Width d'un composant visuel, ce dernier est redessiné. Avec le méthode SetBounds, il n'est redessiné qu'une fois.
A noter aussi que seuls le constructeur et la propriété Boite ont besoin d'être exposés à l'extérieur de la classe et doivent donc figurer en section Public.

Au niveau de l'unité Unit1 (maintenant allégée), on trouve le code restant avec quelques réaménagements commentés plus bas :
type
  TForm1 = class(TForm)
    btnCreate: TButton;
    btnDestroy: TButton;
    Edit1: TEdit;
    XPManifest1: TXPManifest;
    procedure FormCreate(Sender: TObject);
    procedure btnCreateClick(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure btnDestroyClick(Sender: TObject);
  private
    function FirstFree: integer;
    {Redimensionne la fenêtre en fonction du nombre
    de Threads actifs}
    procedure ResizeWindow(Nombre: integer);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

uses UMaTache;

{$R *.dfm}
var
  MesTaches: array of TMaTache;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //inutile => setlength(MesTaches, 0);
end;

procedure TForm1.btnCreateClick(Sender: TObject);
var
  i: integer;
begin
  i := length(MesTaches);
  if FirstFree = 0 then
  begin
    setlength(MesTaches, i + 1);
    ResizeWindow(i);
  end
  else
    i := FirstFree - 1;

  MesTaches[i] := TMaTache.Create(Self, ((30 * i) + 10), StrToIntDef(edit1.Text, 0));
end;

procedure TForm1.Edit1Change(Sender: TObject);
var
  i: integer;
begin
  i := StrToIntDef(edit1.Text, 0);
  btnCreate.Enabled := (i > 0) and (i < 10000);
end;

function TForm1.FirstFree: integer;
var
  i: integer;
begin
  result := 0;
  for i := length(MesTaches) - 1 downto 0 do
    if not assigned(MesTaches[i]) then
      result := i + 1;
end;

procedure TForm1.btnDestroyClick(Sender: TObject);
var
  i, j: integer;
begin
  i := length(MesTaches);
  if i = 0 then
    exit;
  for j := 0 to i - 1 do
  begin
    if MesTaches[j] = nil then
      continue;
    if MesTaches[j].boite.checked then
    begin
      MesTaches[j].Terminate;
      MesTaches[j] := nil;
    end;
  end;
  j := i - 1;
  while MesTaches[j] = nil do
  begin
    dec(i);
    dec(j);
  end;
  setlength(MesTaches, i);

  ResizeWindow(i);
end;

procedure TForm1.ResizeWindow(Nombre: integer);
begin
  Height := 90 + Nombre * 30;
  btnCreate.Top := Height - 60;
  btnDestroy.Top := Height - 60;
  edit1.Top := Height - 58;
end;

Observations :
- bien que ce ne soit pas une erreur, il est habituel de déclarer tes propres routines en section Public ou Private et non dans la section par défaut (bien que cette dernière soit en réalité de portée Public).
- le code dans Edit1Change a été simplifié
- le code dupliqué redimensionnant la fenêtre Form1 a été déplacé dans une méthode nommée ResizeWindow

En déclarant chaque classe dans son unité propre, c'est aussi le meilleur moyen de permettre sa réutilisation.
Si je n'avais qu'une critique à faire, ce serait celle-ci.

Globalement, tu as bien travaillé et tu es sur la bonne voie ;o)

signaler à un administrateur
Commentaire de bhmalek le 12/06/2006 04:43:46

Merci beaucoup pour vos remarques encourageantes.
Encore plus pour la note.
Et encore plus pour la correction de Delphiprog qui a pris la peine de lire mon code et de le corriger dans sa totalité.
Je viens juste de rejoindre la communauté de delphifr.com, et me voila le bienvenu &#8230;

signaler à un administrateur
Commentaire de MAURICIO le 12/06/2006 16:53:54

Salut Bhmalek,
ta source m' a interessé parce que Delphiprog et moi même avons étudié les threads (pour faire une boite de dialogue avec gauge pour faire patienter l' utilisateur ...) et que nous sommes tombés sur un os.
Malheureusement tu ne résouds pas non plus le problème qui est, s' il existe un autre processus bloquant, celui-ci empêchera tes gauges d' avancer...

Voilà comment tu peux tester ce que je dit:
Mets un bouton sur ta form avec le code suivant:

procedure TForm1.SpeedButton1Click(Sender: TObject);
var i: integer;
begin
  for i := 0 to 99 do
    sleep(100);
end;

Ensuite tu compiles et tu executes une ou 2 gauges et tu cliques sur le bouton que je te propose et tu verras que ta gauge s' arrête tans que le code dans le bouton n' est pas fini...

Malheureusement nous n' avons pas trouvé de solution à ce problème.
Ici on pourrait résoudre le problème gràce à l' utilisation de application.ProcessMessages dans le For mais cela serait impossible lors de l' execution d' un code SQL par exemple.

Très bonne 1ere source tout de même !!!

A+

signaler à un administrateur
Commentaire de Delphiprog le 12/06/2006 23:13:07 administrateur CS

Mauricio : le test que tu donnes est un peu faussé.
Je m'explique : quand les threads secondaires doivent se synchroniser avec le thread principal et que ce dernier est bloqué, comment veux-tu que l'interface soit réactive ?
A moins de modifier le code de la procédure Sleep, on ne peut pas faire autrement. Mais rien ne t'empêche d'écrire ta propre procédure équivalente à Sleep et d'y inclure un appel à Application.ProcessMessages.

signaler à un administrateur
Commentaire de Francky23012301 le 15/06/2006 20:49:33

Salut,

Je viens de (re)regarder ta source : bon boulot ;).

Je me permets de faire quelques remarques :

*Il aurait été plus judicieux dans un esprit de pédagogie que tu fasses deux sources :
-Une sur la création dynamique d'un composant.
-Une sur la création et utilisation d'un Thread.
En effet un débutant risque d'etre un peu paumé ;).

*Tu devrais profiter de ce post pour faire un tuto sur les Threads et sur la création des composants. On manque cruellement de tutos sur CS et les meilleurs tutos de débutants sont ceux faits par les débutants (je dis ca car il y a deja des tutos sur les composants mais ils sont à mon gout d'un niveau et d'une formulation peu accessible pour les débutants).

Tu peux encore proposer des sources comme ca : je suis preneur ^^.

A+

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Création dynamique de fiche [ par seeev ] Salut, Dans mon appli, je crée une fiche type TForm1, lorsqu'elle est appelée au démarrage ou plus tard par application.create(TForm1, Form1), pas de Comment dialoguer entre deux threads [ par nicolaspennaneach ] Voilà, j'ai deux threads. Un gère les entrées claviers et l'autre gère la connection à une machine distante en telnet.Ce que je souhaiterai savoir c'e threads [ par sisi231 ] SISI231Je me suis mis aux threads y'a 2 jours : j'ai un peu compris , j'ai corrigé une erreur grace à synchronize mais il en reste une : (petite expli THREAD [ par LHOLVOET ] Bonjour,J'ai écris un programme en VB qui utilise des THREADS (indispensable pour ce programme).Malheureusement, VB plante sans cesse avec les threads TQuery et thread [ par Fandril ] Est ce que quelqu un a deja mis un TQuery (pour executer requete SQL select sur Paradox) dans un thread...Car ca marche mais ca met 10 secondes pour Threads [ par valkyrie ] Bonjour a tout le mondemon prog plante inelucablement des que je bouge la fenetre pendant son execution ou que je clique sur un autre truc......l exec OpenGL et Threads [ par FleX2009 ] Bonjour &#224; tous, voil&#224; j'ai un petit probl&#232;me : je veux dessiner en OpenGL dans un thread, mon algo est du type : Boucle Dessin Fin bou Question bête sur les threads ! [ par BKnet ] Bonjour tout le monde, J'aimerai savoir si on peut associer un &#233;v&#232;nement sur un thread ? Si oui comment ? Si non y a t'il une autre solutio Threads et events [ par Danonne ] Salut a tous.Après de nombreuses recherches sur divers sites et forums, je n'ai pas réussi à trouver une réponse (claire et précise) à ma question exi Problème création thread [ par VolaiL ] Bonjour, j'ai un petit problème de création de thread.Je souhaiterai lancer le thread lorsqu'on appuie sur enter, mais ca bloque dès la crétion sur "i


Nos sponsors

Sondage...

CalendriCode

Septembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
2930     

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,42 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.