Discussion: Transtypage de string en Txyz [Lazarus]

  1. #1
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut Transtypage de string en Txyz

    Bonjour,

    J'ai rempli la liste d'un ComboBox avec des strings représentant des TFPBaseInterpolation (unité extinterpolation, ça s'utilise ainsi : DestCanvas.Interpolation := TQuadraticInterpolation.Create; ou un autre filtre, DestCanvas est un TLazCanvas).

    Maintenant, j'ai deux possibilités concernant l'utilisation au quotidien, à partir du choix fait dans le ComboBox :
    soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        case cbbxFilters.ItemIndex of
         0: DestCanvas.Interpolation := TBilineairInterpolation.Create;
         1: DestCanvas.Interpolation := TBlackmanInterpolation.Create;
         // et il y a beaucoup d'autres lignes
        end;
    soit une seule ligne DestCanvas.Interpolation := (cbbxFilters.Text as TFPBaseInterpolation).Create; mais ça ne compile pas :
    Citation Envoyé par erreur_du_compilo
    Error: Class or COM interface type expected, but got "TTranslateString"
    avec le curseur qui clignote devant le "as".

    J'ai jeté un œil à l'aide sur "as", je n'ai pas trouvé d'explication me permettant d'avancer, et je ne sais pas du tout quoi taper dans les moteurs de recherche.

    Si quelqu'un a une idée de ce qui manque, sa réponse sera un grand bonheur
    Merci d'avance,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Membre averti

    Homme Profil pro
    Amateur Passionné
    Inscrit en
    septembre 2015
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : septembre 2015
    Messages : 192
    Points : 410
    Points
    410

    Par défaut

    Salut Jipete

    soit une seule ligne DestCanvas.Interpolation := (cbbxFilters.Text as TFPBaseInterpolation).Create; mais ça ne compile pas
    Normal tu passes une variable de type String. Ca ne peut pas être compatible (ce genre de truc pour construire des objet dynamiquement est très utile et ça me manque aussi un peu par rapport au PHP )

    Tu n'as pas le choix que faire un truc dans le genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Function GetInterpolationClass(Idx:Integer): TFPCustomInterpolation;
    begin
      result:=nil;
      Case of Idx :
        0: result:=TMitchellInterpolation.Create;
        ....
      end;
    end
    ;
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Profil pro
    Inscrit en
    septembre 2008
    Messages
    4 333
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : septembre 2008
    Messages : 4 333
    Points : 8 737
    Points
    8 737

    Par défaut

    as est un transtypage contrôlé à la compilation. L'autre variante serait bien sûr TFPBaseInterpolation(cbbxFilters.Text).

    Dans le premier cas (as), le type de la donnée transtypée doit être conforme à ce qui est attendu (soit un type identique ou dérivé), dans le cas contraire, le compilateur râle. Dans le deuxième cas, le compilateur va passer tout droit (aucun contrôle particulier) et l'erreur éventuelle surviendra en runtime (violation d'accès logiquement si les points d'entrée ne sont pas conformes). Dans ce dernier cas, il faut donc bien savoir ce que l'on fait dès le départ.

    Mais il y a peu de chance que ça fonctionne ici, même si cbbxFilters.Text n'est finalement qu'un pointeur

  4. #4
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut

    Bonsoir,

    et merci pour vos réponses

    Citation Envoyé par Andnotor Voir le message
    as est un transtypage contrôlé à la compilation. L'autre variante serait bien sûr TFPBaseInterpolation(cbbxFilters.Text).

    Dans le premier cas (as), le type de la donnée transtypée doit être conforme à ce qui est attendu (soit un type identique ou dérivé), dans le cas contraire, le compilateur râle. Dans le deuxième cas, le compilateur va passer tout droit (aucun contrôle particulier) et l'erreur éventuelle surviendra en runtime (violation d'accès logiquement si les points d'entrée ne sont pas conformes).
    Ah ben non, Lazarus n'est pas content, d'entrée de jeu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DestCanvas.Interpolation := TFPBaseInterpolation(cbbxFilters.Text).Create;
    -->
    Citation Envoyé par compilo_en_colère
    Error: Incompatible types: got "TObject" expected "TFPCustomInterpolation"
    On ne m'ôtera cependant pas de l'idée que c'est dommage et qu'on n'est pas loin puisqu'en regardant bien une ligne qui compile et fonctionne : DestCanvas.Interpolation := TMitchelInterpolation.Create;, la partie en rouge on est bien d'accord que c'est du bête texte, hein.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  5. #5
    Membre averti
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    juillet 2011
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : juillet 2011
    Messages : 188
    Points : 413
    Points
    413

    Par défaut

    Bonjour,

    Citation Envoyé par Jipété Voir le message
    Bonsoir,

    DestCanvas.Interpolation := TMitchelInterpolation.Create;, la partie en rouge on est bien d'accord que c'est du bête texte, hein.
    Non, pas vraiment,
    Pour ton compilateur c'est du texte mais il peut (parce que il en a trouve quelque part la définition) en l'adresse de la fonction de crétaion de la classe.
    Lorsque tu passes du texte DestCanvas.Interpolation := 'TMitchelInterpolation'.Create; (qui ne fonctionne pas) pour ton compilateur c'est du texte et il ne trouve pas (sauf à regarder du côté de RTTI de classe correspondante). C'est toute la difficulté entre les langages compilés (pascal) qui font le travail de mise en correspondance au moment se la compilation et ceux interprétés (PHP) qui eux attendent l'exécution de la ligne pour aller chercher dans les classes déjà trouvées si il y en a une qui correspond.

    Cordialement

  6. #6
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut

    Yep !

    M'en suis sorti autrement : j'ai récupéré tous ces Txxx dans le fichier où ils étaient définis, les ai collés dans une nouvelle unité à moi, les ai intégrés dans une array of records prévue pour et roule ma poule, ça fonctionne du feu de Dieu !
    ("_ei" ça n'a rien à voir avec qui vous savez, de sinistre mémoire, c'est juste ExtInterpolation pour différencier les doublons d'avec "_rs" pour uReSample, l'unité qui m'a mis le pied à l'étrier.)
    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
    const
      ResampleFilters: array[0..16] of record
        Name  : string;	// Filter name
        Filter: TFilterProc;// Filter implementation
        Width : Double;	// Suggested sampling width/radius
      end = (
      (Name: 'Bilinear_ei';	Filter: @BilinearFilter_ei;	Width: 1.0),
    //  (Name: 'Blackman';	Filter: @BlackmanFilter;	Width: 1.0),
    //  (Name: 'BlackmanBessel';	Filter: BlackmanBesselFilter;	Width: 3.24),
    //  (Name: 'BlackmanSinc';	Filter: BlackmanSincFilter;	Width: 4.0),
      (Name: 'Box_ei';	Filter: @BoxFilter_ei;	Width: 0.5),
      (Name: 'Catrom';	Filter: @CatromFilter;	Width: 2.0),
      (Name: 'Cubic';	Filter: @CubicFilter;	Width: 2.0),
    //  (Name: 'Gaussian';	Filter: @GaussianFilter;	Width: 1.25),
      (Name: 'Hamming';	Filter: @HammingFilter;	Width: 1.0),
      (Name: 'Hanning';	Filter: @HanningFilter;	Width: 1.0),
      (Name: 'Hermite_ei';	Filter: @HermiteFilter_ei;	Width: 1.0),
      (Name: 'Lanczos_ei';	Filter: @LanczosFilter_ei;	Width: 3.0),
      (Name: 'Mitchel_fp';	Filter: @MitchelFilter_fp;	Width: 2.0),
      (Name: 'Quadratic';	Filter: @QuadraticFilter;	Width: 1.5),
        (Name: 'Box_rs';	Filter: @BoxFilter_rs;	Width: 0.5), 
    //renommé    (Name: 'Triangle';	Filter: TriangleFilter;	Width: 1.0), // ancien nom de dessous
        (Name: 'Bilinear_rs';	Filter: @BilinearFilter_rs;	Width: 1.0),
        (Name: 'Hermite_rs';	Filter: @HermiteFilter_rs;	Width: 1.0),
        (Name: 'Bell';	Filter: @BellFilter;	Width: 1.5),
        (Name: 'B-Spline';	Filter: @BSplineFilter;	Width: 2.0),
        (Name: 'Lanczos3_rs';	Filter: @Lanczos3Filter_rs;	Width: 3.0),
        (Name: 'Mitchell_rs';	Filter: @MitchellFilter_rs;	Width: 2.0));
    Je me balaye tout ça à grands coups de for i := 0 to length(ResampleFilters)-1 do ou autres ResampleFilters[cbbxFilters.ItemIndex].Filter, j'aime quand les choses fonctionnent ainsi

    Plus qu'à essayer de comprendre pourquoi Gaussian et BlackMan plantent violemment à l'exécution (plus un autre souci avec les 2 BlackManXXX), mais comme j'ai suffisamment à faire avec ceux qui restent, puisqu'il paraît que le mieux est l'ennemi du bien, je vais sans doute déclarer que ça va bien comme ça !

    Bon dimanche,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  7. #7
    Membre éprouvé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2003
    Messages
    524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : septembre 2003
    Messages : 524
    Points : 1 127
    Points
    1 127
    Billets dans le blog
    5

    Par défaut

    Citation Envoyé par Jipété Voir le message
    Bonjour,

    soit une seule ligne DestCanvas.Interpolation := (cbbxFilters.Text as TFPBaseInterpolation).Create; mais ça ne compile pas :

    avec le curseur qui clignote devant le "as".

    ....

    Si quelqu'un a une idée de ce qui manque, sa réponse sera un grand bonheur
    Bonjour Jipété,

    Évidemment, que cela ne peut pas compiler ! Les opérateurs as, is appliqués à des instances d'objet, ont une signification bien précises. Mais là, je suis désolé, je vous le dis amicalement c'est du "n'importe quoi !".

    Pour résoudre le problème de manière plus élégante, vous auriez pu utiliser le concept de "Référence de classe". Exemple :

    Code PASCAL : 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
    Type
     TFPBaseInterpolationRefClass : Class of TFPBaseInterpolation;
     
    ....
     
    var
      aFPBaseInterpolationRefClass : TFPBaseInterpolationRefClass;
      aFPBaseInterpolation : TFPBaseInterpolation;
     
     
     aFPBaseInterpolationRefClass := nil; // Une référence de classe peut être à nil, et donc ne référencer aucune classe
     case cbbxFilters.ItemIndex of
         0: DestCanvas.Interpolation := aFPBaseInterpolationRefClass := TBilineairInterpolation;
         1: DestCanvas.Interpolation := aFPBaseInterpolationRefClass := TBlackmanInterpolation;
     
           .....
     end;
     
    // Exemple d'instantiation d'objets
    if aFPBaseInterpolationRefClass <> nil then
      aFPBaseInterpolation := aFPBaseInterpolationRefClass.Create
    else
      aFPBaseInterpolation := nil;  // Ici , c'est l'instance d'objet qui est à nil.
     
    // Exemple d'utilisation d'une instance d'objet
    if Assigned(aFPBaseInterpolation) then
      aFPBaseInterpolation.xxxx := ....;
     
    ...
     
    if  (aFPBaseInterpolation is TBilineairInterpolation) then
      TBilineairInterpolation(aFPBaseInterpolation).yyyy := ..... ; 
    ...
    if (aFPBaseInterpolation Is TBlackmanInterpolation) then
      TBlackmanInterpolation(aFPBaseInterpolation).zzzz := .....;
    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  8. #8
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut

    Citation Envoyé par hmira Voir le message
    Évidemment, que cela ne peut pas compiler ! Les opérateurs as, is appliqués à des instances d'objet, ont une signification bien précises. Mais là, je suis désolé, je vous le dis amicalement c'est du "n'importe quoi !".
    Oui oui, mais en général, je ne circule pas trop sur ces terrains minés et pleins de chausse-trappes
    J'aurais dû faire précéder ma ligne "atroce" de la précision "pseudo-code".

    Citation Envoyé par hmira Voir le message
    Pour résoudre le problème de manière plus élégante, vous auriez pu utiliser le concept de "Référence de classe". Exemple :

    Code PASCAL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Exemple d'utilisation d'une instance d'objet
     
    if  (aFPBaseInterpolation is TBilineairInterpolation) then
      TBilineairInterpolation(aFPBaseInterpolation).yyyy := ..... ; 
    ...
    if (aFPBaseInterpolation Is TBlackmanInterpolation) then
      TBlackmanInterpolation(aFPBaseInterpolation).zzzz := .....;
    Et donc une vingtaine d'entrées comme ça ? Sûrement efficace mais pas très élégant à mes yeux (bon, les goûts et les couleurs ça se discute pas ) : 20 filtres = une quarantaine de lignes lourdes, en plus dans le code de l'unité de l'ihm, moyen moyen, je préfère avoir tout ça dans l'unité dédiée aux filtres.

    Merci quand même pour le tuyau (m'en rappellerais-je ? C'est une autre histoire...)
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  9. #9
    Membre éprouvé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2003
    Messages
    524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : septembre 2003
    Messages : 524
    Points : 1 127
    Points
    1 127
    Billets dans le blog
    5

    Par défaut

    Citation Envoyé par Jipété Voir le message
    ...Et donc une vingtaine d'entrées comme ça ? Sûrement efficace mais pas très élégant à mes yeux (bon, les goûts et les couleurs ça se discute pas ) : 20 filtres = une quarantaine de lignes lourdes, en plus dans le code de l'unité de l'ihm, moyen moyen, je préfère avoir tout ça dans l'unité dédiée aux filtres.
    Bonjour,

    Présenté comme ça, cela parait effectivement fastidieux ! MAIS, en réalité ce n'est pas comme cela que les choses se présentent et j'aurais du le préciser.

    Le transtypage explicite est nécessaire et requis uniquement pour les propriétés et les méthodes statiques. Pour les propriétés et les méthodes virtuelles, il n'est nullement nécessaire d'effectuer des transtypage explicite avec des if ... is ... then Txx(aFPBaseInterpolation). xx), dès lors que l'instance d'objet (même si le type de la variable est déclarée en tant que classe de base exemple aFPBaseInterpolation : TFPBaseInterpolation) eut été créée et instanciée avec le type approprié, c.à.d. une classe descendante . Exemple : aFPBaseInterpolationRefClass := TBlackmanInterpolation.Create). En effet, il s'agit tout simplement du mécanisme du polymorphisme.

    J'ai regardé par simple curiosité le code sources des classes TFPBaseInterpolation, TBilineairInterpolation, TBlackmanInterpolation, etc . et il s'avère que toutes les propriétés et méthodes des ces classes sont déclarées virtuelles, et même abstraites dans la classe ancêtre.

    Donc d'après-mois aucun transtypage explicite ne sera nécessaire et donc je persiste et je signe que la méthode que je vous ai suggérée est la bonne approche. Maintenant, libre à vous d'opter pour une autres méthode inefficace comme celle par exemple qui consiste à faire des copier/coller du code source !

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  10. #10
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut

    Bonsoir hmira,

    Citation Envoyé par hmira Voir le message
    Pour résoudre le problème de manière plus élégante, vous auriez pu utiliser le concept de "Référence de classe". Exemple :
    [--snip--]
    J'ai réactivé mes recherches sur les filtres, et je suis bloqué sur un point bizarre.
    Quand je compile votre exemple (résumé juste pour une lecture facile ici) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      var
        aFPBaseInterpolationRefClass : TFPBaseInterpolationRefClass;
        aFPBaseInterpolation : TFPBaseInterpolation; // post hmira
      begin
        case cbbxFilters.ItemIndex of
           0: DestCanvas.Interpolation := aFPBaseInterpolationRefClass := TBilineairInterpolation;
    je gagne ça au niveau de la ligne 0: :
    Error: Incompatible types: got "TFPBaseInterpolationRefClass" expected "TFPCustomInterpolation"
    Je trouve ça très capricieux, chatouilleux et extrêmement bloquant (parce que, oui, en ce qui me concerne, tout ce qui est abstrait et virtuel, j'ai du mal à comprendre le sens des mots et la finalité des choses).

    En plus, je ne savais même pas qu'on pouvait construire des choses avec 2 := qui se suivent ! On en apprend tous les jours, vous me direz, mais là, je ne sais pas ce que ça fait.
    Quand je fais i := 3; je sais que je mets la valeur 3 dans ma variable i déclarée comme integer, par exemple, mais
    DestCanvas.Interpolation := aFPBaseInterpolationRefClass := TBilinearInterpolation; je ne sais pas ce que ça fait, et je ne sais pas le dire et l'écrire en langage français, comme pour le i ci-dessus.

    Un soupçon d'explications complémentaires ?
    Merci,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  11. #11
    Membre éprouvé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2003
    Messages
    524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : septembre 2003
    Messages : 524
    Points : 1 127
    Points
    1 127
    Billets dans le blog
    5

    Par défaut

    Bonjour Jipété,

    Comme je ne disposais pas du contexte complet de votre application, je vous ai donné un exemple rapide pour illustrer le concept et l'utilisation des références de classes tout essayant de rester le proche de votre code initial. J'ai utilisé vos propres noms de classes etc. Et il se troue qu'effectivement en le relisant, une erreur manifeste s'est glissée dans le code ! (il s'agit des ':=' qui se suivent dans la même instruction, et qui ne cherchez pas plus, ne veulent rien dire ! Mea culpa.

    Cependant, le principe général des références de classes reste valable.

    Le code ci-dessous, à adapter bien sûr, annule et remplace le code précédent

    Voilà j'espère que cette fois-ci, il n'y a pas d'erreur, sinon, je vous fournirai à l'occasion un exemple complet et simple, en dehors du contexte de votre application, mettant en ouvre les références de classes. A charge à vous ensuite d'appliquer ces concepts dans votre application.

    Code 'PASCAL : 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
    type
     TFPBaseInterpolationRefClass : Class of TFPBaseInterpolation;
    ....
     
    var
     aFPBaseInterpolationRefClass : TFPBaseInterpolationRefClass;
     // aFPBaseInterpolation : TFPBaseInterpolation; // (n'est plus utilisée, remplacée directement par DestCanvas.Interpolation) 
     
     aFPBaseInterpolationRefClass := nil; // Une référence de classe peut être à nil, et donc ne référencer aucune classe
     case cbbxFilters.ItemIndex of
       0: aFPBaseInterpolationRefClass := TBilineairInterpolation;
       1: aFPBaseInterpolationRefClass := TBlackmanInterpolation;
       .....
     end;
     
    // Exemple d'instantiation d'objets
    if aFPBaseInterpolationRefClass <> nil then
      DestCanvas.Interpolation := aFPBaseInterpolationRefClass.Create
    else
      DestCanvas.Interpolation := nil; // Ici , c'est l'instance d'objet qui est à nil.
     
    // Exemple d'utilisation d'une instance d'objet
    if Assigned(DestCanvas.Interpolation) then
      DestCanvas.Interpolation.xxxx := ....;
     
    ...
    // Le Transtypage est requis uniquement pour les propriétés et les méthodes statiques 
    if (DestCanvas.Interpolation is TBilineairInterpolation) then
      TBilineairInterpolation(DestCanvas.Interpolation).yyyy := ..... ; 
    ...
    // Le Transtypage est requis uniquement pour les propriété et les méthode statiques 
    if (DestCanvas.Interpolation Is TBlackmanInterpolation) then
      TBlackmanInterpolation(DestCanvas.Interpolation).zzzz := .....;

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  12. #12
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut

    Bonsoir,

    merci pour ce retour, mais tout d'un coup j'ai eu une illumination :

    d'abord j'ai utilisé la complétion de code et lorsque j'ai saisi DestCanvas point int le système m'a proposé Interpolation:TFPCustomInterpolation, ensuite j'ai regardé attentivement les 3 lignes concernées dans le tuto FreePascal (2 vraiment du tuto et 1 rajoutée par moi) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Execute the stretch draw via TFPSharpInterpolation
    // DestCanvas.Interpolation := TFPSharpInterpolation.Create; // une horreur, gardé pour mémoire [origine]
    DestCanvas.Interpolation := TMitchelInterpolation.Create; // OK [rajouté par moi]
    // suite du tuto :
    et là je me suis dit : mon gars, tu as tout sous les yeux, qu'est-ce que tu vas te prendre la tête avec la complexité de la solution de hmira, genre DestCanvas.Interpolation.xxxx := ....; et il faudra lui demander par quoi remplacer xxxx et que mettre à droite du :=, la complétion n'étant pas très utile sur ce coup-là.

    Et j'avais d'autant plus tout sous les yeux qu'in fine, c'est ce que j'avais déjà écrit dans le premier post :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    case cbbxFilters.ItemIndex of
      0: DestCanvas.Interpolation := TBlackmanInterpolation.Create;
      1: DestCanvas.Interpolation := TBoxInterpolation.Create;
      2: DestCanvas.Interpolation := TBsplineInterpolation.Create;
      3: DestCanvas.Interpolation := TMitchelInterpolation.Create;
    end;
    // suite du tuto :
    DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
    et ça fonctionne !

    Le seul souci (et c'est l'origine de cette discussion), c'est l'obligation de synchroniser à la main la liste dans le case cbbxFilters.ItemIndex et la liste d'items dans le combobox, avec tous les risques d'erreurs, de fautes de frappe, etc., et c'est ça dont je voulais m'affranchir.
    Bah, si y a pas moyen y a pas moyen, faudra juste être très soigneux.

    Demain les tests complets,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  13. #13
    Membre expert
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    2 392
    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 : 2 392
    Points : 3 743
    Points
    3 743

    Par défaut

    salut

    pourquoi faire un case alors que tu peut tres bien instancier une class par son nom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     DestCanvas.Interpolation := TFPBaseInterpolationRefClass(Findclass('MACLASSFINAL')) .create
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  14. #14
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut

    Salut,
    Citation Envoyé par anapurna Voir le message
    salut

    pourquoi faire un case alors que tu peux très bien instancier une class par son nom

    DestCanvas.Interpolation := TFPBaseInterpolationRefClass(Findclass('MACLASSFINAL')).create
    Ah, toi, tu prends le train en marche et tu as raté le début de l'histoire,

    En fait, c'est juste qu'au final j'ai une bonne vingtaine de filtres à tester et que le plus simple, dans ce cas, c'est le bon vieux combobox dont la liste d'items sera remplie avec la liste des filtres, d'où le case combobox.ItemIndex of que je vais d'ailleurs coupler avec le choix du fichier à traiter, du coup, une fois celui-ci déterminé, plus qu'à choisir un filtre ou un autre dans la liste du combo (qui aurait pu être une ListBox, d'ailleurs, mais elle prend plus de place), et roule ma poule !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  15. #15
    Membre expert
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    2 392
    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 : 2 392
    Points : 3 743
    Points
    3 743

    Par défaut

    salut

    oui je prend le train en route mais je double tout le monde

    l'exemple que je t'ai donnée peut très bien s'écrire pour que ce soit plus parlant pour toi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DestCanvas.Interpolation := TFPBaseInterpolationRefClass(Findclass(format('T%s',[cbbxFilters.Items[cbbxFilters.ItemIndex]]))).create
    je te donne juste un exemple de ce qui est possible de faire sachant que les items des combo sont des TString
    tu peut faire un peu ce que tu veut ajouter un objet ou gérer des libelles

    autre exemple
    initialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cbbxFilters.Items.AddObject('filtre1',TMitchelInterpolation.Create);
    utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      DestCanvas.Interpolation :=  TFPBaseInterpolationRefClass(cbbxFilters.Items.Objects[cbbxFilters.ItemIndex])
    voila mes 2 Cts
    j’espère avoir fait avancer le schmilblick
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  16. #16
    Membre éprouvé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2003
    Messages
    524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : septembre 2003
    Messages : 524
    Points : 1 127
    Points
    1 127
    Billets dans le blog
    5

    Par défaut

    Citation Envoyé par anapurna Voir le message
    salut

    pourquoi faire un case alors que tu peut tres bien instancier une class par son nom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     DestCanvas.Interpolation := TFPBaseInterpolationRefClass(Findclass('MACLASSFINAL')) .create
    Dans le cas présent Non !
    En effet, sauf erreur de ma part, FindClass ne marche que pour les classes descendantes de TPersistent et de surcroit déjà enregistrées par RegisterClass ou RegisterClasses.
    Or, il se trouve qu'aucune des classes qui nous concernent (TFPCustomInterpolation, TFPBaseInterpolation, TBlackmanInterpolation, TMitchelInterpolation, etc..) n'est persistante, et encore moins enregistrée !
    Sinon, FindClass aurait été une très bonne idée et résoudrait incontestablement, de manière élégante, le problème de Jipété sans qu'il soit obligé d'avoir des illuminations.

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  17. #17
    Membre expert
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    2 392
    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 : 2 392
    Points : 3 743
    Points
    3 743

    Par défaut

    salut

    le finclass n'est qu'un exemple j'ai pas regardé les ancêtres des filtres
    finclass ne fait qu'une recherche dans une list d'objets on peut tres bien l’écrire soit même


    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
     
    //variable list global
    var
      classFilterByName : TStringList;
    ...
     
    // Enregistrer une classe
    procedure registerClassFilterByName(classe: TFPBaseInterpolationRefClass);
    begin
      // Ajout de la classe si elle n'est pas déjà référencée
      if (classFilterByName.IndexOf(classe.ClassName) = -1) then
      begin
        classFilterByName.AddObject(classe.ClassName,TObject(classe));
      end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // Obtenir une classe par son nom
    function getClassFilterByName(nom: string): TFPBaseInterpolationRefClass;
    var
      i : integer;
    begin
      // Recherche dans la liste des classByName
      i := classFilterByName.IndexOf(nom);
      // si pas trouvé, on renvoie nil
      if (i = -1) then
        result := nil  // si trouvé, on renvoie la classe associée
      else
        result := TFPBaseInterpolationRefClass(classFilterByName.objects[i]);
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // enregistrement des classes  :
    if  classFilterByName = Nil Then 
      classFilterByName := TStringList.Create;
     
    registerClassFilterByName(TMitchelInterpolation);
    ...
    // libération classFilterByName
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if classFilterByName.count =1 Then  
    begin
      classFiletrByName.Free;
    end;
    // Utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    getClassFilterByName('TMitchelInterpolation').create
    ...
    je pense en avoir assez dis pour qu'il puisse se débrouiller tout seul
    on se sert d'une méthode similaire pour ajouter la lecture des différents format graphique

    mes 2 Cts
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  18. #18
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : mars 2005
    Messages : 2 864
    Points : 7 609
    Points
    7 609

    Par défaut

    Les noms remplissant la ComboBox viennent bien de quelque part... Soit une constante tableau de ces appellations avec une autre dimension pour une référence au type, un Create spécifique doit être aisé et éviter de s'emmêler dans l'ordre du combo et du case of, au mieux d'ailleurs avec un TStringList et un IndexOf sur le nom.
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  19. #19
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    5 437
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 5 437
    Points : 7 442
    Points
    7 442

    Par défaut

    Citation Envoyé par anapurna Voir le message
    je pense en avoir assez dit pour qu'il puisse se débrouiller tout seul
    Bon, ben il va essayer demain, mais il rappelle qu'il a énormément de mal avec tout ce qui est abstrait, virtuel, impalpable...

    En plus il essaye de mixer les Tfpmachinchose de Lazarus/FreePascal avec la construction trouvée dans l'unité Resample du projet DoubleCommander, qui se goupille ainsi (il ne met qu'un filtre pour ne pas trop alourdir) :
    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
    type
      // Type of a filter for use with Stretch()
      TFilterProc = function(Value: Single): Single;
     
      // Sample filters for use with Stretch()
      function HermiteFilter (Value: Single): Single;
     
      // Interpolator
      // Src:	Source bitmap
      // Dst:	Destination bitmap
      // filter:	Weight calculation filter
      // fwidth:	Relative sample radius
      procedure Stretch(Src, Dst: TBitmap; filter: TFilterProc; fwidth: single);
     
    // -----------------------------------------------------------------------------
    //			List of Filters
    // -----------------------------------------------------------------------------
     
    const
      ResampleFilters: array[0..1] of record
        Name  : string;	// Filter name
        Filter: TFilterProc;  // Filter implementation
        Width : Single;	// Suggested sampling width/radius
      end = (
        (Name: 'Hermite';	Filter: HermiteFilter;	Width: 1.0));
     
    implementation
     
    uses
      Math, IntfGraphics, GraphType, FPImage;
     
    // -----------------------------------------------------------------------------
    //			Filter functions
    // -----------------------------------------------------------------------------
     
    // Hermite filter
    function HermiteFilter(Value: Single): Single;
    begin
      // f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1
      if (Value < 0.0) then
        Value := -Value;
      if (Value < 1.0) then
        Result := (2.0 * Value - 3.0) * Sqr(Value) + 1.0
      else
        Result := 0.0;     
    end;
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  20. #20
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : mars 2005
    Messages : 2 864
    Points : 7 609
    Points
    7 609

    Par défaut

    Voici une illustration de la class factory :
    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
    implementation
     
    {$R *.frm}
     
    type
      TAncetre = class
        class function CreateDescendant(aIndex: integer): TAncetre;
        function QuiSuisJe: string; virtual;
      end;
     
      TEnfant1 = class(TAncetre)
        function QuiSuisJe: string; override;
      end;
      TEnfant2 = class(TAncetre)
        function QuiSuisJe: string; override;
      end;
      TEnfant3 = class(TAncetre)
        function QuiSuisJe: string; override;
      end;
      TEnfant4 = class(TAncetre)
        function QuiSuisJe: string; override;
      end;
     
      TClasseDescendant = class of TAncetre;
     
      TAssociation = record
        Nom    : string;
        Classe : TClasseDescendant;
      end;
     
    var
      TableauAssociatif: array [1..4] of TAssociation;
     
    { TForm1 }
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i: integer;
      Descendant: TAncetre;
    begin
      i:=Trunc(random(4))+1;
      Descendant:=TAncetre.CreateDescendant(i);
      ShowMessage(TableauAssociatif[i].Nom+' =? '+Descendant.QuiSuisJe);
      Descendant.Free;
    end;
     
    class function TAncetre.CreateDescendant(aIndex: integer): TAncetre;
    begin
      Result:= TableauAssociatif[aIndex].Classe.Create;
    end;
     
    function TAncetre.QuiSuisJe: string;
    begin
      Result:='TAncetre';
    end;
     
    function TEnfant1.QuiSuisJe: string;
    begin
      Result:='TEnfant1';
    end;
     
    function TEnfant2.QuiSuisJe: string;
    begin
      Result:='TEnfant2';
    end;
     
    function TEnfant3.QuiSuisJe: string;
    begin
      Result:='TEnfant3';
    end;
     
    function TEnfant4.QuiSuisJe: string;
    begin
      Result:='TEnfant4';
    end;
     
    initialization
      randomize;
      with TableauAssociatif[1] do begin Nom:='Enfant1'; Classe:=TEnfant1; end;
      with TableauAssociatif[2] do begin Nom:='Enfant2'; Classe:=TEnfant2; end;
      with TableauAssociatif[3] do begin Nom:='Enfant3'; Classe:=TEnfant3; end;
      with TableauAssociatif[4] do begin Nom:='Enfant4'; Classe:=TEnfant4; end;
     
    finalization
     
    end.
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Transtypage de string en shortstring
    Par Martin Lestas dans le forum Débutant
    Réponses: 9
    Dernier message: 27/10/2015, 11h03
  2. Thread ShellExecute PChar string transtypage
    Par ouiouioui dans le forum Débutant
    Réponses: 11
    Dernier message: 02/11/2008, 00h51
  3. Transtypage int => char, String => char
    Par autregalaxie dans le forum Débuter
    Réponses: 7
    Dernier message: 10/04/2007, 13h48
  4. Transtypage String en Pchar impossible
    Par madfu dans le forum Delphi
    Réponses: 6
    Dernier message: 10/07/2006, 12h39
  5. [debutant] transtypage string en int
    Par melvar dans le forum Langage
    Réponses: 3
    Dernier message: 08/03/2006, 16h08

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