0
votes

I tried to create a very simple component(Tgraph) using the FireMonkey platform (XE7). First of all I create two new classes: 1) TGraph (anchestor type TLayout); 2) TMyPlot1D(anchestor type Tpanel); I saved two units and created a package called 'MyPackage'. I compiled and Installed it in the "Samples" page. I opened a new Firemonkey project and drag and drop the TGraph instance in the form. Everything works well. At designtime,I can see the component as defined, and all the relevant units are visible from the main unit. The relevant code is in the following:

First Class

unit UMyPlot;

interface

 uses
 System.SysUtils, System.Classes, FMX.Types, 
 FMX.Controls, FMX.StdCtrls;

 type
 TMyPlot1D = class(TPanel)
 private
  { Private declarations }
 protected
  { Protected declarations }
 public
  { Public declarations }
 published
  { Published declarations }
 end;

 procedure Register;

 implementation

 procedure Register;
 begin
  RegisterComponents('Samples', [TMyPlot1D]);
 end;

 end.

Second Class

unit UMyGraph;

interface

uses
 System.SysUtils, System.Classes, FMX.Types, FMX.Controls, FMX.Layouts,      
 UMyPlot;

type
  TMyGraph = class(TLayout)
  private
    Plot : TmyPlot1D;
  public
    constructor create(Aowner:TComponent); override;
  end;

 procedure Register;

implementation

 procedure Register;
  begin
   RegisterComponents('Samples', [TMyGraph]);
  end;

 constructor TMyGraph.create(Aowner: TComponent);
  begin
   inherited;
   Plot := TMyPlot1D.Create(Self);
   plot.Parent := Self;
 end;

 end.

The problem is shown when I try to run my application. I got the following error: "Exception EClassNotFound in module Project1.exe at 000A51FA. Class TmyPlot1D not Found". The failed function seems to be the Application.RealCreateForms.

If I drag and drop only the TmyPlot1D instance, it works (of course) both in designtime and in runtime!

Any ideas?

Thanks in advance

2

2 Answers

2
votes

In your TMyGraph.Create you are creating a child object, Plot. This behaviour happens at both design time and at runtime.

At runtime there's no problem, but the problem is occurring because when you save your design time form the children of the component are also streamed out to the FMX file.

When you run your app it streams the form in and attempts to stream in the TMyGraph and the TMyPlot1D child object which was created at design time, which fails. Even if it succeeded you would have a problem because you would have both the TMyPlot1D created at design time and the one created at run time.

You can solve this by setting the Stored := False for any children you create at design time, so your Create method will look like this:

constructor TMyGraph.Create(Aowner: TComponent);
begin
  inherited;
  Plot := TMyPlot1D.Create(Self);
  Plot.Parent := Self;
  Plot.Stored := False;
end;

Now we come to the reason why the class if failing to be read in by the streaming system. In FMX you need to call RegisterFMXClasses (Classes unit) to enable a class to be streamed into a form. You need to put this in the initialization section at the end of your units (before the final end.), e.g.:

initialization
  RegisterFMXClasses([TMYGraph]);
end.
0
votes

this command is very vital:

Tcomponent.Stored := true;