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 :

Faire un dynamic_cast de manière "dynamique"


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut Faire un dynamic_cast de manière "dynamique"
    Salut,
    je voudrais faire un dynamic_cast en un type de classe que j'ai dans une string, mais je sais pas comment dire que le type est le contenu de cette string.
    En gros je voudrais éviter de passer par une multitude de if qui test si la chaîne contient cette classe ou celle-ci, mais je ne sais pas si c'est passible.


  2. #2
    Membre Expert
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Par défaut
    Dans le fond si je comprend bien, tu as une classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MaClasse
    {
        private :
            int var1;
    }
    Ensuite une string:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AnsiString MaString;
    MaString = "MaClasse";
    Et tu cherches faire qqchose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    instDeClasse = new MaString;
    Alors si j'ai bien compris, je ne sais pas du tout comment faire

  3. #3
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    en gros c'est ca, mais pas avec un new mais avec un dynamic_cast

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    string maString = "TLabel*";
     
    dynamic_cast<maString> Application->Components[0];

    En sachant que bien entendu, dans maString il y aura le bon type du composant, qui aura été récupéré d'un fichier XML, grace au nom du composant (qui lui est accessible directement depuis TComponent)

  4. #4
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Bonjour,

    Je ne sais pas si tu peut agir de la sorte directement dans le 'dynamic_cast'.
    En revanche, une solution détournée peut être, si tu connais d'avance la liste des classes d'objets pouvant être 'castées'.
    Je reprends l'astuce du 'Switch sur un AnsiString': ici

    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
     
    //global_test est un String définis ... qqpart ailleurs ;-)
       AnsiString Values[] = {"TLabel", "TMemo", "TEdit"};
       int tabSize = sizeof(Values) / sizeof(AnsiString);
    for ( int i = 0; i < this->ComponentCount; i++ )
    {
    		switch(AnsiIndexStr(global_test, &Values[0], tabSize))
    		{
    			case 0: // "TLabel"
    			{
    				break;
    			}
    			case 1: // "TMemo"
    			{
    				TMemo* pmem = dynamic_cast < TMemo* > (this->Components[i]);
    				if (pmem != NULL) {
    					pmem->Lines->Add("essai cast");
    				}
    				break;
    			}
    			case 2: // "TEdit"
    			{
    				break;
    			}
    			default:
    			break;
    		}
    }
    En espérant t'aider,
    @+

  5. #5
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut pottiez
    Un lien dans la FAQ ce n'est pas exactement ce que tu cherche mais c'est une piste

  6. #6
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Salut,
    merci pour toute vos propositions, je voulais simplement éviter une multitude de if ou de case dans un switch, surtout que je ne sais pas forcément tout les types de composant.
    Par contre (une idée comme ça), comme je veut accéder à une propriété qui est commune sur pratiquement tous les composants (le Caption pour ne pas le citer), je pourrai regarder la hiérarchie des classe Borland et caster sur la classe ou le Caption apparaît.

  7. #7
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Re,

    Donc sinon une petite idée de début d'éventuelle solution:
    -> en passant par 'API'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //en amont
    String global_test = "TEdit";
    //
    String txt =  "test edit";
     
    HWND hwnd = FindWindowEx(Handle, NULL, global_test.c_str(), NULL);
    if (hwnd != NULL)
    {
    	SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)txt.c_str());
    }
    Cela suppose d'avoir le Handle de la fenêtre possédant l'objet recherché, etc ...

    @+

  8. #8
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Salut,
    je vais expliquer clairement ce que je voudrais faire, ça sera plus rapide

    En fait, j'ai un fichier XML, dans lequel est enregistré des informations de tous les composants affichant du texte de mon appli. Je dispose des infos suivante: le name du composant, (la propriété Name d'un composant est directement accessible depuis la classe TComponent), le type du composant (TLabel, TGroupBox, TForm,...) et ces deux information sont suivie d'une liste de texte dans différentes langues (voila le but du projet).

    Mon projet est donc de faire une classe, qui contiendra entre-autre une fonction qui prendra pour argument un TComponent, cette fonction changera le propriété texte dans la langue qui conviendra, puis fera une boucle sur tout les composants enfants du composant passé en argument, en appelant cette même fonction (récursive donc ).

    Voila le projet, le seul souci est d'accéder à des propriété comme le Caption, ou tous autre propriété d'affichage de texte.

    Je sais que le Caption est définit a partir de la classe TControl, mais il est en protected, donc non atteignable est cela jusqu'à ce que les composants soit définit eux même, donc pas de classe commun ou je pourrait l'atteindre.

    Tous cela pour dire que au final, je vais devoir faire une succession de if ou de case, ce que je voulais éviter, mais bon, j'étais a peut près sur de devoir passer par la .

    Merci tout de même pour vos recherche et votre aide .

  9. #9
    Membre Expert
    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
    Par défaut
    Vous pourriez passer par un tableau de pointeurs de fonctions (une fonction par type de composant) mais ça risque d'être une usine à gaz pour pas grand-chose, une série de if bien présentée me paraît plus claire ou un case prévu à cet effet.

    Le tableau de fonctions n'est intéressant à mettre en oeuvre que si le nombre de composants différents était très grand, le jeu en vaudrait la chandelle, comme on dit. Sinon, ça me paraît une technique trop sophistiquée pour cette problématique.

    À bientôt
    Gilles

  10. #10
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Bonjour,

    Donc tu as: le name, le classname, le/les types de propriétés a affecter, etc ...

    Pffiou ... pleins d'infos, on devrait pouvoir y arriver. Pas sur que je sois forcement de bon conseil mais j'ai un bout de code/idée a proposer:
    .h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    private:
    void __fastcall ChangeProp(String Class_Name, String Object_Name, String Property_Name, String AValue);
    .cpp:
    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
     
    void __fastcall TForm2::ChangeProp(String Class_Name, String Object_Name, String Property_Name, String AValue)
    {
    try
    {
    HWND hwnd = FindWindowEx(Handle, NULL, Class_Name.c_str(), Object_Name.c_str());
    	if (hwnd != NULL)
    	{
    		TControl *pControl = dynamic_cast < TControl* > (FindControl(hwnd));
    		if (pControl != NULL) {
    			try
    			{
    				SetPropValue(pControl, Property_Name, AValue);
    			}
    			catch(EPropertyError &propError)
    			{
    				//catcher l'erreur sur propriété non dispo
    			}
    		}
    		else
    		{
    			//pControl est null
    		}
    	}
    	else
    	{
    		// hwnd est null
    	}
    }
    catch(...)
    {
     
    }
    }
    NB: j'ai retrouver l'idée du GetPropValue et SetPropValue dans un vieux post, qui remonte - imaginez vous bien - a l'époque ou Maître GreyBird fréquentait les lieux ! ( ) -> ici

    J'ai une idée peut être un peu barbare: j'imaginerais passer en paramètre - pour la propriété a affecter - plutôt que de ne passer qu'un seul nom de propriété un tableau avec les éventuelles propriétés a affecter ('Text', 'Caption', etc).
    Si ca plante sur le premier élément, on passe avec le EpropertyError dans le catch et on peut tester sur le second ...
    Bon, un peu sauvage comme truc. Mais si tu as peu de cas, pourquoi pas ?

    Donc tu lis le fichier XML, tu récupères et stockes en liste les classes et les noms d'objets, tu parcours la liste et fait appel a la fonction en passant les différents paramètres, etc ...

    NB2: je ne manipule pas très bien les infos de RTTI et cie, donc il y a peut être un moyen de faire mieux ...

    Voili
    ++

  11. #11
    Membre éprouvé
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Par défaut
    Sorry,

    Je poste vraiment n'importe quoi, désolé.
    Je proposerais de virer l'utilisation de FindWindowEx, et de ne faire qu'ainsi:
    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
     
    void __fastcall TForm2::ChangeProp(String Object_Name, String Property_Name, String AValue)
    {
    try
    {
    		TControl *pControl = dynamic_cast< TControl* > (FindComponent(Object_Name));
    		if (pControl != NULL) {
    			try
    			{
    				SetPropValue(pControl, Property_Name, AValue);
    			}
    			catch(EPropertyError &propError)
    			{
    				//catcher l'erreur sur propriété non dispo
    			}
    		}
    		else
    		{
    			//pControl est null
    		}
    	}
    catch(...)
    {
     
    }
    }
    Donc dans ce cas, plus vraiment besoin de l'info concernant le nom de la classe.
    J'ai testé avec des objets du type TLabel, TEdit, il faut voir avec d'autres objets possédant "Text" et/ou "Caption". D'ailleurs a ce propos, TLabeledEdit possède les deux si je ne me trompe pas ... mince, comment on fait ?

  12. #12
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut
    Sur le site il y a un article sur RTTI, si ca peu aider

  13. #13
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Bonjour,
    je reviens à vous car lorsque je compile mon application sous BCB6 il me fait une lieur erreur sur la fonction GetPropList alors que tout fonctionne correctement sous BCB2006 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [Lieur Erreur] Unresolved external '__fastcall Typinfo::GetPropList(System::TObject *, Typinfo::TPropInfo * *&)' referenced from C:\DOCUMENTS AND SETTINGS\ALEXANDREP\BUREAU\SRC6\GESTIONLANGUE.OBJ
    Je ne vois pas du tout d'ou ca peut provenir, j'ai regardé par rapport à mon projet 2006, il ne manque rien, bizard

  14. #14
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut pottiez
    Un lien avec je pense le meme probleme, je ne sais pas s'il y a une solution

  15. #15
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Merci pour ce lien, j'ai trouvé une autre fiche de bug parlant du même problème mais avec une solution, seulement je n'arrive pas à la mettre en place, j'ai du mal à comprendre (moi et l'anglais )

    http://qc.codegear.com/wc/qcmain.aspx?d=1533

  16. #16
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Cette directive c'est pour le compilateur

    " #pragma alias "

  17. #17
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Oui mais je ne sais pas ou je doit la mettre, il me semble que c'est dans le .cpp ou je fait l'appelle a la fonction, mais je ne suis pas sur.

    Et la suite il faut le mettre aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      "@Typinfo@GetPropList$qqrp17Typinfo@TTypeInfo46System@%Set$t17Typinfo@TTypeKind$iuc$0$iuc$17%pp17Typinfo@TPropInfoo"
     
      ="@Typinfo@GetPropList$qqrp17Typinfo@TTypeInfo46System@%Set$t17Typinfo@TTypeKind$iuc$0$iuc$17%pa16380$p17Typinfo@TPropInfoo"

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

Discussions similaires

  1. [xsl]simuler le mecanisme OO de "liaison dynamique"
    Par philemon_siclone dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 19/12/2003, 11h34

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