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 :

[XE] Variable et Class Helper


Sujet :

Langage Delphi

  1. #1
    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 [XE] Variable et Class Helper
    Bonjour,

    Je rencontre un petit soucis avec l'utilisation des class Helper avec les variables

    Ex :

    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
     
      TEditClassHelper = class Helper for TEdit
        Class Var 
          FOldValue : String;
        private
         procedure FSetOldValue(AValue : String);
         function FGetOldValue : String;
        published
          function IsDifferent : Boolean;
          property OldValue : String read FGetOldValue write FSetOldValue;
      end;
     
    Class function TEditClassHelper.FGetOldValue: String;
    begin
      Result := FOldValue;
    end;
     
    Class procedure TEditClassHelper.FSetOldValue(AValue: String);
    begin
     
      FOldValue:= AValue;
      Self.Text := AValue;
    end;
     
    function TEditClassHelper.IsDifferent: Boolean;
    begin
      Result := trim(Self.Text) <> trim(FOldValue);
    end;
    Le soucis se trouve quand j'appelle FoldValue car la valeur est toujours la même quelques soit le composant TEdit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      Edit1.OldValue := 'Toto';
      Edit2.Oldvalue := 'Titi';
     
      ShowMessage(Edit1.Text + ' - ' + Edit1.OldValue); // Toto - Titi
      Showmessage(Edit2.Text + ' - ' + Edit2.OldValue); // Titi - Titi
    En fait FOldValue prend la valeur du dernier TEdit.

    Et la je suis perdu ^^

    Quelqu'un a une idée du soucis ?

    Merci

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    En même temps, tu as déclaré class var et class function
    C'est donc logique !
    Ce sont des variables au niveau de la classe et non au niveaux des instances !

    C'est la suite de ton sujet [D2007] Class Helper : Modifier un évènement ? et comme le rappelais sjrd : "Un type d'assistance peut ne pas déclarer de données d'instance, mais les champs de classe sont autorisés." : ce qui implique pas de champ supplémentaire

    J'ai l'impression que dans la documentation Assistances de classes et d'enregistrements (Delphi), il y a une erreur, cela évoque des "champs de classe" mais c'est quoi ? des membres d'instances ou des membres de classe au sens POO ?

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 753
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 753
    Points : 13 337
    Points
    13 337
    Par défaut
    Tu ne peux tout simplement pas ! N'oublie pas que tu travailles sur la classe elle-même et non une instance de classe.

    Bizarre même que ça compile. Les getter/setter de variables de classe doivent être static et les propriétés définies en class property (différence class-helper ou doux mélange ?)

  4. #4
    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
    Citation Envoyé par ShaiLeTroll Voir le message
    En même temps, tu as déclaré class var et class function
    C'est donc logique !
    Ce sont des variables au niveau de la classe et non au niveaux des instances !
    Je pense que j'ai quelques lacunes la dedans

    Citation Envoyé par ShaiLeTroll Voir le message
    Pas vraiment la même chose.
    En fait je voulais faire que mes TEdit garde l'ancienne valeur en mémoire (d'où la création de FOldValue) et puis me faire une petite function qui permet de retourner si la nouvelle valeur et ancienne sont identiques.
    Je pense que je vais passer par le HelpKeyWord du composant TEdit pour stocker cette valeur (même si c'est pas très propre)

    Citation Envoyé par ShaiLeTroll Voir le message
    J'ai l'impression que dans la documentation Assistances de classes et d'enregistrements (Delphi), il y a une erreur, cela évoque des "champs de classe" mais c'est quoi ? des membres d'instances ou des membres de classe au sens POO ?
    Vu le peu de doc la dessus, j'ai eu un peu de mal, j'ai trouvé quelques exemples mais rien de parlant.
    1 seul utilisait des Class Var

    http://www.codingtiger.com/questions...e-fonts-..html

    Citation Envoyé par Andnotor Voir le message
    Tu ne peux tout simplement pas ! N'oublie pas que tu travailles sur la classe elle-même et non une instance de classe.

    Bizarre même que ça compile. Les getter/setter de variables de classe doivent être static et les propriétés définies en class property (différence class-helper ou doux mélange ?)
    C'est un copier/M...der, des tests que j'avais fait, les Class devant les fonctions ne doivent pas y être

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    les class helpers sont là pour habiller les classes .Net existantes avec de nouvelles méthode statiques, ce n'est pas supposé être utilisé pour autre chose.

    dans ton cas tu as juste besoin de surcharger TEdit, et si tu ne veux pas créer de nouveau composant TEditPlus, tu peux simplement surcharger TEdit dans ta fiche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    type
      TEdit = class(StdCtrls.TEdit)
      private
        FOldValue : string;
        ...
      end;
     
      TForm1 = class(TForm)
        Edit1: TEdit;
        ...
      end;
    le simple fait de surcharger TEdit avant la déclaration de TForm1 suffit, tu peux aussi placer cette déclaration dans une unité si elle se trouve APRES StdCtrls dans la clause Uses.

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 753
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 753
    Points : 13 337
    Points
    13 337
    Par défaut
    Question class var, un petit tout dans la FAQ

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    Sinon il y a la propriété Tag utilisé la comme un pointeur sur une classe !
    On faisait ce genre de chose avant de les helper existe !

    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
    TEditHistoric = class
      private
        FOldValues : TStringList;
        FOldChange: TNotifyEvent;
     
        procedure ChangeHandler(Sender: TObject);
        function GetOldValues(Index: Integer) : String;
        function GetLastValue(): String;
      public
        constructor Create(AEdit: TEdit);
        destructor Destroy(); override;
     
        property OldValues[Index: Integer] : String read GetOldValues;
        property LastValue : String read GetLastValue;
      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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    constructor TEditHistoric.Create(AEdit: TEdit);
    begin
      FOldValues := TStringList.Create();
      FOldChange := AEdit.OnChange;
      AEdit.OnChange := ChangeHandler;
    end;
     
    constructor TEditHistoric.Destroy();
    begin
      FreeAndNil(FOldValues);
    end;
     
    procedure TEditHistoric.ChangeHandler(Sender: TObject);
    begin
      FOldValues.Add(TEdit(Sender).Text);
     
      if FOldChange then
        FOldChange(Sender);
    end;
     
    function TEditHistoric.GetOldValues(Index: Integer) : String;
    begin 
      Result := FOldValues[Index];
    end;
     
    function TEditHistoric.GetLastValue(): String;
    begin 
      if FOldValues.Count > 0 then
        Result := FOldValues[FOldValues.Count - 1]
      else
        Result := '';
    end
    l'utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Edit1.Tag := NativeInt(TEditHistoric.Create(Edit1)); // NativeInt pour XE2, sinon integer
    libération
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if Edit1.Tag <> 0 then
    begin
      TEditHistoric(Edit1.Tag).Free(); // une TObjectList peut aussi faire ce boulot !	  
      Edit1.Tag := 0;	
    end;

    published ne sert qu'au DFM, un helper peut-il s'installer en package ???

    EDIT :

    Citation Envoyé par Paul TOTH Voir le message
    le simple fait de surcharger TEdit avant la déclaration de TForm1 suffit, tu peux aussi placer cette déclaration dans une unité si elle se trouve APRES StdCtrls dans la clause Uses.
    Je connais aussi la technique de la surcharge avec le même nom de classe, je ne l'ai jamais pratiqué en production (juste pour le hack de propriété protected )
    Comment cela se comporte à la création du TEdit, cela utilise la nouvelle classe ?
    FindClass du coup renvoie la nouvelle classe de TEdit et non celle de la VCL, sinon il y aurait une violation d'accès pour une mémoire non allouée pour FOldValue
    Du coup, tous les TEdit de l'appli utilise ce nouveau TEdit ?
    Faudra que j'essaye un jour ! Je suis en C++Builder, on ne peut pas faire cette tricherie, mais je peux inclure des fichiers PAS, a étudier !

  8. #8
    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
    @Shai : Oui j'y avais pensé par le TAG ^^

    Merci à tous pour vos exemples & co.
    J'oublie à chaque fois la méthode par surcharge qui fonctionne parfaitement

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 560
    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 560
    Points : 25 156
    Points
    25 156
    Par défaut
    Je confirme en C++Builder, cela rale un peu, mais ça fonctionne le coup du TButton = class(StdCtrls.TButton),
    par contre,
    il faut explicitement typé le TButton et là le RAD n'est pas content, mais un #define pour le berner suffit
    cela ne semble faire effet que sur les TForm ayant fait un include !
    Comment le FindClass fait-il pour créer des TButton normal pour une TForm et des TButton "surchargée" pour une autre TForm ???

    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
    unit ControlDelphiImpl;
     
    interface
     
    uses SysUtils, Windows, Classes, StdCtrls, Variants;
     
    // Cette unité est juste conserve pour l'extrait de code !
     
    type
      TButton = class(StdCtrls.TButton)
      private
        FMessage : string;
        class var FCount: Integer;
      public
        constructor Create(AOwner: TComponent); override;
      end; 
     
    implementation
     
    constructor TButton.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
     
      Inc(FCount);
      FMessage := Format('%d Instances de %s (%d + %d = %d)', [FCount, Self.ClassName, StdCtrls.TButton.InstanceSize, sizeof(FMessage), Self.InstanceSize]);
      OutputDebugString(PChar(FMessage));
    end;
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <StdCtrls.hpp>
    #include "ControlDelphiImpl.hpp"
    #define TButton Controldelphiimpl::TButton
    //---------------------------------------------------------------------------
    class TTrucForm : public TForm
    {
    __published:	// Composants gérés par l'EDI
      TButton *BtnMachin; // en réalité c'est un Controldelphiimpl::TButton
    // Controldelphiimpl::TButton *BtnMachin; // ça fait raler le Concepteur à cause de type différent !



    @Rayek ou @Paul TOTH, si vous incluez ce fichier dans la MainForm, est-ce cela impacte les autres TButton de votre appli ?
    Ou est-ce comme en C++Builder c'est séparé pour chaque TForm ?

    Delphi et son RegisterClasses magique des DFM !
    Je ne sais pas comme il s'y retrouve !

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    @Rayek ou @Paul TOTH, si vous incluez ce fichier dans la MainForm, est-ce cela impacte les autres TButton de votre appli ?
    Ou est-ce comme en C++Builder c'est séparé pour chaque TForm ?

    Delphi et son RegisterClasses magique des DFM !
    Je ne sais pas comme il s'y retrouve !
    je dois dire que je n'ai jamais compris pourquoi ça fonctionnait non plus ^^ mais c'est bien LE composant déclaré dans CHAQUE unité en particulier qui est utilisé. Tu peux donc utiliser cette technique de façon différente pour chaque unité.

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

Discussions similaires

  1. Accès a des variables de classes
    Par lalouve dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 11/05/2006, 16h48
  2. variable de classe en Python
    Par Thierry Chappuis dans le forum Général Python
    Réponses: 5
    Dernier message: 09/02/2006, 22h06
  3. Variable de classe JPanel
    Par Janitrix dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 11/12/2005, 17h50
  4. débutant:utilisation de variable entre classe
    Par troojan dans le forum MFC
    Réponses: 1
    Dernier message: 07/12/2005, 23h31
  5. Réponses: 6
    Dernier message: 23/09/2005, 12h54

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