In Delphi 2009, In one of my projects, I have a custom frame with some controls on it which I want to use as the base class for some other controls. I want to register this
Yes it can be done!
I have done precisely what you are asking in both Delphi 2007 and 2009 and can say that it works well for both versions irrespective of update level. I did run into some interesting problems along the way, but the final solution was very straight forward in hind sight (after beating my head against a wall for a day). More about this below in my answer.
I placed my custom frame into a runtime package referenced by my component's designtime package. This was necessary to allow the frame to be used in applications using runtime packages and also to allow the same frame to be used in other custom component packages. The designtime package also contained a custom module expert to add the frame to the File -> New -> Other... -> "New Items" gallery and to generate custom default module code. That later part was mainly a nicety to save coding time during actual usage and was a royal pain to get right. I chalk that up to learning curve since I could not find a complete example that matched my situation.
Code from the designtime DPK:
requires
DesignIDE,
FramePageListD11R,
...
contains
FramePageListPkgReg in 'FramePageListPkgReg.pas',
And from FramePageListPkgReg
implementation
{$R FramePageListIcons.res}
procedure Register;
begin
...
RegisterCustomModule(TBaseDisplayFrame, TCustomModule);
RegisterPackageWizard(TDisplayFrameModuleExpert.Create);
end;
My frame implementation had no visual components on the frame since my goal was to introduce virtual methods, published properties, events and to implement a custom interface for my dynamic frame handling logic. Here is the contents of the DFM file and part of the PAS file for reference. Please ignore the IDisplayFrameEvent interface since it is irrelevant to the current topic of discussion.
object BaseDisplayFrame: TBaseDisplayFrame
Left = 0
Top = 0
Width = 500
Height = 300
HorzScrollBar.Smooth = True
HorzScrollBar.Style = ssHotTrack
HorzScrollBar.Tracking = True
VertScrollBar.Smooth = True
VertScrollBar.Style = ssHotTrack
VertScrollBar.Tracking = True
TabOrder = 0
end
TBaseDisplayFrame = class(TFrame, IDisplayFrameEvent)
private
FOnPageShow : TDisplayFrameEvent;
FOnPageHide : TDisplayFrameEvent;
...
published
...
property OnPageShow: TDisplayFrameEvent read FOnPageShow write FOnPageShow;
property OnPageHide: TDisplayFrameEvent read FOnPageHide write FOnPageHide;
end;
As for getting the DFM to load, I did not need any special coding. What I did find is that there is a bug in the Delphi IDE that foo bars the inclusion of the form into the package. I do not recall all of the details, but the problem was easily fixed by manually editing the generated DPK code. Here is the relevant part of the DPK for reference. I suspect this is your main problem. Pay careful attention to the comment part of the line since that is critical to DFM inclusion in the package.
contains
BaseDisplayFrameModule in 'BaseDisplayFrameModule.pas' {BaseDisplayFrame: TFrame};
Once everything is working, you can create frames as usual and then modify the PAS file and DFM to inherit from the frame. As Jamo noted, do not forget to change "object" to "inherited" in the first line in the DFM. The only quirk I have seen is the name of event handlers on the inherited frame does not conform to typical Delphi naming conventions, but rather derives from the base frame class. This is purely cosmetic and I have not taken the time to figure out if there is an easy fix.
Best of luck!