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 :

Composant et message de violation d'accès sur inherited dans la méthode Create


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 37
    Points : 17
    Points
    17
    Par défaut Composant et message de violation d'accès sur inherited dans la méthode Create
    Bonjour à tous,

    je suis en train de créer un composant qui utilise les TCollection. Je suis presqu' arrivé à quelque chose qui me convient mais cependant il me reste un message d'erreur qui apparaît quand je veux ajouter un TColletionItem à ma collection. voici mes classes un peu simplifiées:
    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
    TIndicator = class(TCollectionItem)
      private
        FSesTimeLine:   TSesTimeLine;
        FDateTime:      TDateTime;
        ...
      protected
        function GetDisplayName : string; override;
      public
        constructor Create(Collection: TCollection); override;
        destructor Destroy(); Override;
     
        procedure Assign(Source : TPersistent); override;
        ...
     
      published
        ...
      end;
     
      {CLASS TIndicators}
      TIndicators = class(TCollection)
      private
        FSesTimeLine: TSesTimeLine;
     
        function GetItem(Index: Integer): TIndicator;
        procedure SetItem(Index: Integer; Value: TIndicator);
      protected
        function GetOwner : TPersistent; override;
        procedure Update(Item : TCollectionItem); override;
        ...
      public
        constructor Create(ASesTimeLine: TSesTimeLine);
     
        function Add: TIndicator;
        function AddItem(Item: TIndicator; Index: Integer): TIndicator;
        function Insert(Index: Integer): TIndicator;
        ...
      end;
     
      {CLASS TSesTimeLine}
      TSesTimeLine = class(TCustomControl) 
      private
        { Déclarations privées }
        FOwner:               TComponent;
        FIndicators:          TIndicators;
        ...
        procedure DrawBackground(Canvas: TCanvas);
        ...
      protected
        { Déclarations protégées }
        procedure Paint(); override;
        procedure Resize; override;
        ...
      public
        { Déclarations publiques }
        constructor Create(AOwner:TComponent); override; {CREATE}
        destructor Destroy(); Override;
        procedure Loaded; override;
     
        {Add Indicator}
        procedure AddIndicator(ADateTime: TDateTime; AID:Integer; AKind: Integer; ADisplayText: String);
        ...
      published
        { Déclarations publiées }
        ...
        {Indicators}
        property Indicators: TIndicators read FIndicators write SetIndicators;
        ...
        {custom events}
        property OnIndicatorClick: TIndicatorClick read FOnIndicatorClick write FOnIndicatorClick;
      end;
    et les implémentations des méthodes:
    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
    constructor TIndicator.Create(Collection : TCollection);
    begin
      inherited Create(Collection);
     
      FSesTimeLine := TIndicators(Collection).FSesTimeLine;
     
      ...
    end;
     
    constructor TIndicators.Create(ASesTimeLine: TSesTimeLine);
    begin
      inherited Create(TIndicator);
      FSesTimeLine:=ASesTimeLine;
    end;
     
    function TIndicators.Add: TIndicator;
    begin
      RESULT:=TIndicator(inherited Add); {RESULT}
    end;
     
    function TIndicators.AddItem(Item: TIndicator; Index: Integer): TIndicator;
    begin
      if Item = nil then
        Result := Add {RESULT}
      else
        Result := Item; {RESULT}
      if Assigned(Result) then
      begin
        Result.Collection := Self;
        if Index < 0 then
          Index := Count - 1;
        Result.Index := Index; {RESULT}
      end;
    end;
     
    constructor TSesTimeLine.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
     
      {avoid flicker}
      ControlStyle:=ControlStyle + [csOpaque];
     
      {Init}
      FOwner:=AOwner;
     
      ...
     
      {Indicator}
      FIndicators:=TIndicators.Create(Self);
    end;
     
    destructor TSesTimeLine.Destroy;
    begin
      FIndicators.Free;
      inherited;
    end;
     
    procedure TSesTimeLine.AddIndicator(ADateTime: TDateTime; AID, AKind: Integer; ADisplayText: String);
    var
      Kind:           TIndicatorKind;
      Indicator:      TIndicator;
    begin
      {on récupère le type}
      Kind:=TIndicatorKind(AKind);
     
      {Methode 1}
      Indicator:=TIndicator.Create(FIndicators);
      Indicator.Width:=120;
      Indicator.Height:=20;
      Indicator.DateTime:=ADateTime;
      Indicator.ID:=AID;
      Indicator.Kind:=TIndicatorKind(AKind);
      Indicator.Text:=ADisplayText;
      FIndicators.AddItem(Indicator,-1);
     
      {Methode 2}
    //  Indicator:=FIndicators.Add();
    //  Indicator.Width:=120; //Random(100);
    //  Indicator.Height:=20;
    //  Indicator.DateTime:=ADateTime;
    //  Indicator.ID:=AID;
    //  Indicator.Kind:=TIndicatorKind(AKind);
    //  Indicator.Text:=ADisplayText;
    end;
    Donc si j'utilise la méthode 1 ou 2 de TSesTimeLine.AddIndicator, j'ai une violation d'accès à l'adresse 004BBCF1 dans le module Test.exe. Lecture de l'adresse 00000299. En mode debug, la violation intervient sur la ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    inherited Create(Collection);
    du constructeur constructor TIndicator.Create(Collection : TCollection);

    Après avoir cherché pas mal sur le net, et regardé attentivement les tuto de création de composant sur Developez, je n'ai rien trouvé pour solutionner mon problème. Quelqu'un a t'il une piste ? merci d'avance.

    Vincent

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 469
    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 469
    Points : 24 905
    Points
    24 905
    Par défaut
    1ère Question :
    Pourquoi redéclarer FOwner, utilise la propriété Owner hérité du TComponent !

    2eme Question :
    Où est le code appelant AddIndicator, es-tu sur que ton Control TSesTimeLine est complètement initialisé lors de l'appel de AddIndicator
    FIndicators est bien initialisé dans AddIndicator

    3eme Question :
    ton constructeur de TCollection TIndicators (TSesTimeLine) est-il correctemment appelé ?

    Perso, j'utiliserais plutôt la méthode 2, c'est la méthode souhaitée pour la TCollection
    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 à l'essai
    Profil pro
    Inscrit en
    Août 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 37
    Points : 17
    Points
    17
    Par défaut
    merci pour ton aide.

    Citation Envoyé par ShaiLeTroll Voir le message
    Pourquoi redéclarer FOwner, utilise la propriété Owner hérité du TComponent !
    Le manque d'expérience peut être. Bonne remarque. J'ai corrigé.

    Citation Envoyé par ShaiLeTroll Voir le message
    Où est le code appelant AddIndicator, es-tu sur que ton Control TSesTimeLine est complètement initialisé lors de l'appel de AddIndicator
    FIndicators est bien initialisé dans AddIndicator
    Le code appelant se trouve sur un bouton dans une petite forme de test ou j'ai déposé le composant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.btn4Click(Sender: TObject);
    var
      dt: TDateTime;
    begin
      dt:=EncodeDateTime(2011, 05, 01, 12, 00, 00, 00);
      tlTest1.AddIndicator(dt, 1234, 1, FormatDateTime('YYYY-MM-DD hh:nn:ss:zzz',
          dt));
    end;
    En mode design, je peux ajouter sans problème des Indicators dans ma classe TSesTimeLine grâce à l'inspecteur d'objets. Et si je lance l'appli, ils sont affichés correctement, par contre si j'en ajout un avec la fonction AddIndicator, j'ai la violation d'accés à inherited mais il m'ajoute bien mon indicateur.

    Citation Envoyé par ShaiLeTroll Voir le message
    Ton constructeur de TCollection TIndicators (TSesTimeLine) est-il correctement appelé ?
    Je suis passé en mode debug, il est bien appelé correctement avant que je fasse appelle à AddIndicator.

    Citation Envoyé par ShaiLeTroll Voir le message
    Perso, j'utiliserais plutôt la méthode 2, c'est la méthode souhaitée pour la TCollection
    C'est celle que j'avais pris en premier mais j'ai fait des tests avec l'autre pour voir si c'était mieux. Malheureusement les 2 but sur inehrited.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 37
    Points : 17
    Points
    17
    Par défaut
    OK, j'ai trouvé ma boulette:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    TIndicators = class(TCollection)
      private
        FSesTimeLine: TSesTimeLine;
      protected
        procedure Update(Item : TCollectionItem); override;
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TIndicators.Update(Item: TCollectionItem);
    begin
      inherited;
     
      FSesTimeLine.Repaint;
    end;
    au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TIndicators.Update(Item: TCollectionItem);
    begin
      FSesTimeLine.Invalidate;
    end;
    merci à ceux qui ont passé ne serais ce que quelques secondes à lire mon message ou à m'aider.

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

Discussions similaires

  1. [BSD 2006] Erreur de violation d'accès sur un ShowModal
    Par doudoustephane dans le forum C++Builder
    Réponses: 36
    Dernier message: 14/10/2006, 12h10
  2. Violation d'accès sur un TIdFTP
    Par cfalcot dans le forum Web & réseau
    Réponses: 9
    Dernier message: 09/05/2006, 15h14
  3. Message de violation d'accès dans la dcc50.dll
    Par cchatelain dans le forum EDI
    Réponses: 17
    Dernier message: 29/11/2005, 18h28
  4. violation d'accès sur open de TQuery
    Par letissya dans le forum Bases de données
    Réponses: 5
    Dernier message: 08/11/2005, 14h35
  5. Violation d'accès sur un TXMLDocument
    Par WebPac dans le forum Composants VCL
    Réponses: 14
    Dernier message: 15/03/2005, 15h10

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