I've used frames in Delphi for years, and they are one of the most powerful features of the VCL, but standard use of them seems to have some risk such as:
It's easy to accidentally move or edit the frame sub-components on a frame's host form without realising that you are 'tweaking' with the frame - I know this does not affect the original frame code, but it's generally not what you would want.
When working with the frame you are still exposed to its sub-components for visual editing, even when that frame is years old and should not be touched.
So I got to thinking....
Is there a way of 'grouping' components such that their positions are 'locked'? This would be useful for finished forms as well as frames. Often other developers return code to me where only the form bounds have changed and even they did not intend any change.
Is there any way of turning a frame and its components into a single Delphi component? If so, the frame internals would be completely hidden and its useability would increase further.
I'm interested in any thoughts...
Brian.
Registering your frames as a component solves both 1. and 2.:
But: there are a few catches (which can be solved, see article link), of which the most important is this one:
When you put components on your frame, and later drop that frame as a component on a Delphi form or frame, the components are visible in the Structure Pane.
The problem is that because they are visible in the structure pane, you can delete them, causing access violations.
The trick to solve this to not forget the 'sprig'.
I learned that valuable lesson from Ray Konopka during DelphiLive 2009.
Since the lesson is so valuable, I wrote a blog post on it that describes it in detail.
The essential portion is this little piece of code (more details in the blog post):
procedure RegisterFramesAsComponents(const Page: string; const FrameClasses: array of TFrameClass);
var
FrameClass: TFrameClass;
begin
for FrameClass in FrameClasses do
begin
RegisterComponents(Page, [FrameClass]);
RegisterSprigType(FrameClass, TComponentSprig);
end;
end;
Hope this helps.
--jeroen
Yes, just register them as components. :-)
Design your frame normally and after this register it. Also be sure to not have unwanted dependencies on different units since these are linked when your 'component' is used. Also you can add published
properties in order to use them in the Object Inspector later. See for example the following code generated by the IDE (see also my comments):
unit myUnit;
uses
...
type
TmyComp = class(TFrame) //set your frame name to be the name your component
ToolBar1: TToolBar; //different components added in the form designer
aliMain: TActionList;
...
published //this section is added by hand
property DataSource: TDataSource read FDataSource write SetDataSource; //some published properties added just for exemplification
property DefFields: string read FDefFields write SetDefFields;
...
end;
procedure Register; //added by hand
implementation
{$R *.DFM}
procedure Register;
begin
RegisterComponents('MyFrames', [TmyComp]); //register the frame in the desired component category
end;
Compile the above in a package of your choice, install it and check you component palette. :-)
HTH
I'm almost always creating frame instances in code. This is easy and worked well for me so far.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With