2

私は現在、文字列フォーム名を使用してフォームを作成することについて混乱しています(delphiでその名前でクラスをインスタンス化する方法はありますか?)が、私のフォームには独自のコンストラクターcreateがあります。

//-BASE CLASS-//
TBaseForm = class(TForm)
  constructor Create(param1, param2: string); overload;
protected
  var1, var2: string;    
end;

constructor TBaseForm.Create(param1, param2: string);
begin
  inherited Create(Application);
  var1 := param1;
  var2 := param2;
end;

//-REAL CLASS-//
TMyForm = class(TBaseForm)
end;

//-CALLER-//
TCaller = class(TForm)
  procedure Btn1Click(Sender: TObject);
  procedure Btn2Click(Sender: TObject);
end;

uses UnitBaseForm, UnitMyForm;

procedure TCaller.Btn1Click(Sender: TObject);
begin
  TMyForm.Create('x', 'y');
end;

procedure TCaller.Btn1Click(Sender: TObject);
var PC: TPersistentClass;
    Form: TForm;
    FormBase: TBaseForm;
begin
  PC := GetClass('TMyForm');

  // This is OK, but I can't pass param1 & 2
  Form := TFormClass(PC).Create(Application);

  // This will not error while compiled, but it will generate access violation because I need to create MyForm not BaseForm.
  FormBase := TBaseForm(PC).Create('a', 'z');
end;

提供したコードに基づいて、文字列フォーム名を指定するだけで動的にカスタムのコンストラクターフォームを作成するにはどうすればよいですか?それとも本当に不可能ですか?(私はそれが不可能だと思い始めました)

4

1 に答える 1

2

データ型を定義してからclass of TBaseForm、結果をその型に型キャストする必要がありGetClass()ます。その後、コンストラクターを呼び出すことができます。また、コンストラクターを仮想として宣言して、派生クラスのコンストラクターを正しく呼び出すことができるようにする必要があります。

これを試して:

type
  TBaseForm = class(TForm)
  public
    constructor Create(param1, param2: string); virtual; overload;
  protected
    var1, var2: string;    
  end;

TBaseFormClass = class of TBaseForm;

procedure TCaller.Btn1Click(Sender: TObject);
var
  BF: TBaseFormClass;
  Form: TBaseForm;
begin
  BF := TBaseFormClass(GetClass('TMyForm'));
  Form := BF.Create('a', 'z');
end;
于 2012-10-25T08:59:10.133 に答える