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

Langage Delphi Discussion :

Cast d'un objet d'une TObjectList


Sujet :

Langage Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut Cast d'un objet d'une TObjectList
    Bonjour,

    J'utilise une TObjectList pour contenir mes différents composants instanciés.

    Chaque composant possède une même propriété Couleur.

    Pour accèder à cette propriété, je dois caster l'objet que je veux utiliser.

    Le problème est que je ne connais pas à l'avance l'objet.

    J'aimerais donc faire un cast "dynamique" selon le type d'objet. J'ai essayé avec la propriété ClassName :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    liste.Items[0].ClassName(liste.Items[0]).maPropriete
    Mais ça ne fonctionne pas et c'est normal.

    Comment pourrais-je faire ?

  2. #2
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour

    Il me semble que ce que tu devrais écrire est plutot :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ClassName(liste.Items[0]).maPropriete

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par Graffito
    Bonjour

    Il me semble que ce que tu devrais écrire est plutot :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ClassName(liste.Items[0]).maPropriete
    ClassName n'accepte pas d'arguments.... je viens d'essayer.

    Par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    liset.Items[0].ClassName;
    retourne le nom de la classe de l'objet.

    Mais ensuite, comment caster l'objet avec ce string récupéré ?

  4. #4
    Membre éprouvé
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Points : 1 177
    Points
    1 177
    Par défaut
    Si les objets contenus dans la liste ont un ancêtre commun qui a la propriété couleur alors effectivement tu peux caster sauvagement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TNomDeLaClasseAncetre(liste.Items[i]).Couleur := clRed;
    Si les objets contenus dans la liste ont assurément une propriété couleur (TColor) et qu'ils hérite directement ou pas de TPersistent, alors avec RTTI on peu valoriser directement: (cf. la FAQ)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetOrdProp(liste[i], 'Couleur', clRed);
    Enfin, si tes items sont tous des descendants de TComponent, préférer un TComponentList au TObjectlist car le TComponentList est, en plus, automatiquement notifié si un de ses items est libéré (.Free) par n'importe qui n'importe où.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par neilbgr
    Si les objets contenus dans la liste ont un ancêtre commun qui a la propriété couleur alors effectivement tu peux caster sauvagement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TNomDeLaClasseAncetre(liste.Items[i]).Couleur := clRed;
    Vu que c'est un test que je veux faire, j'essaie cette solution.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(TNomDeLaClasseAncetre(liste.Items[0]).Couleur = clInfoBk) then...
    Mais le problème est que je ne connais pas TNomDeLaClasseAncetre à l'avance. Je peux le récupérer avec ClassName mais je ne sais pas comment faire le cast après vu que ClassName retourne un String...

  6. #6
    Membre éprouvé
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Points : 1 177
    Points
    1 177
    Par défaut
    Essais donc la 2eme méthode. Car là on a pas besoin du nom de la classe. Tu donnes l'objet, le nom de la propriété.
    Maintenant, si tu veux LIRE au lieu d'ecrire dedans, c'est aussi "compliqué" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      if GetOrdProp(Liste[vIndice], 'Couleur')=clRed then
        begin
     
        end;
    Ne pas oublier de faire le uses de TypInfo

  7. #7
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Tu as combien de types de composants possibles ?

    Parce qu'avec une méthode surchargée celà pourrait fonctionner...
    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
     
    Interface
      function ObtenirCouleur(UnItem:TClasse1):TColor; overload;
      function ObtenirCouleur(UnItem:TClasse2):TColor; overload;
      function ObtenirCouleur(UnItem:TClasse3):TColor; overload;
      function ObtenirCouleur(UnItem:TClasse4):TColor; overload;
      function ObtenirCouleur(UnItem:TClasse5):TColor; overload;
     
    implementation
     
    function ObtenirCouleur(UnItem:TClasse1):TColor;
    begin
      Result:=UnItem.couleur;
    end;
     
    // etc pour les autres types
    ...
     
    //puis
    var UneCouleur:TColor;
    begin
      //si l'item possède une propriété PUBLIEE (published) qui s'appelle couleur
      if (liste.Items[0] as liste.Items[0].ClassType).FieldAddress('couleur')<>nil
      then UneCouleur:=ObtenirCouleur((liste.Items[0] as liste.Items[0].ClassType));
    end;
    ou bien... :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var UneCouleur:TColor;
    begin
      //si l'item possède une propriété PUBLIEE (published) qui s'appelle couleur
      if (liste.Items[0] as liste.Items[0].ClassType).FieldAddress('couleur')<>nil
      then UneCouleur:=(liste.Items[0] as liste.Items[0].ClassType).Couleur;
    end;
    J'ai pas testé tout ça mais ça devrait fonctionner

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Ok, merci bien pour ces indications !

    Je vais essayer la méthode de neilbgr.

    Pourquoi qui suit ne fonctionne pas en sachant que la propriété Selected est Boolean ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(GetOrdProp(liste[i], 'Selected')) then
    Mais, en ce qui concerne le cast "dynamique", vous auriez pas une idée ?

    J'en aurais besoin pour d'autre fonctionnalités comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TNomDeLaClasseAncetre(PopupMenu1.PopupComponent);
    Suis-je obligé de faire un switch ClassName case... ?

  9. #9
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 885
    Points : 11 403
    Points
    11 403
    Billets dans le blog
    6
    Par défaut
    et pourquoi pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for i:=0 to List.Count-1 do
     try
       with List[i] as List[i].ClassType
         do color:=clLime;
     except
        on Exception do Continue;
     end;

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par tourlourou
    et pourquoi pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for i:=0 to List.Count-1 do
     try
       with List[i] as List[i].ClassType
         do color:=clLime;
     except
        on Exception do Continue;
     end;
    joli ça, mais ça ne fonctionne que pour une affectation.

    par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for i:=0 to List.Count-1 do
     try
       with List[i] as List[i].ClassType
         do uneVariable := color;
     except
        on Exception do Continue;
     end;
    ne fonctionne pas.

    Alors j'essaie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for i:=0 to List.Count-1 do
     try
       uneVariable := List[i].ClassType(List[i]).color;
     except
        on Exception do Continue;
     end;
    mais ça ne fonctionne pas

  11. #11
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Salut,

    Je suis sur que ceci va marcher
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for i:=0 to List.Count-1 do
     try
       if IsPublishedProp(List[i], 'Color') and PropIsType(List[i], 'Color', tkInteger) then
          uneVariable :=TColor(GetOrdProp(List[i], 'Color'));  
     end;
    en admettant que UneVariable soit un TColor...

  12. #12
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Citation Envoyé par maredami
    Ok, merci bien pour ces indications !

    Je vais essayer la méthode de neilbgr.

    Pourquoi qui suit ne fonctionne pas en sachant que la propriété Selected est Boolean ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(GetOrdProp(liste[i], 'Selected')) then
    parce que GetOrdProp renvoi un integer, il faut donc caster le résultat (et puis il a une parenthèse de trop) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if boolean(GetOrdProp(liste[i], 'Selected') then
    Citation Envoyé par maredami
    Ok, merci bien pour ces indications !
    Mais, en ce qui concerne le cast "dynamique", vous auriez pas une idée ?

    J'en aurais besoin pour d'autre fonctionnalités comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TNomDeLaClasseAncetre(PopupMenu1.PopupComponent);
    Suis-je obligé de faire un switch ClassName case... ?
    Pas forcément, qu'est ce que tu veux faire avec PopupMenu1.PopupComponent ? Accéder à une méthode particulière ou à une propriété ? Et pourquoi la classe ancètre du composant pointé par PopupComponent ?

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par waskol
    Pas forcément, qu'est ce que tu veux faire avec PopupMenu1.PopupComponent ? Accéder à une méthode particulière ou à une propriété ?
    C'est pour savoir quel composant a été cliqué à l'aide du popupmenu.
    Citation Envoyé par waskol
    Et pourquoi la classe ancètre du composant pointé par PopupComponent ?
    Erreur, je cherche à caster en classe de l'objet -> TNomDeLaClasse

  14. #14
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Citation Envoyé par maredami
    Citation Envoyé par waskol
    Pas forcément, qu'est ce que tu veux faire avec PopupMenu1.PopupComponent ? Accéder à une méthode particulière ou à une propriété ?
    C'est pour savoir quel composant a été cliqué à l'aide du popupmenu.
    Citation Envoyé par maredami
    excuses moi, je reformule ma question, que veux tu faire avec le dit composant sur lequel tu sais que tu as cliqué ?
    faire Composant.quelquechose; ?
    Obtenir quelle information ?
    Citation Envoyé par waskol
    Et pourquoi la classe ancètre du composant pointé par PopupComponent ?
    Erreur, je cherche à caster en classe de l'objet -> TNomDeLaClasse
    OK, donc ça rejoint ma question précédente...

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Ce que j'essaie de faire depuis le début est de caster un objet en son type de départ pour pouvoir l'utiliser comme tel ensuite.

    Mon souci est qu'il n'est visiblement pas possible d'effectuer un cast dynamique.

    J'en déduis donc qu'il faut passer par un switch case.

    -> TObjectList pratique quand on stocke un seul type d'objet, sinon...

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Personne n'a jamais eu ce problème en utilisant des TObjectList ? :o

    Vous les utilisez toujours avec un seul type d'objet ?

  17. #17
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Citation Envoyé par maredami
    Ce que j'essaie de faire depuis le début est de caster un objet en son type de départ pour pouvoir l'utiliser comme tel ensuite.
    Si, mais si tu connais son type...
    De toute façon, si tu veux l'utiliser tel quel il faut que tu connaisse son type au moment ou tu programmes. Ou du moint que tu en ai une idée.
    Pour les composant visuels, au pire, tu peux tester si ce sont des TWinControl ou des TGraphicControl, de toute façon, c'est soit l'un soit l'autre, ça fera pas plus de ligne de code.

    Citation Envoyé par maredami
    Mon souci est qu'il n'est visiblement pas possible d'effectuer un cast dynamique.
    Ben si, en connaissant le type vers lequel tu veux caster, sinon non...
    Citation Envoyé par maredami
    J'en déduis donc qu'il faut passer par un switch case.
    Bonne déduction...

    Citation Envoyé par maredami
    -> TObjectList pratique quand on stocke un seul type d'objet, sinon...
    ha ça, c'est sur que si tu veux y stocker 36000 objets de type différents....

  18. #18
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Citation Envoyé par maredami
    Personne n'a jamais eu ce problème en utilisant des TObjectList ? :o

    Vous les utilisez toujours avec un seul type d'objet ?
    Non Aucun pour ma part.

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Ok, merci pour tout ! Vraiment sympa !

    Vu que l'utilisateur de mon programme pourra ajouter n'importe quel composant de ma liste et le nombre qu'il veut, je serai obligé d'utiliser un Switch Case pour déterminer sur quel type de composant il clique...

    J'ai pas fini de m'amuser...

  20. #20
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Citation Envoyé par maredami
    Ok, merci pour tout ! Vraiment sympa !

    Vu que l'utilisateur de mon programme pourra ajouter n'importe quel composant de ma liste et le nombre qu'il veut, je serai obligé d'utiliser un Switch Case pour déterminer sur quel type de composant il clique...

    J'ai pas fini de m'amuser...
    En fait, tu t'en moque, la plupart du temps, de savoir sur quel composant il clique !

    Ce qui est important c'est ce que tu veux en faire après de ce composant.

    Par exemple, si c'est pour changer sa Hauteur, tu le castes en TControl, dont héritent absolument TOUS les composants visuels, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TControl(PopupMenu1.PopupComponent).height:=150;
    Si c'est pour changer la couleur, comme la propriété Color de TControl est protégée, il faut que tu crée une classe qui dérive de TControl (voir la FAQ ici : http://delphi.developpez.com/faq/?pa...#protectedhack

    et ça te donne (que ce soit un TImage, un TButton, un TShape ou un TPanel, etc...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    type TPublicControl=class(TControl);
    ...
    begin
    ...
      TPublicControl(PopupMenu1.PopupComponent).Color:=clRed;
    ...
    end;
    Et hop, ça te change la couleur de (presque) tous les Contrôles surle quel ton utilisateur à cliqué... Ca ne fait pas 10000 lignes de code.

Discussions similaires

  1. [POO] Cast d'objet vers une classe
    Par karl3i dans le forum Langage
    Réponses: 9
    Dernier message: 27/07/2009, 11h12
  2. Faire le Cast d'un objet récupéré dans une datagrid
    Par MaitreTsiang dans le forum Flex
    Réponses: 11
    Dernier message: 04/11/2008, 17h13
  3. Cast Objet en une instance de type T
    Par Julien_C++ dans le forum C++/CLI
    Réponses: 1
    Dernier message: 30/04/2008, 19h03
  4. [JSP][Debutant]recuperer un objet d'une page a l'autre
    Par zozolh2 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 17/05/2004, 11h25
  5. [VB6]Passage par référence d'une prop. d'objet à une fct
    Par -gYs- dans le forum VB 6 et antérieur
    Réponses: 15
    Dernier message: 02/09/2002, 09h55

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