Suppression de composants

Résolu
xzenou Messages postés 9 Date d'inscription samedi 4 mars 2006 Statut Membre Dernière intervention 9 juin 2007 - 3 mars 2007 à 14:12
xzenou Messages postés 9 Date d'inscription samedi 4 mars 2006 Statut Membre Dernière intervention 9 juin 2007 - 4 mars 2007 à 10:42
Bonjour;
J'ai bien sur une question à poser, j'utilise des composants Tlabel que je crée 'dynamiquement' avec une simple fonction create.
Quand je ferme la form(la 2 dans mon programme) j'aimerais supprimer ces composants (Tlabel). J'ai pourtant essayé d'utiliser la méthode du tag, mais au lancement du programme il m'indique un Hors limite. Voici la partie du code :
Creation du Tlabel :
               labtest:=tlabel.Create(self);
               labtest.Parent:=self;
               labtest.tag:=2;
               labtest.Name:='lab' + components[i].Name ; //le components[i].name est un tedit

A la fermeture de la form j'utilise :
  for i:=0 to pred(componentcount) do
    begin
        components[i].Tag=2 then
        components[i].Destroy;
    end;

Quand je ferme la form, la première fois 1 tlabel sur 2 est supprimer puis une erreur hors limite, ensuite je relance la fermeture puis les derniers sont retirés et je peux enfin fermer ma form tranquilement.

Voila tout merci d'avance.

4 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
3 mars 2007 à 14:47
c'est simple a resoudre :

type
  TLabelArray : array of TLabel;

var
  DynLabels : TLabelArray;

procedure FreeLabels(var Labels : TLabelArray);
var N : integer;
begin
  if Length(Labels) <> 0 then
  begin
     for N := High(Labels) downto 0 do
         if Assigned(Labels[N]) then
            FreeAndNil(Labels[N]);

     SetLength(Labels, 0);
  end;
end;

procedure CreateLabels(var Labels : TLabelArray; const Count : integer; const NamePrefix : string; AOwner : TComponent);
var N : integer;
begin
  if Length(Labels) <> 0 then
     FreeLabels;

  SetLength(Labels, Count);

  for N := 0 to High(Labels) do

  begin

    Labels[N] := TLabel.Create(AOwner);

    with Labels[N] do
    begin

      Parent := AOwner;

      Name   := 'Lab'+NamePrefix+'IntToStr(N);

    end;

  end;
end;

procedure TForm2.Form2Create(Sender : TObject);
begin
  CreateLabels(DynLabels, 10, EdtLabelNamer.Text, Self);
end;

procedure TForm2.Form2Destroy(Sender : TObject);
begin
  FreeLabels(DynLabels);
end;

0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
3 mars 2007 à 18:11
Sans vouloir faire de polémique, je dis que copier les composants dans un tableau revient à dupliquer les références contenues dans la propriété Components de la fiche propriétaire. Ce n'est jamais bon de dupliquer. Tôt ou tard, ça amène des problèmes quand on est désynchronisé.

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
http://www.afipa.net/
0
xzenou Messages postés 9 Date d'inscription samedi 4 mars 2006 Statut Membre Dernière intervention 9 juin 2007
4 mars 2007 à 10:42
Je crois que je vais opté, même que j'ai opté pour la solution du décomptage. C'est vrai que je n'avais pas pensé que l'indice des composants changé..
merci de me l'avoir appris !!
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
3 mars 2007 à 14:37
A dire vrai, comme la fiche est propriétaire des composants TLabel que tu crées dynamiquement, il n'est pas nécessaire de les détruire explicitement. Un propriétaire est (normalement) toujours chargé de la destruction des composants placés sous sa responsabilité.

Pour répondre à ta question, la réponse est simple.
Si tu parcours la liste des composants détenus par la fiche du premier au dernier, tu obtiens toujours cette erreur.
Explications : lors du premier tour de la boucle, l'index vaut zéro et tu détruis bien le premier élément. Au deuxième tour, l'index vaut 1. Seuleument, ce qui était le deuxième composant au départ est devenu le premier entre temps ! Eh oui, componentCount n'est pas révalué à chaque tour de boucle.

Il y a donc deux techniques pour réaliser la destruction de composants.
1- détruire autant de fois l'élément d'indice 0 qu'il y a d'éléments dans la liste
2- détruire du dernier au premier élément contenu dans le liste :
  for i:= pred(componentcount) downto 0 do
    begin
        if components[i].Tag = 2 then
          components[i].Destroy;
    end;

May Delphi be with you !
<hr color="#008000" />
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
http://www.afipa.net/
-2
Rejoignez-nous