3
votes

I am trying to create composite component TTreePage (descendant form TCustomControl). It should contain 3 subcomponents: Treeview (TTreeview) align:=alLeft, Splitter (TSplitter) align:=alLeft and Container (TPanel) align:=alClient.

here is the contstructor:

constructor TTreePage.Create(AOwner: TComponent);
begin
  inherited;
  FTreeview := TTreeView.Create(self);
  FTreeview.SetSubComponent(True);
  InsertControl(FTreeview);
  FSplitter := TSplitter.Create(self);
  FSplitter.SetSubComponent(True);
  FSplitter.Width := 3;
  FSplitter.Color := clBlack;
  InsertControl(FSplitter);
  FContainer:= TPanel.Create(Self);
  FContainer.SetSubComponent(True);
  FContainer.BevelInner := bvNone;
  FContainer.BevelOuter := bvNone;
  FContainer.Color := clYellow;
  InsertControl(FContainer);
  RefreshLayout;  // this performs alignment of subcomponents
end;

here is create params procedure:

procedure TTreePage.CreateParams(var Params:TCreateParams);
begin
  inherited;
  Params.Style := Params.Style + WS_EX_CONTROLPARENT;
  ControlStyle := ControlStyle + [csAcceptsControls, csCaptureMouse, csOpaque];
end;

The whole component behaves as the one single block. I am unable to select any of subcomponents (TTreeview, TSplitter or TPanel) by mouse. Yes, I can edit their properties in Object Inspector, but I can not edit for example the width of TTreeview or drag TSplitter. The most important thing for me is to add nodes in TTreeview at design time, but I can not evoke Tree node editor for it.

What should I do?

Thanx

2

2 Answers

5
votes

Have the TTreePagecomponent handle the CM_DESIGNHITTEST message, which provides mouse coordinates for the clicking. If those coordinates are on a subcomponent that you want to click on, set the message's Result to 1, otherwise 0 (or call inherited). When 1 is returned, the mouse click gets passed on to the subcomponent for further processing. Since your entire client area is covered in subcomponents that you want to click on, just return 1 unconditionally, eg:

type
  TTreePage = class(TCustomControl)
  private
    ...
    procedure CMDesignHitTest(var Message: TCMDesignHitTest); message CM_DESIGNHITTEST;
    ...
  end;

procedure TTreePage.CMDesignHitTest(var Message: TCMDesignHitTest);
begin
  Message.Result := 1;
end; 

This is how some native VCL components, like TPageControl and TCoolBar, allow their sub-tabs/buttons/etc to be clickable at design-time.

3
votes

This is standard behaviour for subcomponents. You can see it with TLabeledEdit, where you cannot select the label with the mouse.

If you want separate selectable components use a TFrame.