Como declarar o tipo: TForm no Delphi?

Gostaria de saber qual é o tipo TForm que posso declarar numa chamada de função?
Vi que ele é do tipo: TFormExemplo= class(TForm), só que se eu declarar assim, não funciona.
Como eu declararia isso num chamada de função?
Quero fazer assim porque preciso chamar vários forms, e iria economizar linhas só fazendo essa chamada de função:

procedure TfrmPrincipal.showForm(form: TForm; teform: ???);
begin
    form:= teform.Create(self);
    form.Parent:= pnPrincipal;
    form.Show;
    form.Align:= alClient;
end;

A chamada da função seria essa: showForm(frmCadastroDepartamento,TfrmCadastroDepartamento);
Desde já agradeço.

Você pode usar TFormClass como parâmetro. Para chamar os métodos de criação e alterar valores, pode ser necessário fazer um cast para TForm. Algo como:

procedure TfrmPrincipal.showForm(form: TForm; AForm: TFormClass);
  TForm(AForm) := AForm.Create(self);
  TForm(AForm).Parent := pnPrincipal;
  // etc
end;

Não tenho como testar no momento, então ajustes podem ser necessários. Veja a referência em:

Abraço.

1 curtida

Muito obrigada!
Era o que eu estava precisando, não sabia qual era o tipo a ser colocado, no caso TFormClass.
Não foi necessário colocar o cast.
Abraço, valeu! :slight_smile:

Fui testar melhor aqui, e o parâmetro não é passado para o frmCadastroDepartamento.
O frmCadastroDepartamento continua sendo nil. Achei que ao passar o parâmetro frmCadastroDepartamento , ele seria carregado dentro da função showForm, e não ficaria nil.
Quero dar um FreeAndnil() quando o panel receber outro form.
É como se eu tivesse criado um novo objeto do tipo frmCadastroDepartamento, ao invés de apenas passar os parâmetros e valores diretamente pra ele.
Sabe como resolver isso?

Fiz algo tipo assim:

procedure TfrmPrincipal.showForm(form: TFormClass);
begin
     closeActiveForm();
     TForm(form):= form.Create(Application);
     TForm(form).Parent:= pnPrincipal;
     TForm(form).Show;
     TForm(form).Align:= alClient;
     pnPrincipal.Caption:=copy(TForm(form).name,0,length(TForm(form).name)-2);

end;

procedure TfrmPrincipal.closeActiveForm();
begin
     if pnPrincipal.Caption = ‘frmCadastroDepartamento’ then
     FreeAndnil(frmCadastroDepartamento) else
     if pnPrincipal.Caption = ‘frmCadastroEmpregado’ then
          FreeandNil(frmCadastroEmpregado) else
     if pnPrincipal.Caption = ‘frmConsultaDepartamento’ then
          FreeandNil(frmConsultaDepartamento)else
     if pnPrincipal.Caption = ‘frmConsultaEmpregado’ then
          FreeandNil(frmConsultaEmpregado);
end;

Fiz uma gambiarra antes de chamar a função showForm, coloquei assim:
Desativei lá no código fonte do projeto e coloquei no onclick do botão pra chamar a função:
Application.CreateForm(TfrmCadastroDepartamento, frmCadastroDepartamento);
Depois, chamo o showForm(TfrmCadastroDepartamento);
Só assim o frmCadastroDepartamento por exemplo, não fica nil. Se eu só chamar o showForm, o frmCadastroDepartamento fica nil.

Existe alguma solução mais elegante?

Não está claro para mim qual problema você quer resolver. O que espera obter com esse conjunto de funções?

Desconfio que você está adicionando mais complexidade que o necessário, sem obter muito benefício. Ter a opção de determinar dinamicamente qual o form a ser criado não é tanta vantagem assim se você precisa dar tantas voltas para usar isso.

Se o que você quer é simplesmente criar o form e configurá-lo, acredito ser mais fácil passar o form já criado para a procedure, do que passar a classe dele e tentar criá-lo dentro dessa procedure. Se somente um form pode ser exibido (e o anterior deve ser fechado antes), você pode adicionar uma variável ao seu form principal (pnPrincipal, pelo que entendo) e verificar essa variável antes de configurar o novo form. Algo como:

procedure TfrmPrincipal.ShowForm(AForm: TForm);
begin
  // FormAtual é uma variável private do tipo TForm, em TfrmPrincipal
  if (FormAtual <> nil) then
  begin
    FormAtual.Close;
    FreeAndNil(FormAtual);
  end;

  AForm.Parent := Self;
  AForm.Align  := alClient;
  Self.Caption := copy(AForm.name, 0, length(AForm.name) -2); // muda o título do form principal
  AForm.Show;

  FormAtual := AForm;
end;

Exemplo de uso:

procedure TfrmPrincipal.Button1Click(Sender: TObject);
begin
  ShowForm(TfrmCadastroEmpregado.Create(Application));
end;

Abraço.

1 curtida

Obrigada. Eu estava tendo problemas com a passagem de parâmetros, e para poder liberar a memória. Estava percebendo que a memória estava começando a ficar cheia. Achei que fosse possível passar parâmetro do tipo TForm, e ele ficasse persistente, colocando um var na frente, mas não funcionou.
Assim: Procedure TfrmPrincipal.ShowForm(var AForm: TForm);