如何动态创建表单

tez616oj  于 2022-10-16  发布在  其他
关注(0)|答案(1)|浏览(223)

我有一个Delphi 10.4应用程序,其中有20多个动态创建的表单。有一个创建表单的函数,如下所示:

Procedure SetForm(nForm : ShortInt);
Begin
Case nForm of
1: begin
              If not Assigned(Form1) then
                             Application.CreateForm(TForm1, Form1);
              Form1.Show;
              End;
2: begin
              If not Assigned(Form2) then
                             Application.CreateForm(TForm2, Form2);
              Form2.Show;
              End;
…
End;

问题是:我是否可以创建一个泛型函数来创建如下表单:

Procedure SetForm(nForm: ShortInt);
Begin
xForm : TForm;
xForm := arrayForm[nForm];    // Array containing all forms;
if not Assigned(xForm) then
              Application.CreateForm((some cast as TComponentClass), xForm);
xForm.Show;
end;

使问题复杂化的是,一些表单有一个在显示之前需要执行的函数,如下所示:

xForm.SetUser(nUser);

我尝试此操作只是为了创建和激活表单

...
type
  TFormInfo = record
    ClassType: TFormClass;
    Form: TForm;
  end;

procedure CreateForm(nForm: ShortInt);

var
  arrayForm: array[1..2] of TFormInfo = (
    (ClassType: TFormParam; Form : nil),
    (ClassType: TFormCliGrid; Form: nil)
  );

implementation

procedure CreateForm(nForm:ShortInt);
var xForm:TForm;
begin
    xForm := arrayForm[nForm].Form;
    if not Assigned(xForm) then
        begin
        xForm := arrayForm[nForm].ClassType.Create(Application);
        arrayForm[nForm].Form := xForm;
        end;
    xForm.Show;
end;

当我尝试在FormActivate上更改第二个窗体(FormCliGrid)中的组合框时

...
comboStatus.Items.BeginUpdate;

我得到了‘访问违规’

8wtpewkr

8wtpewkr1#

是的,您所要求的是非常可行的,使用带有TForm的虚拟构造函数的元类。
例如,您可以创建一个基类来访问所有表单的公共功能,例如:

type
  TMyBaseForm = class(TForm)
  public
    procedure SetUser(nUser: UserTypeHere); virtual; abstract;
  end;

  TMyBaseFormClass = class of TMyBaseForm;
type
  TForm1 = class(TMyBaseForm)
  public
    procedure SetUser(nUser: UserTypeHere); override;
  end;

  TForm2 = class(TMyBaseForm)
  public
    procedure SetUser(nUser: UserTypeHere); override;
  end;

  ...
type
  TFormInfo = record
    ClassType: TMyBaseFormClass;
    Form: TMyBaseForm;
  end;

var
  arrayForm: array[0..1] of TFormInfo = (
    (ClassType: TForm1; Form: nil),
    (ClassType: TForm2; Form: nil)
  );

Procedure SetForm(nForm: ShortInt);
Var
  xForm : TMyBaseForm;
Begin
  xForm := arrayForm[nForm].Form;
  if not Assigned(xForm) then
  begin
    xForm := arrayForm[nForm].ClassType.Create(Application);
    arrayForm[nForm].Form := xForm;
  end;
  xForm.SetUser(nUser);
  xForm.Show;
end;

或者,如果不能选择使用基类,则可以使用接口,例如:

type
  ISetUser = interface
    ['{6cc8854b-f945-4a0d-ab13-624a13eaade1}']
    procedure SetUser(nUser: UserTypeHere);
  end;
type
  TForm1 = class(TForm, ISetUser)
  public
    procedure SetUser(nUser: UserTypeHere);
  end;

  TForm2 = class(TForm, ISetUser)
  public
    procedure SetUser(nUser: UserTypeHere);
  end;

  ...
type
  TFormInfo = record
    ClassType: TFormClass;
    Form: TForm;
  end;

var
  arrayForm: array[0..1] of TFormInfo = (
    (ClassType: TForm1; Form: nil),
    (ClassType: TForm2; Form: nil)
  );

Procedure SetForm(nForm: ShortInt);
Var
  xForm : TForm;
  Intf: ISetUser;
Begin
  xForm := arrayForm[nForm].Form;
  if not Assigned(xForm) then
  begin
    xForm := arrayForm[nForm].ClassType.Create(Application);
    arrayForm[nForm].Form := xForm;
  end;
  if Supports(xForm, ISetUser, Intf) then
    Intf.SetUser(nUser);
  xForm.Show;
end;

相关问题