Jump to content
Sign in to follow this  
brk303

Component names cleared in design package

Recommended Posts

I have a design time package which has a form linked to a datamodule.

The same code is used for a standalone app, in which everything works fine, but in design time package the links between forms/datamodules are not restored.

 

I have used RegisterFindGlobalComponentProc to hook in my function that does this:

  if AnsiSameText(Name, 'dmxxx) then
    Result := dmxxx

This fixes the links from form to dmxxx, but I then found the dmxxx has name = '' and ComponentCount = 0, there should be 3 components on datamodule.

All of this runs fine in standalone app outside IDE.

 

Does anyone know what is different with component name/linking/restoring in IDE compared to standalone ?

Share this post


Link to post
51 minutes ago, brk303 said:

I have a design time package which has a form linked to a datamodule.

The same code is used for a standalone app, in which everything works fine, but in design time package the links between forms/datamodules are not restored.

 

I have used RegisterFindGlobalComponentProc to hook in my function that does this:

  if AnsiSameText(Name, 'dmxxx) then
    Result := dmxxx

This fixes the links from form to dmxxx, but I then found the dmxxx has name = '' and ComponentCount = 0, there should be 3 components on datamodule.

All of this runs fine in standalone app outside IDE.

 

Does anyone know what is different with component name/linking/restoring in IDE compared to standalone ?

As far as I know forms (all TCustomForm descendants in fact, including TDatamodule) are not meant to be added to design-time packages. If you want to make them reusable from other projects add them to the object repository instead, this way they are accessible from the File -> New -> Others dialog.

Share this post


Link to post

Yes, but Form is a custom component editor, like say a DBConnection wizard, so it's not the kind you inherit in the project.

Share this post


Link to post

Do you make sure that the datamodule is created before the form is loaded?

In similar cases I usually create the datamodule with the form as parent in the form Create (i.e. before the form is loaded). That guarantees that the references to the datamodule can be resolved.

If you are interested there are some explanations about DFM loading in this article: Tweaking DFM Loading

Share this post


Link to post

I made new package with simple TComponent that creates a form, to debug it (since my real project is too big).

It seems the problem is here:

constructor TCustomForm.Create(AOwner: TComponent);

begin

....

    InitializeNewForm;
    if (ClassType <> TForm) and not (csDesigning in ComponentState) then
    begin
      Include(FFormState, fsCreating);
      try
        DisableAlign;
        if not InitInheritedComponent(Self, TForm) then
          raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);

...

end;

So if a TForm descendant is in csDesigning then InitInheritedComponent is not called and thus .dfm resouce is not loaded, so component name will stay blank, and all components in dfm will not be created.

Not quite sure what to do now, one of components contains significant amount if data stored in dfm, so I can't just create it in code.

 

 

Share this post


Link to post
Just now, Uwe Raabe said:

Do you make sure that the datamodule is created before the form is loaded?

Yes, I have a standalone project with same code, that I can debug easier, and everything is correct there, so order of construction, etc is all fine.

Since the code is same, the difference must be in VCL behavior at design time, and it seems what I wrote in previous post is the problem. Delphi does not load .dfm resource for forms created at design time. I was not aware of this, and it sounds severely limiting.

Share this post


Link to post

So if anyone is interested in the future, what I did to solve the problem was:

 

In constructor of Form and Datamodule that I want to use at design time, I added the following:

 

constructor TdmXXX.Create(AOwner: TComponent);
begin
  inherited;
  if (csDesigning in ComponentState) then
    if not InitInheritedComponent(Self, TDataModule) then
      raise EResNotFound.CreateResFmt(@SResNotFound, [ClassName]);
end;

constructor TdmModelEdit.Create(AOwner: TComponent);
begin
  inherited;
  if (csDesigning in ComponentState) then
    if not InitInheritedComponent(Self, TDataModule) then
      raise EResNotFound.CreateResFmt(@SResNotFound, [ClassName]);
end;

So this is the opposite of what happens in TCustomForm.Create.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×