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 :

Détruire un bouton sur son OnClick [FAQ]


Sujet :

C++Builder

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 21
    Points : 21
    Points
    21
    Par défaut Détruire un bouton sur son OnClick
    Bonjour,

    La question est dans le sujet. J'ai crée dynamiquement un bouton que j'aimerais pouvoir détruire sur son évènement OnClick. Avec ce que j'ai déjà fait, j'ai une violation d'accès lorsque le code de l'évènement OnClick se termine (ce qui me paraît logique, vu qu'à ce moment là, le bouton qui a appelé ce gestionnaire d'évènement n'existe plus).

    Comment faire ?

    Merci d'avance

  2. #2
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    En principe, on ne peut pas détruire l'objet sur son clic, c'est une erreur dite abstraite, c'est comme si l'objet se suicidait puisqu'une méthode d'instance de classe est censée détruire sa propre instance donc in fine se suicider. La POO n'autorise pas le suicide, la mort d'un objet est toujours extérieure. La question avait été déjà posée sous une autre forme (http://www.developpez.net/forums/viewtopic.php?t=21060). Ce qu'il faut faire, c'est simplement de jouer sur la visibilité de l'objet, donc de le rendre invisible sur le OnClick.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    Button1->Visible=false;
    }
    Sinon, si vous voulez vraiment détruire l'objet, il faudra le détruire de l'exétrieur. En principe ça ne sert à rien car la visibilité seule suffit à résoudre 99% des cas.

    À bientôt
    Gilles

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 21
    Points : 21
    Points
    21
    Par défaut
    Tout d'abord, merci de votre réponse. Je me doutais bien de ce genre de réponse (malheureusement pour moi !).

    Je vais essayer d'expliquer pourquoi je voulais détruire ce bouton.

    En fait, mon programme se compose d'une feuille et d'un ScrollBox dessus. J'ai une méthode qui crée dynamiquement dans ce ScrollBox des TImage, des TLabels en pagaille et quelques TButton. Cette méthode affiche tout cela selon le résultat d'une requête SQL (donc la quantité de tout ces objets dans le scrollbox n'est pas déterminé). Sur le OnClick d'un de ces boutons (mais à terme aussi sur le OnClick de certains Labels et Images), la base de donnée est modifiée. J'ai par conséquent besoin de rafraichir l'affichage et donc de relancer cette méthode. C'est pourquoi j'avais écrit sur ce OnClick ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ScrollBox1->DestroyComponents();
    MaMethodeQuiMeRefaitToutLaffichage();
    Ce système m'aurait particulièrement bien allé (facile, rapide à écrire, lisible). Avec le principe du Visible=false, il va falloir gérer le tout bien plus lourdement : garder un pointeur en mémoire sur l'ensemble des composants crées (des listes chainés), effacer certains, en créer d'autres suivant ce qu'il y a à rafraichir... Bref, pas simple...

    Ne serait-il pas possible de contourner ce problème ? Puisque la destruction doit venir de l'extérieur, un système message Windows ajouté dans la file des messages sur le OnClick/un gestionnaire d'évènement sur ce message qui ferait le rafraichissement, serait-il possible et élégant ?

    Merci encore.

  4. #4
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Je comprends ce que vous voulez dire et j'ai eu un problème similaire. Pour ma part, je passe alors par le OnPaint de la Form principale lié à un flag. Je commence par déclarer un flag de destruction dans la classe principale.

    J'initialise le flag dans la construction de la Form principale.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
    {
    FlagDestroy=false;
    }
    Sur le clic du bouton, je rends le bouton invisible et je mets le flag à vrai.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    FlagDestroy=true;
    Button1->Visible=false;
    }
    Ceci a pour effet de forcer le OnPaint de la Form principale car le bouton disparaît, il faut donc bien redessiner la Form sans le bouton. Dans ce OnPaint, je teste le flag. Si le flag est à true, je détruis l'objet et je remets le flag à false.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void __fastcall TForm1::FormPaint(TObject *Sender)
    {
    if (FlagDestroy)
       {
       delete Button1;
       FlagDestroy=false;
       ShowMessage("Le bouton a été détruit");
       }
    }
    Dans un OnPaint normal, il ne se passe rien mais quand vous cliquez sur le bouton, le message s'affiche ce qui est la preuve que le bouton a bien été détruit. Maintenant que vous êtes sûr que le bouton a été détruit, vous enlevez évidemment le message.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void __fastcall TForm1::FormPaint(TObject *Sender)
    {
    if (FlagDestroy)
       {
       delete Button1;
       FlagDestroy=false;
       }
    }
    À bientôt
    Gilles

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 21
    Points : 21
    Points
    21
    Par défaut
    C'est pas bête du tout comme système. Ca rejoint un peu ce à quoi je pensais (en ajoutant un message windows) mais en nettement plus simple.

    Merci beaucoup

    A bientôt.

  6. #6
    Membre confirmé Avatar de nemo69500
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    639
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 639
    Points : 519
    Points
    519
    Par défaut
    tu fais

    ou ce qui est mieux

    *************##--##***************
    www.ptichoupi.fr



    Pensez au
    De tmps en tps du repos, ca fais du bien!

    ************//////\\\\\\**************

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

Discussions similaires

  1. Enregistrer un son à partir d'un bouton sur le guide
    Par fleurrouge dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 29/06/2009, 18h56
  2. Détruire un bouton sur lequel on vient de cliquer
    Par gazier20 dans le forum Langage
    Réponses: 13
    Dernier message: 15/12/2005, 23h33
  3. Réponses: 2
    Dernier message: 16/06/2005, 00h56
  4. Réponses: 3
    Dernier message: 09/12/2004, 12h49
  5. Quatrième bouton sur la barre de titre d'une fenêtre
    Par Yacine95000 dans le forum MFC
    Réponses: 8
    Dernier message: 02/06/2004, 18h54

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