为什么复合组件无法作为控件的父项? [英] Why the composite component fails to parent controls?

查看:90
本文介绍了为什么复合组件无法作为控件的父项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了自己的Component:TPage,其中包含子组件TPaper(TPanel)。
问题是,当我在TPaper上放置TMemo或TButton之类的控件(几乎填满整个区域)时,这些控件根本无法加载。参见下面的示例

I created my own Component : TPage , which Contains Subcomponent TPaper (TPanel). The problem is, that when I put controls such as TMemo or TButton on the TPaper (which fills up nearly whole area), the controls do not load at all. see example below

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)中作为父项,但是$ p $ b按下运行后,它不存在。

... Memo1 is parented in TPaper (TPanel) at design-time, but after pressing "Run" it does not exist.

procedure TForm1.btn1Click(Sender: TObject);
begin
if not Assigned(Memo1) then ShowMessage('I do not exist');   //Memo1 is nil
end;

您是否知道出了什么问题?

Have you any idea what's wrong?

非常感谢

PS Delphi 7

P.S Delphi 7

当我将TMemo放入TPaper并保存单元时(Unit1) ,检查了相关的dfm文件后,没有TMemo组件的痕迹。 (这就是为什么它无法加载到应用程序的原因。)

When I put TMemo inside TPaper and save the unit (Unit1), after inspection of associated dfm file, there is no trace of TMemo component. (Thats why it can not load to app.)

推荐答案

Serge是正确的。 Delphi仅流式处理它们所驻留的Form所拥有的组件。为了避免在读取表单文件期间发生EClassNotfound异常(您现在至少应该在dfm文件中看到一个Tpaper组件),您必须注册该类通过使用RegisterClass函数(以Class为单位)。

Serge is right. Delphi only streams components that are owned by the Form they reside in. In order to avoid the EClassNotfound Exception, which occurs during reading of the form file (You should now at least see a Tpaper component in your dfm file) you must register the class by using the RegisterClass function (in the unit Classes). A good place for this would be in the initialisation section of your unit.

如果不能将Tpaper的所有者设置为Form,那么仍然可以使用Delphi通过重写Getchildren和GetChildOwner方法并应用TCustomForm使用的逻辑来流传输子组件:

If setting the owner of Tpaper to a Form is not an option, then you can still get Delphi to stream your subcomponents by overriding the Getchildren and GetChildOwner methods and applying the logic TCustomForm uses:

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;

这篇关于为什么复合组件无法作为控件的父项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆