IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants VCL Delphi Discussion :

Le Assign copie les objets pour un combobox mais pas pour un mémo


Sujet :

Composants VCL Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 32
    Points : 32
    Points
    32
    Par défaut Le Assign copie les objets pour un combobox mais pas pour un mémo
    Bonjour à tous,

    Je me suis bien pris la tête sur ce point alors, comme ça m'a servi, peut être servira-t-il aux autres

    L'assignation des éléments d'une combobox copie les objets associés alors que l'assignation des éléments d'un mémo ne copie pas les objets.
    Pourquoi ?

    Bien que les éléments d'un mémo et d'une combobox soient tous deux de type TStrings, leur fonctionnement diffère.

    1. Pour un memo, les éléments ont pour propriété 'Lines'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TMemo = class(TCustomMemo)
      published
        ...
        property Lines;
    Il dérive de TCustomMemo

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    TCustomMemo = class(TCustomEdit)
      private
        ...
      protected
        ...
      public
        ...
        property Lines: TStrings read FLines write SetLines;
      end;
    La variable private s'appelle FLines et on va voir comment elle est créée...

    Il n'y a pas de TMemo.Create.
    On passe à TCustomMemo. Create :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    constructor TCustomMemo.Create(AOwner: TComponent);
    begin
      ...
      FLines := TMemoStrings.Create;
      ...
    end;
    FLines est donc de type TMemoStrings.

    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
    TMemoStrings = class(TStrings)
      private
        Memo: TCustomMemo;
      protected
        function Get(Index: Integer): string; override;
        function GetCount: Integer; override;
        function GetTextStr: string; override;
        procedure Put(Index: Integer; const S: string); override;
        procedure SetTextStr(const Value: string); override;
        procedure SetUpdateState(Updating: Boolean); override;
      public
        procedure Clear; override;
        procedure Delete(Index: Integer); override;
        procedure Insert(Index: Integer; const S: string); override;
      end;
    Le Assign n'est pas présent dans TMemoStrings, on monte à TStrings.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TStrings.Assign(Source: TPersistent);
    begin
      ...
        AddStrings(TStrings(Source));
      ...
    end;
    On regarde AddStrings :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TStrings.AddStrings(Strings: TStrings);
     
    begin
      ...
      AddObject(Strings[I], Strings.Objects[I]);
    end;
    On regarde AddObject :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function TStrings.AddObject(const S: string; AObject: TObject): Integer;
    begin
      Result := Add(S);
      PutObject(Result, AObject);
    end;
    On regarde PutObject :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    procedure TStrings.PutObject(Index: Integer; AObject: TObject);
    begin
    end;
    -> Ne fait rien... Cool

    2. Pour un combo, les éléments ont pour propriété items

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TComboBox = class(TCustomComboBox)
      published
        ...
        property Items; { Must be published after OnMeasureItem }
      end;
    Dérive de TCustomComboBox

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TCustomComboBox = class(TCustomCombo)
    qui n'a pas items de défini

    Il dérive de TCustomCombo

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    TCustomCombo = class(TCustomListControl)
      private
        ...
      protected
        ...
      public
        ...
        property Items: TStrings read FItems write SetItems;
        ...
      end;
    La variable private est donc FItems.
    On regarde si le create de TCustomCombo la définit...

    -> Non...

    On regarde donc si le create de TCustomComboBox la définit...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    constructor TCustomComboBox.Create(AOwner: TComponent);
    begin
      ...
      FItems := GetItemsClass.Create;
      ...
    end;
    Oui... Donc FItems est de type GetItemsClass (sans doute descendant de TStrings...)

    En fait, GetItemsClass est une fonction qui renvoie la classe TCustomComboBoxStringsClass

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TCustomComboBoxStringsClass = class of TCustomComboBoxStrings;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    TCustomComboBoxStrings = class(TStrings)
      private
        ...
      protected
        ...
        procedure PutObject(Index: Integer; AObject: TObject); override;
        ...
      public
        ...
      end;
    PutObject, défini à vide en TStrings est ici déclaré...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TCustomComboBoxStrings.PutObject(Index: Integer; AObject: TObject);
    begin
      SendMessage(ComboBox.Handle, CB_SETITEMDATA, Index, Longint(AObject));
    end;
    ...et pas vide

    Voilà donc pourquoi le assign sur les éléments d'un Combo et d'un Memo sont différents, bien que les éléments Lines et Items soient de même type...
    Comme ils sont créés avec des types différents, l'un surcharge la copie des objets, ce que l'autre ne fait pas...

    Hope it helps

  2. #2
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Quel version de delphi ?
    Quel test as tu fait sur le Assign ? Memo1.Assign(Memo2) ?

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 610
    Points : 25 298
    Points
    25 298
    Par défaut
    C'est tout à fait normal !
    Sur un TComboBox les items sont stables, il n'y pas de risque de déplacement inopiné, c'est l'API Windows qui gère un Pointeur Data pour chaque Item, comme dans le TListView ou TTreeNodes
    Sur un TMemo, les lignes peuvent être modifié automatiquement par WordWrap au redimensionnement du TMemo, comment géré le déplacement d'objet ! Et Windows ne fourni pas le Pointeur Data avec ce contrôle !

    Le TStrings est une encapsulation fort pratique mais comme en dessous c'est des Contrôles Windows, on a en toute logique les mêmes limitations

    C'est juste écrit dans la documentation de StdCtrls.TCustomMemo.Lines
    Citation Envoyé par StdCtrls.TCustomMemo.Lines
    Remarque : Bien que la propriété Lines soit implémentée comme descendant de TStrings, elle n'implémente pas le support des objets associés aux chaînes de la liste.
    CQFD !

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 32
    Points : 32
    Points
    32
    Par défaut
    Envoyé par StdCtrls.TCustomMemo.Lines
    Remarque : Bien que la propriété Lines soit implémentée comme descendant de TStrings, elle n'implémente pas le support des objets associés aux chaînes de la liste.
    C'est vrai, ceci dit, même si j'avais été voir, je n'aurais pas compris la phrase...
    Si on m'avait dit que le assign ne faisait rien sur la copie des objets, j'aurais compris ceci dit

    Ce qui est chiant c'est de se dire que 2 type TStrings peuvent bosser différemment et qu'il faut avoir le réflexe d'aller voir le create de la classe de base pour contourner les problèmes d'héritage...

    Maintenant, j'ai compris

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 610
    Points : 25 298
    Points
    25 298
    Par défaut
    Citation Envoyé par Ziginou Voir le message
    Citation Envoyé par StdCtrls.TCustomMemo.Lines
    Remarque : Bien que la propriété Lines soit implémentée comme descendant de TStrings, elle n'implémente pas le support des objets associés aux chaînes de la liste.
    C'est vrai, ceci dit, même si j'avais été voir, je n'aurais pas compris la phrase...
    Pourtant elle est clair !

    Citation Envoyé par Ziginou Voir le message
    'il faut avoir le réflexe d'aller voir le create de la classe de base pour contourner les problèmes d'héritage...
    Faut juste lire la doc et la comprendre, ce qui est normalement plus simple que lire le code ...


    Disons que le TCustomMemo doit être la seule exception !
    C'est la seule que je connais pour avoir essayer un jour !

    Tu peux faire confiance aux autres !
    Pour la TStringGrid, la propriété Objects fonctionne très bien et je peux de dire que le code derrière est assez copieux !

    Ce n'est même pas Assign qui pose problème, ce simple code ne fonctionne pas !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if Memo1.Lines.Objects[Memo1.Lines.AddObject('Salut', Memo1)] <> Memo1 then
      ShowMessage('CQFD');
    if ListBox1.Items.Objects[ListBox1.Lines.AddObject('Salut', ListBox1)] = ListBox1 then
      ShowMessage('CQFD');

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 32
    Points : 32
    Points
    32
    Par défaut
    Pourtant elle est clair !
    Tout est relatif... Moi, je l'ai trouvée trop vague pour la comprendre...

    Faut juste lire la doc et la comprendre, ce qui est normalement plus simple que lire le code ...
    Très subjectif comme remarque Avec des 'Il suffit de comprendre', j'aurais pu sortir major de promo de centrale ou de polytechnique
    Je n'avais pas compris comment, à partir de deux propriétés TStrings, on pouvais aboutir à deux fonctionnements différents...
    Quand on comprend que l'on fait un create sur un objet hérité dans le composant, on comprend tout, surtout quand on se rend compte que PutObject ne fait rien dans TStrings...

    Tu peux faire confiance aux autres !
    Pour la TStringGrid, la propriété Objects fonctionne très bien et je peux de dire que le code derrière est assez copieux !
    Je suis heureux de le savoir, merci !

    Ce n'est même pas Assign qui pose problème, ce simple code ne fonctionne pas !
    Ca, j'avais compris aussi quand on sait que Assign -> AddStrings -> AddObject -> PutObject et que c'est PutObject qui est absent du TStrings de base, on se doute bien que le AddObject ne marchera pas...
    Ainsi Assign ne marche pas car AddStrings ne marche pas car AddObject ne marche pas car PutObject est vide...

    Bien plus que la doc, l'explication parfaite que tu m'as fournie est celle-ci :
    Sur un TMemo, les lignes peuvent être modifié automatiquement par WordWrap au redimensionnement du TMemo, comment géré le déplacement d'objet !
    Le reste m'a été moyennement utile mais merci quand même...

    Quand au CQFD, je le trouve déplacé, mais ceci n'est que mon simple avis.

    Thanks anyway.

    Th.

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 610
    Points : 25 298
    Points
    25 298
    Par défaut
    Citation Envoyé par Ziginou Voir le message
    Tout est relatif... Moi, je l'ai trouvée trop vague pour la comprendre...
    Quelle partie de la phrase, justement si tu ne l'as trouve pas clair, il faudrait nous dire quoi ! Je peux te l'expliquer !
    Après tout, on peut proposer des modifications de l'aide (feedback) ! Envoie leur un mail via le lien "Envoyer mon commentaire" en bas de Page!
    Je l'ai déjà fait, ils corrigent, parfois il traduise en français des extraits de code qui est un peu ballot !

    Citation Envoyé par Ziginou Voir le message
    Très subjectif comme remarque Avec des 'Il suffit de comprendre',
    tu n'avais pas vu le je te taquinais ! surtout que ton explication de code était excellente !
    T'inquiète, moi aussi j'ai lu les sources, l'aide était parfois mal traduit, on avait quelques erreurs dans CompareText, tout était inversé dans l'aide de D7 par rapport à celle de D6, la boulette !
    Parfois il manquait des points importants comme justement les limitations de l'implémentation, des notes pas toujours facile à trouver encore aujourd'hui mais au moins elles sont écrites maintenant !


    Sinon, désolé de t'avoir trollé

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 32
    Points : 32
    Points
    32
    Par défaut
    Quelle partie de la phrase, justement si tu ne l'as trouve pas clair, il faudrait nous dire quoi ! Je peux te l'expliquer !
    Après tout, on peut proposer des modifications de l'aide (feedback) ! Envoie leur un mail via le lien "Envoyer mon commentaire" en bas de Page!
    Je l'ai déjà fait, ils corrigent, parfois il traduise en français des extraits de code qui est un peu ballot
    !

    Tu m'as déjà tout expliqué et tes explications sont très claires, bien plus que l'aide apportée...
    Comme je te l'ai dit, je comprends pourquoi (wordwrap...), grâce à toi, pourquoi ça a été implémenté comme ça...
    En fait, je faisais un blocage (...à tort...) sur le fait que les lignes et les items étaient de type TStrings et que l'un prenait en charge les objets et pas l'autre...
    L'idéal aurait été d'avoir rajouté tes explications concernant le Wordwrap et d'insister sur le fait que le mémo et le combo ne manipulent pas des TStrings, mais des descendants avec des méthodes surchargées...

    tu n'avais pas vu le je te taquinais !
    Pas de problème : surtout que l'on a l'habitude de se faire taquiner par le Troll Pour tout te dire, c'est même sujet à plaisanterie chez nous où tes remarques taquines sont toujours appréciées (t'es une star chez nous Shai ) Mais rassure toi, tout le monde reconnaît aussi l'extrême justesse de tes propos, ainsi, tes taquineries sont largement acceptées

    surtout que ton explication de code était excellente !
    Un compliment du Troll ! Ben dis donc, je vais l'afficher celle-là !

    Sinon, désolé de t'avoir trollé
    Pas de problème

    Th.

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

Discussions similaires

  1. mod_rewrite fonctionne pour un vhost mais pas pour l'autre
    Par Romalafrite dans le forum Apache
    Réponses: 3
    Dernier message: 31/12/2014, 10h22
  2. Transformation qui marche pour une page mais pas pour l'autre
    Par pestakeur dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 06/11/2012, 16h34
  3. Réponses: 2
    Dernier message: 10/03/2010, 15h36
  4. un petit pas pour vous, un grand pas pour moi!
    Par gerv33 dans le forum Langage
    Réponses: 6
    Dernier message: 01/11/2009, 13h38
  5. Réponses: 9
    Dernier message: 25/04/2008, 21h21

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