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

Delphi Discussion :

Programmation en dynamique


Sujet :

Delphi

  1. #1
    Membre éclairé Avatar de Cpt Anderson
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2005
    Messages
    641
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 641
    Par défaut Programmation en dynamique
    Bonjour à tous,

    je me suis fais un petit programme avec des composants crées dynamiquement et gerés dynamiquement. J'ai des exceptions assez étranges. C'est surtout les erreurs lors du "moins" qui m'intriguent. Est ce parce que mes objets ne se liberent pas ?

    Voici le code. Je précise que je travaille en Delphi 7.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Buttons;
     
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        sb      : TScrollBox ;
        gb      : TgroupBox ;
        btPlus  : TBitBtn ;
        btMoins : TBitBtn ;
        ICompteur : integer ;
        itop      : integer ;
        Procedure CreeGroupBox   ;
        Procedure OnclickPlusGB(Sender: TObject) ;
        Procedure OnclickMoinsGB(Sender: TObject) ;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    Procedure TForm1.CreeGroupBox   ;
    var
     i : integer ;
    begin
     if sb <> nil then
      freeandnil(sb) ;
     sb        := TScrollBox.Create(Form1) ;
     sb.Parent := Self ;
     sb.Align  := alClient ;
     
     for i:=0 to Icompteur-1 do
      begin
       gb        := TgroupBox.Create(sb) ;
       gb.Parent := sb ;
       gb.Left   := 200;
       gb.Width  := 500 ;
       gb.Top    := gb.Top + (200*i) ;
       gb.Height := 150 ;
     
       btPlus         := TBitBtn.Create(gb) ;
       btPlus.Parent  := gb ;
       btPlus.Top     := 20 ;
       btPlus.Left    := 100 ;
       btPlus.OnClick := OnclickPlusGB ;
       btPlus.Caption := 'Plus' ;
     
       btMoins         := TBitBtn.Create(gb) ;
       btMoins.Parent  := gb ;
       btMoins.Top     := 80 ;
       btMoins.Left    := 100 ;
       btMoins.OnClick := OnclickMoinsGB ;
       btMoins.Caption := 'Moins' ;
     end ;
    end ;
     
    Procedure TForm1.OnclickPlusGB(Sender: TObject) ;
    begin
     Inc(ICompteur);
     CreeGroupBox  ;
    end ;
     
    Procedure TForm1.OnclickMoinsGB(Sender: TObject) ;
    begin
     if ICompteur > 1 then
      ICompteur := ICompteur -1 ;
     CreeGroupBox  ;
    end ;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     ICompteur := 1 ;
     itop := 50 ;
     CreeGroupBox ;
    end;
     
    end.

  2. #2
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Salut!

    Je n'ai pas creusé profondément ton code, mais à première vue, on dirait que tes boutons servent à se détruire eux-mêmes, ce qui ne peut que générer des erreurs.

    Si tu cherches à faire en sorte qu'un objet puisse se détruire lui-même, je te suggère d'effectuer une recherche sur ce forum. Il existe plusieurs solutions qui ont fait l'objet de discussions ces derniers temps (utilisations de messages Windows, etc.).

    Bon dev!

  3. #3
    Membre éclairé Avatar de Cpt Anderson
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2005
    Messages
    641
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 641
    Par défaut
    oui en fait tous mes composants sont crée sur le(s) groupBox, lesquels sont crées sur le scrollbox.

    Si, à chaque fois que j'ajoute ou que je soustrait, je détruis le scrollbox, cela ne suffit il pas ? pourquoi ai je ces erreurs ? je ne comprend pas trop !

  4. #4
    Membre émérite Avatar de Yurck
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    682
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2005
    Messages : 682
    Par défaut
    Comme le dit slimjoe tu scies la branche sur laquelle tu es assis.

    L'évènement OnClick est appelé dans le code du composant (doclick).
    Et c'est dans ce code que tu appelles une méthodes qui (au travers des liens de parentés et de propriétés entre les composants ) détruit le dit composant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if sb <> nil then
      freeandnil(sb) ;
    Tu devrais réfléchir à une autre cinétique de programme ou à une autre architecture de fenêtre.
    D'ailleurs lorrsque tu fais un moins plutôt que de tout détruire pourquoi ne pas détruire seulement le groupbox concerné.
    Pour cela détaches auparavant lres liens qui unissent tes composants (removecontrol) .

    etc...

    a+

  5. #5
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Par défaut
    Bonjour,

    Je vois que ne suis pas seul à avoir ce type de problème dans un contexte similaire :
    - Je crée et affiche dynamiquement des images en ayant déclaré leur parent,
    - Pas de problème pour les détruire en rafale dans une boucle,
    - Mais impossible de détruire à l'unité une image sélectionnée à la souris sans que cette destruction ne déclenche le message d'erreur "Violation d'accès à l'adresse ..." ou selon l'humeur du moment "Le contrôle '' n'a pas de parent" sans citer le nom du contrôle alors que chacun d'eux en porte un du type Img suivi de son numéro de création et que chacun a son parent déclaré !!!.

    Mais comme la destruction s'est quand même produite (ce qui est l'essentiel) ne peut-on bloquer l'affichage de ce type de message d'erreur ?
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  6. #6
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    Citation Envoyé par Cpt Anderson
    oui en fait tous mes composants sont crée sur le(s) groupBox, lesquels sont crées sur le scrollbox.

    Si, à chaque fois que j'ajoute ou que je soustrait, je détruis le scrollbox, cela ne suffit il pas ? pourquoi ai je ces erreurs ? je ne comprend pas trop !
    En fait l'erreur vient du fait que tu detruis le composant alors que l'évènement n'est pas encore fini.

    Exemple: Un groupbox avec 2 labels et un bouton

    1- Clic sur le bouton -> Evenement en cours OnClick
    2- Destruction des labels
    3- Destruction du bouton
    4- Destruction du GroupBox
    5- Fin de l'évènement OnClick -> Erreur le bouton n'existe plus

    C'est schématique bien sûr ^^

    La solution la plus simple est de mettre un timer qui exécute l'action de destruction.
    Pour ma part, dans un cas comme celui la. Je mets tous les éléments que je veux détruire en Visible := False puis je execute le timer qui détruit tous les composants non visible.
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  7. #7
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    sujet maintes fois debatu et maintes fois resolu

    voir ici et la

    @+ Phil

  8. #8
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Citation Envoyé par anapurna
    salut

    sujet maintes fois debatu et maintes fois resolu

    voir ici et la

    @+ Phil
    Cette problématique revient au moins à tous les mois. Ne serait-il pas judicieux d'en parler en FAQ ?

  9. #9
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    J'ai mis en attente dans la liste des QR à faire, normalement elle devrait apparaitre à la prochaine fournée ^^
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  10. #10
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Citation Envoyé par Malatar
    J'ai mis en attente dans la liste des QR à faire, normalement elle devrait apparaitre à la prochaine fournée ^^

    Quelle efficacité!

  11. #11
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Par défaut
    Cpt Anderson : La remarque de Yurck qui disait "réfléchir à une autre cinétique de programme" est judicieuse, m'a mis la puce à l'orieille ... et m'a permis de résoudre mon problème de destruction d'image.

    A cet effet j'ai :
    -1) déclaré une variable globale nommée imageSlectionnee égale à nil,
    -2) ensuite j'ai limité le contenu de la procedure TForm1.Image1MouseDown() associé à l'événement onMouseDown déclaré dans la routine de création dynamique des images à la seule instruction imageSlectionnee :=(Sender as tImage); (Auparavent cette instruction était complétée par celles qui concouraient à libérer l'image); Pour la nouvelle version cela donne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // : Pour Supprimer une image choisie par erreur :
    //     - Click-souris-relâcher pour préselectionner l'image puis touches-clavier Ctrl + Suppr
    procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin    imageSlectionnee:=(Sender as tImage); end;
    -3) En association avec le Form1.Keypreview:=true je provoque ensuite la libération de l'image et de son panel-support par la procédure suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // Libération de l'image avec touches-clavier Ctrl + Suppr
    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin    if (imageSlectionnee <>nil) and (ssCtrl in Shift) and (key=VK_DELETE) then
               begin (imageSlectionnee.parent as tPanel).free;
                       imageSlectionnee:=nil;
               end;
    end;
    Cela marche et je n'ai plus ces messagee d'erreur. Une parade similaire devrait pouvoir se trouver pour ton problème :
    1) Identifier le ou les élément(s) à supprimer dans une première procédure.
    2) Provoquer une libération différée avec une deuxième procédure
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  12. #12
    Membre éclairé Avatar de Cpt Anderson
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2005
    Messages
    641
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 641
    Par défaut
    salut,

    oui et j'ai deja reperé la maniere de faire mais tu sais comment cela se passe dans une societé, on a un temps imparti pour le dev. et il faut le respecter (meme si la, je l'ai deja dépassé) alors je dois faire en sorte que cela fonctionne correctement dès aujourd'hui; je fignolerais plus tard.

    Bref, je te remercie et je regarderai ta solution en detail dès que je le pourrais...

  13. #13
    Membre éclairé Avatar de Cpt Anderson
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2005
    Messages
    641
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 641
    Par défaut
    Bon en ce qui concerne ma problématique, j'ai procédé de la façon suivante:

    je ne libere plus ma scrollbox, je les crée au fur et à mesure mais je les stock dans une TObjectList et à la fermeture de la fenetre je boucle dans cet ObjectList pour liberer toutes mes scrollbox...

    Je ne sais pas si c'est une bonne facon de faire mais ca fonctionne bien.

  14. #14
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Citation Envoyé par Cpt Anderson
    Bon en ce qui concerne ma problématique, j'ai procédé de la façon suivante:

    je ne libere plus ma scrollbox, je les crée au fur et à mesure mais je les stock dans une TObjectList et à la fermeture de la fenetre je boucle dans cet ObjectList pour liberer toutes mes scrollbox...

    Je ne sais pas si c'est une bonne facon de faire mais ca fonctionne bien.
    Ce n'est pas particulièrement mauvais....
    Perso j'ajouterais à ça du code qui viderais l'ObjectList à un intervalle régulier via un TTimer ou sur l'événement OnIdle de TApplication.


  15. #15
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Par défaut
    On aurait également eu la possibilité :
    - de libérer puis recréer la scrollbox dans la routine associée à un timer avec une instruction du style if monTrucALibérer<>nil then begin monTrucALibérer.free; monTrucALibérer:=nil; CreeGroupBox; end;
    - après avoir identifié monTrucALibérer dans la Procedure TForm1.OnclickMoinsGB(Sender: TObject) ; où monTrucALibérer est le parent du parent du TBitBtn qui a émis l'évenement OnClickMoins.

    Lorsque la libération est provoquée dans la routine du timer j'ai pu vérifier avec mon exemple d'image(s) à libérer que cela marche aussi sans provoquer de message d'erreur.

    L'essentiel est que "ca fonctionne bien".
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  16. #16
    Membre éclairé Avatar de Cpt Anderson
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2005
    Messages
    641
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 641
    Par défaut
    oui c'est ce qu'avait proposé malatar.

    Véritablement, ca serait bien que dans la FAQ, on propose une solution tip-top à ce genre de problème.

  17. #17
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    Citation Envoyé par Malatar
    J'ai mis en attente dans la liste des QR à faire, normalement elle devrait apparaitre à la prochaine fournée ^^
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  18. #18
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    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
    Procedure TForm1.CreeGroupBox   ;
    var
     i : integer ;
    begin
     if sb <> nil then
      freeandnil(sb) ;
     sb        := TScrollBox.Create(Form1) ;
     sb.Parent := Self ;
     sb.Align  := alClient ;
     
     for i:=0 to Icompteur-1 do
      begin
       gb        := TgroupBox.Create(sb) ;
       gb.Parent := sb ;
       gb.Left   := 200;
       gb.Width  := 500 ;
       gb.Top    := gb.Top + (200*i) ;
       gb.Height := 150 ;
    sa veut dire que tu crée Icompteur de TGroupbox(gb)??
    pour ma part je préfére les message avec postmessage sans passé par un timer, je te donne un petit example pas testé, mais surement il te donneras une idée.
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    private
    sb      : TScrollBox ;
    gb      : TgroupBox ;
    contro :Tcontrol ;
    ….
    procedure Monmessage(var msg :Tmessage) ;message wm_user ;
    Procedure suprimenfant(c :control) ;
    Procedure CreeGroupBox   ;
    end ;
    Procedure TForm1.suprimenfant(c :control) ;
    Var  i :integer ;
    Begin
            For i :=0 to c.ControlCount-1 do
                c.Controls[i].Free ;
    End ;
    Procedure TForm1.Monmessage ;
    Begin
             If  msg. WParam=2 then  // par example wparam=2 ==> surpim control 
                 Begin
                     CreeGroupBox;
                 End ;
    End ;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     ICompteur := 1 ;
     itop := 50 ;
     postmessage(handle,wm_user,2,0);
    end;
     
    Procedure TForm1.CreeGroupBox   ;
    var
     i : integer ;
    begin
     if sb <> nil then
        begin
           Suprimenfant(sb) ; // tu peut faire une boucle ou simplement changer un peut suprimenfant pour qu'il soit récursif
           freeandnil(sb) ;
         end;
    ......

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

Discussions similaires

  1. Quelle technique pour de la programmation web dynamique ?
    Par BaldeckJ dans le forum Général Conception Web
    Réponses: 1
    Dernier message: 13/09/2007, 13h58
  2. SQL Dynamique dans un programme cobol
    Par genio dans le forum DB2
    Réponses: 14
    Dernier message: 04/12/2006, 11h23
  3. [FLASH MX2004][expert] Programmation objet clips dynamiques
    Par CUCARACHA dans le forum ActionScript 1 & ActionScript 2
    Réponses: 13
    Dernier message: 24/09/2006, 11h27
  4. Réponses: 4
    Dernier message: 21/09/2006, 12h45
  5. Liaison dynamique et vitesse des programmes
    Par sebzinzin dans le forum Langage
    Réponses: 2
    Dernier message: 11/04/2006, 09h51

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