I've got a custom frame I need to inherit from in multiple projects. This frame includes some code and some components, and it resides somewhere on disk, in it's own project directory. I don't want to COPY it to the Object Repository folder, that doesn't seem right to me: I'd end up having two copies of the form, one in my Mercurial-backed repository, one in Delphi's Object Repository. Absolutely not a good idea.
What I want is to have my frame in a Package and have the Package do all that's required to make the frame known to the IDE and allow the IDE to create new siblings of the given frame, without actually adding the frame to every single project.
What I've done so far, problems I've encountered, solutions I tried:
- I added my frame to a package, registered my frame using both
RegisterClass
and RegisterNoIcon.
Problem: When I go into some other project and try to open a derived frame for editing it says it can't find my original frame.
- To fix problem "1" I figured I'd have to register my frame as an Custom Module. So I called
RegisterCustomModule(TMyFrameName, TCustomModule)
. Problem: From the 'other' project I open a derived frame, the IDE doesn't create the components on my original frame and the IDE is complaining about one of the "inherited" components missing.
- To fix "2" I thought I'd give the IDE a helping hand by calling
InitInheritedComponent(Self, TFrame)
. This helped, when I tried opening the frame in the 'other' project everything got re-created and I was able to see the frame as I expected. Problem: when I save the frame it forgets all about the inherited components, treats every single component as a new component added to this particular frame. If I look into the saved DFM everything starts with "object", nothing starts with "inherited" as I'd expect.
Unfortunately I got stuck on problem "3". I tried digging into Classes.pas, ToolsAPI, DesignIntf and DesignEditors but didn't find anything helpful. Apparently the "inherited" attribute I was hoping to see in the DFM is generated by TWriter when it's "TWriter.Ancestor" property is assigned before streaming a TComponent, but there's no way for me to set it up, the IDE needs to set it up. And I can't convince the IDE to do it for me.
Here are the cumulated, relevant parts of code:
TTestFrame = class(TFrame)
public
constructor Create(Owner:TComponent);override;
end;
constructor TTestFrame.Create(Owner: TComponent);
begin
inherited;
if csDesignInstance in ComponentState then InitInheritedComponent(Self, TFrame);
end;
procedure Register;
begin
RegisterClass(TTestFrame);
RegisterNoIcon([TTestFrame]);
RegisterCustomModule(TTestFrame, TCustomModule);
end;
Any ideas, besideds "give up and put your stuff into Object Repository"?
Thanks!
Edit
Why I need to do this and why solutions that depend on actual path names getting written into my project's files don't work: I want to support Branching: when one branches it's reasonable to expect multiple versions of the same project being "alive" in different directories on the same machine. The corollary, I can't have multiple versions of the same project in the same place at the same time.
To make sure this works I decided to make my projects not depend on where the live, and to enforce this I have everyone on our team Clone (Mercurial terminology) or Check Out (SVN terminology) our projects in different directories. A hard-coded path on my system will not be good on my colleague's system: if any of us makes the mistake of hard-coding any sort of path into the application, it will not be long before it brakes on one of us, so the error gets fixed.
This is of course a problem with forms and frames that are part of some library (so they're not in our project's directory) that we need to inherit from! In order to get IDE support when working with those files we need to temporarily add them to the project and we need not forget removing them after we're done. If we forget and push/check in changes, the changes would brake the build for our colleagues (because they have the libraries checked out at different locations).
In order to solve this I attempted adding those frames and forms to a design time package (packages are loaded using full-path into the IDE, but the path is not part of the project's files so it's OK). Unfortunately this failed, and that's wyhy I posted this question.
See Question&Answers more detail:
os