brk303 0 Posted December 7, 2022 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
PeterBelow 238 Posted December 7, 2022 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
brk303 0 Posted December 7, 2022 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
Uwe Raabe 2057 Posted December 7, 2022 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
brk303 0 Posted December 7, 2022 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
brk303 0 Posted December 7, 2022 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
brk303 0 Posted December 8, 2022 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