3

我正在尝试创建复合组件 TTreePage(后代形式 TCustomControl)。它应该包含 3 个子组件:Treeview (TTreeview) align:=alLeft、Splitter (TSplitter) align:=alLeft 和 Container (TPanel) align:=alClient。

这是构造函数:

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;

这是创建参数过程:

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

整个组件表现为一个单独的块。我无法通过鼠标选择任何子组件(TTreeview、TSplitter 或 TPanel)。是的,我可以在 Object Inspector 中编辑它们的属性,但我不能编辑例如 TTreeview 的宽度或拖动 TSplitter。对我来说最重要的是在设计时在 TTreeview 中添加节点,但我无法为此调用 Tree 节点编辑器。

我应该怎么办?

谢谢

4

2 回答 2

5

TTreePage组件处理CM_DESIGNHITTEST消息,该消息为单击提供鼠标坐标。如果这些坐标位于您要单击的子组件上,请将消息的 Result 设置为 1,否则设置为 0(或调用inherited)。当返回 1 时,鼠标点击被传递到子组件以进行进一步处理。由于您的整个客户区域都包含在您想要单击的子组件中,因此只需无条件返回 1,例如:

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; 

这就是一些原生 VCL 组件(例如TPageControlTCoolBar)在设计时允许其子选项卡/按钮/等可点击的方式。

于 2013-07-10T19:35:46.417 回答
3

这是子组件的标准行为。您可以使用 TLabeledEdit 来查看它,其中无法用鼠标选择标签。

如果您想要单独的可选组件,请使用 TFrame。

于 2013-07-10T14:52:36.947 回答