如何在我的项目中创建每个表单的实例?

How to create an instance of every form in my project?

我已将一个应用程序从 ADO 移植到 FireDAC,在源代码上应用多个 RegExp 替换,将 ADOQuery、ADOTables、ADOCommands、ADOStoredProcs 等转换为相应的 FireDAC 组件。

它运行良好,但是现在 运行 由于持久字段的类型与预期类型不同(当持久字段是已创建)。

我正在尝试列出这些错误,创建我所有表单的实例并使用持久字段打开它们的数据集,并记录错误。我可以从项目源代码中获取表单列表,但是当我尝试使用 FindClass 创建每个表单时,我收到一条错误消息,提示未找到 class。

是否有任何其他方法可以从其 class 名称创建 Form/DataModule?

这是我当前的代码:

class procedure TfrmCheckFormularis.CheckDatasets(ProjecteFile: string);
var frmCheckFormularis: TfrmCheckFormularis;
    Projecte: string;
    rm: TMatch;
    cc: TComponentClass; 
    c: TComponent;
    i: integer;
    Dataset: TFDQuery;
begin
  Projecte := TFile.ReadAllText(ProjecteFile);
  frmCheckFormularis := TfrmCheckFormularis.Create(Application);
  try
    with frmCheckFormularis do begin
      Show;
      qryForms.CreateDataSet;
      qryErrors.CreateDataSet;
      // I get a list of all the forms and datamodules on my project
      for rm in TRegEx.Matches(Projecte, '^(?:.* in '')(?<File>.*)(?:'' {)(?<Class>.*)(?:},)', [roMultiline]) do begin
        qryForms.AppendRecord([rm.Groups['File'].Value, rm.Groups['Class'].Value]);
      end;

      // Check every form and datamodule
      qryForms.First;
      while not qryForms.Eof do begin
        cc := TComponentClass(FindClass(qryFormsClass.Value));
        c := cc.Create(frmCheckFormularis);
        try
          for i := 0 to c.ComponentCount - 1 do begin
            if c.Components[i] is TFDQuery then begin
              Dataset := c.Components[i] as TFDQuery;
              // When the Dataset has persistent fields, I open it to check if the persistent fields are correct
              if Dataset.FieldDefs.Count > 1 then begin
                try
                  Dataset.Open;
                except
                  on E: Exception do qryErrors.AppendRecord([c.Name, Dataset.Name, E.Message]);
                end;
              end;
            end;
          end;
        finally
          c.Free;
        end;
        qryForms.Next;
      end;
    end;
  finally
    frmCheckFormularis.Free;
  end;
end;

谢谢。

使用 Delphi 中的“新”RTTI 非常简单。以下代码将(希望*)为您的应用程序中的每个表单创建一个实例:

procedure TForm1.Button1Click(Sender: TObject);
var
  Context: TRttiContext;
  &Type: TRttiType;
  InstanceType: TRttiInstanceType;
begin
  Context := TRttiContext.Create;
  for &Type in Context.GetTypes do
  begin
    if (&Type.TypeKind = tkClass) and &Type.IsInstance then
    begin
      InstanceType := TRttiInstanceType(&Type);
      if InstanceType.MetaclassType.InheritsFrom(TForm) and (InstanceType.MetaclassType <> TForm) then
        TFormClass(InstanceType.MetaclassType).Create(Application){.Show}; // optionally show it
    end;
  end;
end;

* 从技术上讲,它将为 TForm 的每个适当后代 class 创建一个实例。