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

Composants VCL Delphi Discussion :

Supprimer un composant lorsque l'on clique dessus


Sujet :

Composants VCL Delphi

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 7
    Points : 6
    Points
    6
    Par défaut Supprimer un composant lorsque l'on clique dessus
    Salut,

    J'ai un scrollbox où je met une liste de TPanel. Sur chaque TPanel je met un bouton avec une propriété OnClick qui fait ceci (enfin entre autre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ScrollBox2.DestroyComponents;
    Seulement Delphi n'aime pas que je supprime un objet lors de l'appel du onclick de celui-ci :/

    Est-ce que quelqu'un aurait une solution ?

    Merci d'avance

  2. #2
    Rédacteur
    Avatar de Giovanny Temgoua
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    3 830
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 3 830
    Points : 4 006
    Points
    4 006
    Par défaut
    Comme cà à la volée, je te proposerai d'envoyer un message à la fiche (avec PostMessage) qui se chargera de détruire les composants du ScrollBox...

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 258
    Points : 558
    Points
    558
    Par défaut
    Sinon moi je te propose de rechercher tous les composants TPanel que tu as créé sur ta ScrollBox et d'appliquer Free pour chacun d'eux...

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Pourquoi faire un free sur tous les éléments alors qu'il n'y a que le bouton d'un seul TPanel qui est activé.
    J'ai donc pensé faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        Sender.Free;
        ScrollBox2.DestroyComponents;
    Mais j'ai toujours une exception...

    Pour ce qui est de PostMessage, je n'ai pas trouvé beaucoup d'information dessus.

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Normal : ton bouton appartient au TPanel que tu vas détruire, OK ?
    Mais lorsque tu détruit le parent au sein du gestionnaire d'évènement d'un composant enfant, que se passe-t-il au retour du gestionnaire d'évènement ? Hum ?
    Plus de composant => Boum !

    Solution : "notifier" la suppression de manière asynchrone. J'ai déjà utilisé, avec succès, l'évènement OnIdle pour ça.

    Déjà, tu vas commencer par rajouter un TApplicationEvents à ta fiche.

    Dans ton gestionnaire de bouton, tu vas mettre l'instance de ton TPanel dans un attribut "FPanelToDestroy : TObject", qui en général est à Nil.
    Ensuite, tu te contentes de rendre le TPanel invisible, de manière à laisser croire à l'utilisateur que le panneau est détruit immédiatement.

    Ensuite, dans le ApplicationEvents.OnIdle, tu vas rajouter ce type de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    If Assigned(FPanelToDestroy) Then
       FreeAndNil(FPanelToDestroy);
    Ainsi, il ne sera détruit que lorsque ton application aura un moment libre.

    Tu peux avoir des problèmes de réentrance : donc, pour "forcer" la destruction du TPanel, tu peux rajouter un accesseur Write à FPanelToDestroy :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Procedure SetFPanelToDestroy ( Const Value : TObject ) ;
    Begin
         // Pas la peine d'assigner 2 fois le même.
         If (FPanelToDestroy=Value) Then
            Exit ;
         // Destruction forcée de l'instance précédente au cas où.
         If Assigned(FPanelToDestroy) Then
            FreeAndNil(FPanelToDestroy);
         // Sinon, il sera détruit dans le OnIdle.
         FPanelToDestroy:=Value;
    End;
    Faudra peut-être protéger un peu mieux le code avec une section critique notamment s'il y a des problèmes de "cliquage fou", mais sinon, ça devrait marcher tel quel.

    Tout est OK pour toi ?

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par Mac LAK
    Tout est OK pour toi ?
    Déjà, merci beaucoup pour ton aide

    Mais ça ne marche pas chez moi j'ai toujours une EAccessViolation...

    Voilà ce que j'ai mis dans mon code :

    Le onclick du bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.DeleteComand(Sender: TObject);
    begin
        {Lst.Delete(StrToInt(((Sender as TBitBtn).Parent as TPanel).Hint));}
        SetFPanelToDestroy((Sender as TBitBtn).Parent as TPanel);
    end;
    Le OnIdle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    begin
    If Assigned(FPanelToDestroy) Then
       FreeAndNil(FPanelToDestroy);
    end;
    Pour SetFPanelToDestroy je n'y est pas touché. L'erreur semble venir du OnIdle :/

    Merci

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Havrest
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.DeleteComand(Sender: TObject);
    begin
        {Lst.Delete(StrToInt(((Sender as TBitBtn).Parent as TPanel).Hint));}
        SetFPanelToDestroy((Sender as TBitBtn).Parent as TPanel);
    end;
    Je trouve ton code bien complexe, quand même... Pourquoi n'as tu pas mis FPanelToDestroy comme un TObject, tout simplement ?

    Citation Envoyé par Havrest
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    begin
    If Assigned(FPanelToDestroy) Then
       FreeAndNil(FPanelToDestroy);
    end;
    Mets "Done" à True après le test If. Regarde l'aide de l'évènement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    begin
    If Assigned(FPanelToDestroy) Then
       FreeAndNil(FPanelToDestroy);
    Done:=True;
    end;
    Citation Envoyé par Havrest
    Pour SetFPanelToDestroy je n'y est pas touché. L'erreur semble venir du OnIdle :/
    Bizarre... Ca ne devrait pas, pourtant : n'as-tu rien fait d'autre entre les deux actions ?

Discussions similaires

  1. Réponses: 6
    Dernier message: 02/05/2012, 15h36
  2. série en gras lorsque l'on clique dessus
    Par dawaman dans le forum Excel
    Réponses: 1
    Dernier message: 21/03/2012, 13h28
  3. Réponses: 1
    Dernier message: 03/01/2011, 21h38
  4. [AC-2003] Comment désactiver un bouton lorsque l'on clique dessus ?
    Par [ZiP] dans le forum VBA Access
    Réponses: 2
    Dernier message: 18/02/2010, 09h21
  5. Masquer un bouton lorsque l'utilisateur clique dessus
    Par cgodefrw dans le forum Access
    Réponses: 4
    Dernier message: 27/04/2006, 10h44

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