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 :

Problème avec TPersistent


Sujet :

Composants VCL Delphi

  1. #1
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut Problème avec TPersistent
    Salut tout le monde,

    J'ai un petit problème avec un TPersistent.

    Je m'explique:

    J'ai deux composant: TCustomMachine qui hérite de TPersistent et TFlow qui hérite de TComponent:


    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
      TCustomMachine=class(TPersistent)
      private
        FCodeIMMO: Word;
        FIdHum:integer;
        procedure SetCodeIMMO(const Value: Word);
        procedure CheckCodeImmoValid(CodeImmo:integer);
      protected
        FOwner: TComponent;
        function GetOwner: TPersistent; override;
      public
        constructor Create(Aowner: TComponent); virtual;
        procedure Assign(Source : TPersistent); override;
      published
        property CodeIMMO:Word read FCodeIMMO write SetCodeIMMO;
      end;
     
    { TCustomMachine }
     
    procedure TCustomMachine.Assign(Source: TPersistent);
    begin
      if Source is TCustomMachine then
        TCustomMachine(Source).FCodeIMMO := FCodeIMMO
      else
        inherited;
    end;
     
    constructor TCustomMachine.Create(Aowner: TComponent);
    begin
      inherited create;
      FOwner:=AOwner;
    end;
     
    function TCustomMachine.GetOwner: TPersistent;
    begin
      Result:=FOwner;
    end;
     
    procedure TCustomMachine.SetCodeIMMO(const Value: Word);
    begin
      if value<>FCodeIMMO then
      begin
        FCodeIMMO:=Value;
        CheckCodeImmoValid(value);
      end;
    end;
     
    procedure TCustomMachine.CheckCodeImmoValid(CodeIMMO:integer);
    var
      MyQuery:TMyQuery;
    begin
      FIdHum:=-1;
      MyQuery:=TMyQuery.Create(nil);
      try
        with MyQuery do
        begin
          Connection:=TCustomFlow(FOwner).FMySQLConnection;
          SQL.Clear;
          SQL.Add('select id_hum,alias from machine.numero_hum where '+
          'code_immo=:CodeIMMO');
          Params[0].Value:=CodeIMMO;
          Execute;
          if Recordcount<>0 then
          begin
            First;
            FIdHum:=Fields[0].Value;
          end;
        end;
      finally
        MyQuery.Free;
      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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
      TCustomFlow=class(TComponent)
      private
        FMySQLConnection: TCustomMyConnection;
        FMachine:TMachine;
         procedure SetMachine(const Value: TMachine);
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
         property Connection:TCustomMyConnection read FMySQLConnection write
          FMySQlConnection;
         property Machine:TMachine read FMachine write SetMachine;
      end;
     
     
    constructor TCustomFlow.Create(AOwner: TComponent);
    begin
      inherited;
      FMachine:=TMachine.Create(self);
    end;
     
    destructor TCustomFlow.Destroy;
    begin
      FMachine.Free;
      inherited;
    end;
     
    procedure TCustomFlow.SetMachine(const Value: TMachine);
    begin
      FMachine.Assign(Value);
    end;
    Tout fonctionne parfaitement dans l'inspecteur d'object.
    Mais quand je compile mon logiciel, la méthodeTCustomMachine.SetCodeIMMO
    est appelée, alors que je n'ai pas encore la connection dans FMysqlConnection
    et forcement j'ai mon application qui plante dans la procédure TCustomMachine.CheckCodeImmoValid.

    Il faut bien comprendre que toutes les interconnections sont définies au moment du design et que je n'ai aucun code dynamique qui change les property.

    La seule solution que j'ai trouvé est de tester avant l'éxécution de la procédure si FMySQLConnection est différent de Nil. Mais cela m'oblige à rajouter une méthode dans TCustomFlow pour "rafraichir" mon objet FMachine, une fois que ma connection est valide.

    Y a t il un moyen de résoudre ce problème plus facilement ?

    J'espere que mes explications sont claires.

    Cordialement

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 457
    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 457
    Points : 24 870
    Points
    24 870
    Par défaut
    Il manque le code où tu instancies tes objets, au moment où tu affecte une connexion à TCustomFlow !
    Qui modifie CodeIMMO ? tu as une affectation explicite ? tu as un chargement via RTTI ?

    Tu pourais mettre ta connexion dans un singleton via une propriété de classe (ou en bidouillant une fonction de classe pour D7), ainsi tu initialise la connexion au 1er Accès ... sauf si tu as besoin de plusieurs connexions ... ça se complique ...

    Sinon comme le Owner de TCustomMachine est un TComponent, tu peux voir avec ComponentState si le composant est en csDesign, tu peux ainsi avoir un code pour l'IDE et un autre pour le RunTime
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    je ne me suis jamais servi des propriété de classe, t as pas un tutoriel pour que je comprenne mieux ?

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Les méthodes et propriétés de classe s'écrivent de la même manière que les méthodes et propriétés standards sauf qu'il faut précéder leur déclaration par le mot clé class.

    Pour l'interprétation derrière par contre c'est complètement différent. Les propriétés et méthodes standards sont accessibles via les instances que tu créé de chaque objet. Les propriétés et méthodes de classe n'appartiennent pas à une instance en particulier, elles appartiennent à toute la classe (et les classes dérivées).

    Dès lors l'appel n'est plus MonInstance.MaPropriete mais TMaClasse.MaPropriete. Chaque propriété/champ/méthode est unique dans tout le programme ce qui définit bien le comportement de singleton.
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  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 445
    Points
    28 445
    Par défaut
    Oui, c'est un des trucs pénible quand tu réalises des composants comme ça

    il faut jouer sur ComponentState et la méthode Loaded pour déclencher des traitements après que toutes les propriétés aient été fixées. Exemple :

    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
     
    procedure TCustomMachine.SetCodeIMMO(const Value: Word);
    begin
      if value<>FCodeIMMO then
      begin
        FCodeIMMO:=Value;
        if not csLoading in ComponentState then
          CheckCodeImmoValid(value);
      end;
    end;
     
    procedure TCustomMachine.Loaded;
    begin
      inherited;
      if FCodeIMMO<>0 then
       CheckCodeImmoValid(FCodeIMMO);
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. VC++ Direct3D8, problème avec LPD3DXFONT et LPD3DTEXTURE8
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 03/08/2002, 11h10
  2. Problème avec [b]struct[/b]
    Par Bouziane Abderraouf dans le forum CORBA
    Réponses: 2
    Dernier message: 17/07/2002, 10h25
  3. Problème avec le type 'Corba::Any_out'
    Par Steven dans le forum CORBA
    Réponses: 2
    Dernier message: 14/07/2002, 18h48
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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