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

C++Builder Discussion :

Création et destruction dynamique de composants visuels


Sujet :

C++Builder

  1. #1
    Candidat au Club
    Inscrit en
    Octobre 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Création et destruction dynamique de composants visuels
    Salut,

    Je me résous à solliciter votre aide car je ne comprends vraiment pas le problème de mon code.

    J'ai un vecteur (appelé "zobi") contenant des pointeurs vers des objets d'une classe que j'ai créée. Ces objets sont listés dans un TListView. Quand je clique sur un élément du TListView (correspondant à un objet du vecteur), je vérifie une propriété de l'objet en question et je crée dynamiquement des TLabeledEdit en nombre variable (4 ou 5 selon l'objet).
    Bon, j'ai rien fait d'original (cf. le code plus bas) : quand l'utilisateur clique sur la liste, je repère qui a été cliqué, je consulte l'objet à travers le vecteur, j'en déduis de combien de TLabeledEdit j'ai besoin et je les crée dans une boucle. Pour garder une trace, je stocke les pointeurs vers ces TLabeledEdit dans une TList (appelée "zobo"). A chaque fois qu'un élément du TListView est cliqué, je détruis tous les TLabeledEdit, je vide la TList et j'en crée de nouveaux.

    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
     
    void __fastcall TForm1::ListView1Click(TObject *Sender)
    {
    ItemSelec = -1;
    if (ListView1->ItemIndex >= 0) ItemSelec = ListView1->ItemIndex;
     
    if (ItemSelec >= 0)
            {
            if (zobo->Count > 0)
                    {
                    for (int i = zobo->Count - 1 ; i >= 0 ; i--)
                            {
                            delete (TLabeledEdit* )zobo->Items[i];
                            }
                    }
            zobo->Clear();
            for (int i = 0 ; i < zobi.at(ItemSelec).GetParamNb() ; i ++)
                    {
                    TLabeledEdit *NewEdit = new TLabeledEdit(Form1);
                    //TLabeledEdit *NewEdit = new TLabeledEdit(this);
                    zobo->Add(( void*)NewEdit);
                    NewEdit->Text = FloatToStr(zobi.at(ItemSelec).GetIndParam(i));
                    NewEdit->EditLabel->Caption = "Parameter " + IntToStr(i);
                    NewEdit->Parent = Form1->Panel1;
                    NewEdit->Left = 10;
                    NewEdit->Top = zobo->Count * 40;
                    }
            }
    }
    A l'exécution, si j'ai 2 éléments dans le vecteur (et donc la TListView), je clique le premier, ça roule, les TLabeledEdit apparaissent. Je clique sur le suivant plantage tentative d'écriture à l'adresse 0x0000000. Au pas-à-pas, ça arrive à la ligne "TLabeledEdit *NewEdit = new TLabeledEdit(Form1);".
    La même erreur arrive dans d'autres circonstances, c'est juste un exemple.

    Pourquoi ?

    Dites moi s'il vous faut plus de détails et merci d'avance.

  2. #2
    Membre expérimenté
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Points : 1 307
    Points
    1 307
    Par défaut
    Etant donné que ta boucle de création de composant me semble bonne, le problème pourrait venir de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    zobi.at(ItemSelec).GetParamNb()
    Est-ce que zobi est alloué?
    Est-ce que zobi.at(ItemSelec) est alloué? (est ce que ItemSelec ne pointe pas en dehors?)
    Est-ce que GetParamNb() ne fais pas appel à un objet non alloué?

    Remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i = 0 ; i < zobi.at(ItemSelec).GetParamNb() ; i ++)
    Par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i = 0 ; i < 5; i ++)
    Juste pour faire un test.


    .
    Ce que l'on apprend par l'effort reste toujours ancré plus longtemps...

  3. #3
    Candidat au Club
    Inscrit en
    Octobre 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Merci pour la réponse.

    Je me suis rendu compte que mon fichier .h contenait évidemment la déclaration pour le vecteur de "Endpoint" zobi (vector<Endpoint> *zobi = new vector<Endpoint>) dans les propriétés publiques de la fenêtre Form1 mais que je ne l'initialisais pas dans la fonction qui crée la fenêtre Form1. J'ai corrigé ça (et changé mes . en ->). Cela dit, zobi contenait bien des éléments puisqu'au moins dans certains cas, j'avais bien des TLabeledEdit crées.

    Sinon, bonne suggestion de changer la limite de la boucle en un nombre fixe et qui révèle quelques trucs intéressants (4 plutôt que 5 car dans les cas où il n'y a que 4 paramètres, GetParamInd(int) retournerait une erreur).
    Les paramètres valent toujours 0 pour l'instant donc les TLabeledEdit doivent contenir la valeur 0 or si je clique sur le premier élément, le second puis que je reviens au premier, j'ai une valeur à la con qui remplit le TLabeledEdit !
    Conclusion : Il y a manifestement un problème avec mon vecteur zobi. Son contenu change, il pointe vers des adresses dont le contenu est réécrit, l'adresse elle-même change ? Je ne sais pas.

    Je me demande soudainement, ne devrais-je pas déclarer zobi comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    vector<Endpoint*> *zobi = new vector<Endpoint*>
    Pas sûr de savoir expliquer pourquoi mais j'ai comme un feeling que c'est pour ça que mes valeurs changent...
    ?

  4. #4
    Candidat au Club
    Inscrit en
    Octobre 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Mmmmh bon je viens de tester mon hypothèse et ça tourne maintenant. Pas d'erreur, bonnes valeurs dans les TLabeledEdit et bon nombre de ces derniers.

    Leçon n°1 en C++ : si ça marche pas, rajouter des *

    Merci pour ton aide, Sat83.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/05/2006, 16h24
  2. pb avec composant visuel créé dynamiquement
    Par richard038 dans le forum Composants VCL
    Réponses: 9
    Dernier message: 12/08/2005, 09h59
  3. Cherche exemple création composant visuel
    Par bertin dans le forum Composants VCL
    Réponses: 1
    Dernier message: 02/08/2005, 16h14
  4. Création dynamique de composants et destruction
    Par cpdump dans le forum Composants VCL
    Réponses: 4
    Dernier message: 19/01/2005, 17h57
  5. Réponses: 7
    Dernier message: 08/08/2003, 18h09

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