LMD DesignPack Guide


Designable Surface


The designable surface, where components can be laid out in design-time, is provided by a Root control which is to be referenced by the Root property of the Design Module component.

 

The Root control that must be a descendant of TWinControl. Two different cases are to be distinguished:

 

The root is a TCustomForm descendant;

Otherwise.

 

The rules which are to be obeyed in these cases while setting up the design environment, are presented in the table below.

 

Rule

Form-based Root

Non-form Root

Creation of the Root

Can be created in usual way as a common Delphi form

The descendant of TWinControl must be used. Actually, you can use standard components, like TPanel for the root, but such components do not implement all the logic required to be used as a root. So, it is advisable to declare a descendant of some appropriate VCL control, for example TPanel, and add this logic by overriding its Notification and GetChildren methods as shown below

Owner of the Root

Can be any valid component, or can be set to nil

Must be set to nil. This implies that you should create an instance of the root control dynamically in the code, because Delphi form designer always set the owner (to parent form).

Parent of the Root

Must not be assigned to any control. If you want to place the form inside some other window you should use ParentWindow property instead

Must not be assigned to any control while designing. When designer will be activated, the root control will automatically appears inside TLMDDesignPanel.

DesignPanel property of the TLMDDesigner

Is not mandatory to be assigned

Should be set to a TLMDDesignPanel control which will be used together with the designer. Internally TLMDDesignPanel contains a TCustomForm instance, in which the custom Root is automatically placed when designer is activated.

 

Creating a custom Root control

 

Logic required for correct Root control behavior is already implemented in Delphi forms, because they are used in Delphi designer, but it is not implemented in other standard VCL controls. So to create a custom Root control, the following steps are to be performed:

 

1.A control should be created as a descendant of TWinControl

2.Its Notification method is to be overridden in the following way:

 

procedure TMyRoot.Notification(AComponent: TComponent;
  Operation: TOperation);
var
  LForm: TCustomForm;
begin
  inherited;
  LForm := GetParentForm(Self);
  if (LForm <> nil) and (LForm.Designer <> nil) then
    LForm.Designer.Notification(AComponent, Operation);
end;

 

3.Its GetChildren method is to be overridden in the following way:

 

procedure TMyRoot.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
  I: Integer;
  OwnedComponent: TComponent;
begin
  inherited GetChildren(Proc, Root);
  if Root = Self then
    for I := 0 to ComponentCount - 1 do
    begin
      OwnedComponent := Components[I];
      if not OwnedComponent.HasParent then Proc(OwnedComponent);
    end;
end;

 

Components on the Root's designable surface

 

When the root is designed, various components can be placed on it using designer or manually in code. If you add some components manually in code you should specify the root as an owner in component constructor call. Only components that are children of the root can be touched by designer or saved/loaded with the root.

 

Note that some VCL controls can be complex and actually contains more then one instance of TControl descendants. For example, TLabeledEdit actually combines two controls – TLabel and TEdit descendants. But, only main control (s) is design-aware.  So, you, for example, will not be able to select edit label by designer.

 

Root with frames

 

Special rules exists for frames on the root and its children. See Working With Frames topic to learn how to design roots with frames.