The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,224 other subscribers

Delphi – Frames as visual Components – don’t forget your Sprig!

Posted by jpluimers on 2009/07/16

I have been using Delphi Frames as visual components for quite some time now.
They make it really easy to use the Delphi IDE to visually design your component.
This makes the development process for creating visual components much easier and faster.

There are some things you need to watch when doing this, so I’ll devote a few blogs posts on this topic over the next couple of months.

A few of the things are:

  • 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 Visible property is ignored at design time.
  • You need to watch resizing.
  • Frames do not have OnCreate and OnDestroy events.
  • Error messages about a missing ClientHeight property.
  • You can still drop other components on your frame.
  • … probably some more that I forgot right now…

The first blog on this series is about the first issue:

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 bad thing about this is that you can now delete the components on the frame using the structure pane.
This leads to all sorts of problems (mostly access violations).

When I’m in component trouble, I usually ask my long time friend [Wayback/Archive] Ray Konopka who has been publishing and speaking about Delphi component creation a lot.
This time I asked him at the [Wayback] Delphi Live conference, so he invited me to his session about [Wayback] Creating Composite VCL Controls.
Since that didn’t clash with any of my [Wayback] scheduled talks, I already decided to go to his talk anyway, so I was anxious to see his solution.

Edit 20211220: Ray also explains the below in the thread [Wayback/Archive] Visual [Compound] Component Design with TFrame [Edit] – public.delphi.vcl.writing.

Back home, I found out he already wrote about this problem in a CodeGear Delphi forum posting earlier this year.
The trick is to call RegisterSprigType for your frame class, registering TComponentSprig.
A Sprig is what tells the Structure Pane how to behave: TComponentSprig makes it behave as it would do for normal components in stead of frames.
When you know it, it is dead simple.

A quick sample registering TMyFrameComponent is below.

Since both RegisterSprigType and TComponentSprig are in the TreeIntf unit, you need

  1. The TreeIntf unit in your uses list.
  2. The DesignIDE package in your required packages list
  3. Your Registration to be in a design-time package (which is should be anyway).

So here is the code, centralizing the logic in the RegisterFramesAsComponents method, which works analogous to the RegisterComponents method from the Classes unit:

{$I Defines.inc}

unit ComponentsRegistrationUnit;

interface

procedure Register;

implementation

uses
  Classes,
  TreeIntf,
  MyFrameComponentUnit;

type
  TFrameClass = class of TFrame;

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;

procedure Register;
begin
  RegisterFrameAsComponents('bo', TMyFrameComponent);
end;

end.

5 Responses to “Delphi – Frames as visual Components – don’t forget your Sprig!”

  1. […] […]

  2. Ken Knopfli said

    Wow, the code is in a TINY font in FireFox!

  3. Ahmet said

    Doesn’t that cause the frame to lose its some behaviours like redesignablety of subcomponents in it ?
    And is it possible to show additional properties of it on object inspector with that way ?
    (http://stackoverflow.com/questions/289672/showing-tframe-descendants-additional-properties-on-the-object-inspector)

    • jpluimers said

      That is indeed the whole point of making them components: they become fixed :-)

      For me, redesignability freedom you see as an advantage of frames, is a big disadvantage: it allows to break your app with ease.

      For instance, put an edit control on a frame, add that frame to a form, (save and) close the form, rename the edit on the frame then reload the form: boom!
      Or another one: drop an edit on the frame, drop the frame on a form, move the edit on that form, (save and) close the form, move the edit on the frame, reopen the form: now the edit on the frame and the form are out of sync.

      This gets worse when you are sharing a common set of frames within a project group containing multiple projects each having a truckload for forms.
      How do you keep that in sync with your frames when you have so much design freedom?

      Frames are great for adding new and shared functionality.
      But in my experience, an average developer spends about 80% of his time in maintaining applications.
      So I aim for maintainability: less degrees of freedom, which makes your 20% a bit more cumbersome and pays back in that 80% of your time.

      Thanks for your link to the RegisterCustomModule call, I didn’t know that, so I’ll make sure to investigate a bit into that, and I’ll try to get back on it in a future posting.
      For my reference a google search query to start investigating…

      –jeroen

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

 
%d bloggers like this: