Suppression de composants [Résolu]

Signaler
Messages postés
9
Date d'inscription
samedi 4 mars 2006
Statut
Membre
Dernière intervention
9 juin 2007
-
Messages postés
9
Date d'inscription
samedi 4 mars 2006
Statut
Membre
Dernière intervention
9 juin 2007
-
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

Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
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;

Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
31
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/
Messages postés
9
Date d'inscription
samedi 4 mars 2006
Statut
Membre
Dernière intervention
9 juin 2007

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 !!
Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
31
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/