0

I'm having a problem with Delphi XE to access in designtime a read-only property derived from another component only in cases where the component in question it is a specialized form or datamodule.

I have a "Comp1" component and a "Comp2". In "Comp2" component, have a published reading "Comp1" only property.

Plant the "Comp1" component in the "Form1". I specialize "Form1" generating "Form2". If I try to access the "Comp1" property in "Form2" it creates an "Access Violation".

Only identified this problem in Delphi XE. In Delphi 6, tested and works normally. I did not actually test on newer versions XE3, XE4 or XE5.

In the code below I show the case.

Unit UnTestComp;

Interface

Uses Classes, StdCtrls;

Type
  //Component 1

  TComp1 = Class(TComponent)
  Private
    FNome: String;
    FEdit: TEdit;
    Function GetText: String;
    Procedure SetText(Const Value: String);
  Public
    Constructor Create(AOwner: TComponent); Override;
    Destructor Destroy; Override;
  Published
    Property Nome: String Read FNome Write FNome;
    Property Texto: String Read GetText Write SetText;
  End;


  // Component 2
  TComp2 = Class(TComponent)
  Private
    FComp1: TComp1;
  Protected

  Public
    Constructor Create(AOwner: TComponent); Override;
    Destructor Destroy; Override;
  Published
    Property Comp1: TComp1 Read FComp1;

  End;

Procedure Register;

Implementation

Uses SysUtils, Dialogs;

Procedure Register;
Begin
  RegisterComponents('CompReadOnly Test', [TComp1, TComp2]);
End;

{ TComp1 }

Constructor TComp1.Create(AOwner: TComponent);
Begin
  Inherited;
  FEdit := TEdit.Create(Self);
End;

Destructor TComp1.Destroy;
Begin
  FreeAndNil(FEdit);
  Inherited;
End;

Function TComp1.GetText: String;
Begin
  Result := FEdit.Text;
End;

Procedure TComp1.SetText(Const Value: String);
Begin
  FEdit.Text := Value;
End;

{ TComp2 }

Constructor TComp2.Create(AOwner: TComponent);
Begin
  Inherited;
  FComp1 := TComp1.Create(Self);
  FComp1.Name := 'Comp1';
End;

Destructor TComp2.Destroy;
Begin
  FreeAndNil(FComp1);
  Inherited;
End;

End.

Someone had a similar problem that can share a possible solution?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Delphiman
  • 373
  • 4
  • 15
  • I cannot see anything wrong on the code you use. Just do not free `FComp1` when you specify `Self` as an owner of it (`TComp1.Create(Self)`). The owner will take care of its release. But even that should not cause a problem that you describe. You can freely pass an instance of `TComp2` to a different form and access its `Comp1` property. Didn't you mistakenly call `Comp1.Free` for instance ? – TLama Apr 03 '14 at 13:05
  • Why do you call FreeAndNil for internal components with Owner? – MBo Apr 03 '14 at 13:07
  • Hi. TLama and MBo, I not use "Free" in instance. This little component test, is enough to generate the error. I use FreeAndNil by habit. I know it is not necessary to use when I create the object with "Self". But the problem is not I forcing the release of the object. Believe to be a bug in Delphi XE. – Delphiman Apr 03 '14 at 13:21
  • I can't see an error here. The error might be in the code that creates Form1 and Form2. Perhaps you have Form1 := tForm1.Create(Application), and within the constructor of tForm1, you create Form2, and then within the constructor of tForm2 you try to access Form1.Comp2.Comp1, but Form1 has not yet been assigned. But then why would that work in D6 but not DXE? This is all speculation of course. We'd have to see that code. – David Dubois Apr 03 '14 at 17:57
  • Hi user1008646. The error happened in designtime. The code The above code is complete. If a package is created and registered the component mentioned in the example. To reproduce the errors you need the following. 1) Create a form "Form1" and add the component created. 2) It creates a legacy of "Form1". By clicking the component in the inherited form, the error is generated. The code in this post already spent generates the problem that I mentioned. – Delphiman Apr 03 '14 at 19:43
  • Friends. In https://drive.google.com/file/d/0B5LYCu1APjPsd0J3WWJVMHRNeU0/edit?usp=sharing attach the sample to illustrate the problem. – Delphiman Apr 03 '14 at 20:15
  • is TComp1.FEdit parented by anything? – Igor Apr 04 '14 at 01:47

1 Answers1

0

How not found the cause of the problem. I'm change the property to "public" and when needed access via RTTI. Previously, due to a legacy code, the property was "published" in Delphi 6 because we could only access via RTTI if the property was published. Currently, in Delphi XE, due to the improved features of the RTTI that is no longer needed.

Sample:

  TComp2 = Class(TComponent)
  Private
    FComp1: TComp1;
  Protected

  Public
    Constructor Create(AOwner: TComponent); Override;
    Destructor Destroy; Override;
    Property Comp1: TComp1 Read FComp1;
  End;

Thank you for your attention.

Delphiman
  • 373
  • 4
  • 15