我创建了自己的组件:TPage,其中包含子组件TPaper(TPanel)。 问题是,当我将TMemo或TButton等控件放在TPaper(几乎填满整个区域)时,控件根本不加载。见下面的例子
TPaper = class(TPanel)
protected
constructor Create(AOwner: TComponent);override;
destructor Destroy;override;
public
procedure Paint; override;
end;
TPage = class(TCustomControl)
private
FPaper:TPaper;
protected
procedure CreateParams(var Params:TCreateParams); override;
public
constructor Create(AOwner: TComponent);override;
destructor Destroy;override;
published
property Paper: TPaper read FPaper write FPaper;
end;
constructor TPage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
PaperOrientation:=poPortrait;
PaperSize:=psA4;
PaperBrush:=TBrush.Create;
PaperBrush.Color:=clWhite;
PDFDocument:=Nil;
FPaper:=TPaper.Create(Self);
FPaper.Parent:=Self;
FPaper.SetSubComponent(True);
end;
... Memo1在设计时是TPaper(TPanel)的主要产品,但之后 按“运行”它不存在。
procedure TForm1.btn1Click(Sender: TObject);
begin
if not Assigned(Memo1) then ShowMessage('I do not exist'); //Memo1 is nil
end;
你知道什么是错的吗?
非常感谢
P.S Delphi 7
当我将TMemo放入TPaper并保存单元(Unit1)时,在检查相关的dfm文件后,没有TMemo组件的痕迹。 (这就是为什么它无法加载到应用程序。)
答案 0 :(得分:2)
如果将Tpaper的所有者设置为Form不是一个选项,那么您仍然可以通过重写Getchildren和GetChildOwner方法并应用逻辑TCustomForm使用Delphi来流式传输子组件:
TPage = class
...
public
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
function GetChildOwner:TComponent; override;
end;
procedure TPage.GetChildren(Proc: TGetChildProc; Root: TComponent); // this is copied
var // from
I: Integer; // TCustomForm
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;
function TPage.GetChildOwner: TComponent;
begin
inherited;
Result:=Self;
end;
答案 1 :(得分:0)
问题是5年前,但是因为我遇到了同样的问题,在网络中找不到可行的解决方案,决定在经过大量测试后分享我发现的解决方案。
TClientPanel = class(TCustomControl)
private
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
public
constructor Create(AOwner: TComponent); override;
end;
TMainPanel = class(TCustomControl)
private
FClient: TClientPanel;
protected
function GetChildOwner: TComponent; override;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
procedure ReadState(Reader: TReader); override;
procedure CreateComponentEvent(Reader: TReader; ComponentClass: TComponentClass; var Component: TComponent);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
...
end;
constructor TClientPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible];
end;
procedure TClientPanel.WMNCHitTest(var Message: TWMNCHitTest);
begin
if not (csDesigning in ComponentState) then
Message.Result := HTTRANSPARENT
else
inherited;
end;
var
TClientPanel_Registered: Boolean = False;
constructor TMainPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FClient := TClientPanel.Create(Self);
FClient.Parent := Self;
FClient.Align := alClient;
Exclude(FComponentStyle, csInheritable);
if not TClientPanel_Registered then
begin
RegisterClasses([TClientPanel]);
TClientPanel_Registered := True;
end;
end;
destructor TMainPanel.Destroy;
begin
FClient.Free;
inherited Destroy;
end;
function TMainPanel.GetChildOwner: TComponent;
begin
Result := Self;
end;
procedure TMainPanel.GetChildren(Proc: TGetChildProc; Root: TComponent);
begin
Proc(TControl(FClient));
end;
procedure TMainPanel.CreateComponentEvent(Reader: TReader; ComponentClass: TComponentClass; var Component: TComponent);
begin
if ComponentClass.ClassName = 'TClientPanel' then Component := FClient;
end;
procedure TMainPanel.ReadState(Reader: TReader);
begin
Reader.OnCreateComponent := CreateComponentEvent;
inherited ReadState(Reader);
Reader.OnCreateComponent := nil;
end;
不是很专业,但我希望它会有所帮助:^)
P.S。刚做了一个快速测试(XE5),但基本上都有效。