动态创建组件和更改它的属性是可能的,因为ObjectPascal允许构造函数是虚的;
但要给动态他建的组件添加事件处理句柄的处理代码是非常困难的.
好象FastReport中有一个FsScript可实现完全的动态处理,即编译好程序后,你可以在运行程序后,输入脚本,由你的程序解释脚本并运行,也就是说,你可以在你的程序中动态创建一个按钮,并为该按钮添加事件处理程序,俄国人真是厉害.

解决方案 »

  1.   

    The following code defines a component class (TStreamable class) and a persistent class (TContainedClass) that is the type of a property on the component class. When a button is clicked, an instance of the component class is created, saved to a file, deleted, and then loaded from the file. By setting a breakpoint on the property setter of the TContainedClass SomeData property, you can watch how the streaming system sets property values when it reads them from a file.
    The following unit defines the classes to stream:unit StrmExmpl;
    {$R-,T-,H+,X+}
    interface
    uses Classes
    type
    TContainedClass = class(TPersistent)
    private:
      FSomeData: Integer;  procedure SetSomeData(Value: Integer);  public:    constructor Create; override;  // Only published properties
      // are automatically streamed.
      published:    property SomeData: Integer read FSomeData write SetSomeData;end;
    TStreamableClass = class(TComponent)
    private:
      FContainedClass: TContainedClass;
      public:    constructor Create(AOwner: TComponent); override;    destructor Destroy; override;  // Only published properties
      // are automatically streamed.
      published:    property ContainedClass: TContainedClass read FContainedClass write FContainedClass;end;implementationprocedure TContainedClass.SetSomeData(Value: Integer);
    begin
    { Place a breakpoint here and notice how the data is streamed back. }
      FSomeData := Value;
    end;
    constructor TContainedClass.Create;
    begin
      FSomeData := 42;
    end;
    constructor TStreamableClass.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FContainedClass = TContainedClass.Create;end;
    destructor TStreamableClass.Destroy;
    begin
      FContainedClass.Free;
    end;
    initialization
      RegisterClasses([TContainedClass, TStreamableClass]);
    finalization
    end.The following OnClick event handler should be added to a button on the application抯 main form. It causes the above classes to be streamed out and in. Note that you must add StrmExmpl to the uses clause of unit1.procedure TForm1.Button1Click(Sender: TObject);var
      AClassInstance: TStreamableClass;
    begin
      AClassInstance := TStreamableClass.Create(nil);
      WriteComponentResFile('C:\Test', AClassInstance);
      FreeAndNil(AClassInstance);  AClassInstance := ReadComponentResFile('C:\Test', nil) 
    as TStreamableClass;
      FreeAndNil(AClassInstance);
    end;
      

  2.   

    首先特别感谢 jjwwang(风归叶) ,终于看到具有可操作性的方案!小弟正在学习中,如果有问题还请再次赐教!同时也感谢其他 朋友的捧场!再次感谢。
      

  3.   

    至 jjwwang(风归叶) :
        您好,小弟研究了一下你的代码,是这样的,您是通过 WriteComponentResFile 把一个控件的信息写成资源文件,然后通过WriteComponentResFile 来加载这个控件的信息!但小弟有个问题还请指教,是这样的,有些控件在开发过程中已经建立,我想在运行期间动态的修个它的属性,怎么办呢?(不是运行期间创建)。能否留下您的其他联系方式??
      

  4.   

    其实我觉得你自己的方法也是很不错的,如果像MS最近的WPF里面的XAML靠拢,应该也可以实现的很好.