Solução pra esse código ?

Delphi

15/07/2004

Olá Pessoal, Bom dia !

Peguei esse código aqui no forum de uma discursão sobre criação de formulários, baseando-se em uma string.

Alguém tem uma idéia mais simples de fazer isso ?

Obrigada !


[b:d1a2e63cf2]Código:[/b:d1a2e63cf2]

function ShowAForm(z: string): boolean;
var
i: integer;
strClass: String;
FormClass: TFormClass;
NewForm: TForm;
begin
result := false;
// verifica se o form ja foi criado e mostra ele
for i := 0 to Screen.FormCount - 1 do begin
if UpperCase(Screen.Forms[i].Name) = UpperCase(z) then begin
result := true;
Screen.Forms[i].Show;
exit;
end;
end;
// Se nao foi criado, cria e mostra!!!
if not result then begin
try
strClass := ´T´ + z;
FormClass := TFormClass(GetClass(strClass));
if (FormClass = nil) then begin // Nao existe form (nao deve ter sido registrado!)
exit;
end;
NewForm := FormClass.Create(Application);
NewForm.Name := z;
NewForm.Show;
Result := true;
except
Result := false;
end;
end;
end;


Renata Coimbra

Renata Coimbra

Curtidas 0

Respostas

Nildo

Nildo

15/07/2004

Esse código:

for i := 0 to Screen.FormCount - 1 do 
begin 
   if UpperCase(Screen.Forms[i].Name) = UpperCase(z) then 
   begin 
      result := true; 
      Screen.Forms[i].Show; 
      exit; 
   end; 
end; 

´
Pode ser trocado por esse:

if Application.FindComponent( z ) <> nil then
begin
   Result := True;
   TForm( Application.FindComponent( z ) ).Show;
end;



GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Obrigada Nildo !

Nildo estou tentando criar um formulário herdado de uma classe:

f_Cliente herda de Tf_Cadastro

Exemplo:
Tf_Cliente = class(Tf_Cadastro)


nessa rotina eu teria que alterar o que ?

o tipo da variavel FormClass: TFormClass para Tf_Cadastro ?


Muito obrigada pela atenção !

Renata Coimbra


GOSTEI 0
Persist

Persist

15/07/2004

Acho que neste código existem duas coisas distintas.
Ele está um formulário para cada classe.
Se na Screen não existir o formulário aberto, ele cria, mas com uma classe diferente.


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Obrigada persist pela atenção !

No meu caso todos os formulários vai ser herdeiro de Tf_Cadastro,

que são:

Tf_Cliente
Tf_Produtos
Tf_Vendas...
etc...

na funcção eu gostaria de passar o nome do formulário como uma string para ser instaciado.

será se tem como adaptar essa função pra isso ?


Obrigada !

[]´s

Renata


GOSTEI 0
Persist

Persist

15/07/2004

Eu não entendí bem.
Vc tem um menú flexível que é montado a partir de parâmetros externos e por isso vc não pode instanciar fixo nos onClicks do ítens de menú, pq vc não sabe qual formulário irá representar qual ítem.
É mais ou menos isso?


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Isso mesmo persist !

eu tenho todos os nomes de formulários em uma tabela que são:
Tf_Cliente
Tf_Produtos
Tf_Vendas...
etc..

daí eu tenho uma variavel dentro de um for que pega o nome dos formulários da tabela.

só não estou conseguindo associar a minha string ´Tf_formulario´ herdeiro da classe Tf_cadastro a rotina de instaciar formulários.

com um TForm funciona normal, o problema é que eu uso heranças de formulários, todos herda de Tf_Cadastro.

vc pode me ajudar ?

[]´s

Renata.


GOSTEI 0
Persist

Persist

15/07/2004

Bom, primeiro vc tem que registrar as classes.
RegisterClass(Tf_Cadastro);
RegisterClass(Tf_Cliente);
RegisterClass(Tf_Produtos);
RegisterClass(Tf_Vendas);

Daí vc pega a classe acenstral de acordo com a string que entra
var f:Tf_Cadastro;
begin
f := Tf_Cadastro(GetClass(´string´));
end;



GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Não deu certo persist !

olha todo o código:

procedure TPrograma.ClickMenu(Sender: TObject);
Var
f : Tf_Cadastro;
NewForm: TForm;
strClass: String;
begin
{Essa rotina procura um formularo do tipo Tf_Cadastro e retorna o mesmo}
f := TChamarProgramas.LocalizarFormularioCadastro(´StrForme´);
if f <> nil then
f.Show
else
begin
strClass := ´T´ + StrForm;
f := Tf_Cadastro(GetClass(strClass));
f := Tf_Cadastro.Create(Application );
f.Show;

end;

e na Inicialization estou registrando todas as classes,

RegisterClass([Tf_CLiente, TfProduto, etc...]);


o que estou fazendo de errado ?

a minha var strClass está mostrando o nome da classe certinho.


[]´s

Renata.


GOSTEI 0
Persist

Persist

15/07/2004

Se vc registra uma classe TF_CLIENTE por exemplo, a string da função GetClass tem que ser ´TF_CLIENTE´.
Vc está colocando ´T´ + StrForm, então StrForm deve conter ´F_CLIENTE´.
O que está em StrForm?


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

strForm é igual f_Cliente que eu pego de uma tabela.

T+strForm

strClass = Tf_Cliente

[]´s

Renata.


GOSTEI 0
Persist

Persist

15/07/2004

O que está dando errado então?


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Pois é persist !

ao invés de criar o Tf_Cliente está criando e abrindo o pai dele Tf_Cadastro.

estou ficando maluca com isso, heheh !

[]´s

Renata;


GOSTEI 0
Persist

Persist

15/07/2004

Entendí, é pq vc está instanciando o objeto TF_Cadastro e não seus descendentes.
Acho que vc terá que fazer um if para criar os descendentes.
São muitos formulários?


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Bastante !

todos os forms do sistema, uns 15 + ou -


GOSTEI 0
Persist

Persist

15/07/2004

Bom, faça 15 ifs então.


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

O persist, desculpa mais não entendir como usar um if nesse caso.

eu não sei qual vai ser o valor da variavel que traz o nome da classe,
se eu tenho 15 forms, a variavel vai ser dinamica dentro de um for

vc poderia me dar um exemplo ?

[]´s

Renata.


GOSTEI 0
Beppe

Beppe

15/07/2004

Vê aqui?
f := Tf_Cadastro(GetClass(strClass)); 
f := Tf_Cadastro.Create(Application );

Vc está chamando o Create na classe pai, é lógico que é a classse pai que surgirá! Os efeitos de GetClass nem são usados...

Declare Tf_CadastroClass, se já naum fez:
Tf_CadastroClass = class of Tf_Cadastro;

Assim vc cria o form:
f := Tf_CadastroClass(GetClass(strClass)).Create(Application);



GOSTEI 0
Persist

Persist

15/07/2004

Não vai adiantar o RegisterClass e GetClass.
var f:TF_Cadastro;
begin
if SameText(StrForm, ´F_Cliente´) then
  f := Tf_Cliente.Create(Application)
else
if SameText(StrForm, ´F_Produtos´) then
  f := Tf_Produtos.Create(Application)
else
if SameText(StrForm, ´F_Vendas´) then
  f := Tf_Vendas.Create(Application);
f.Show;
end;



GOSTEI 0
Persist

Persist

15/07/2004

Tf_CadastroClass = class of Tf_Cadastro


E se em determinada classe filha o constructor for overload e requerer mais de um parâmetro?


GOSTEI 0
Beppe

Beppe

15/07/2004

Este parametro poderia vir de qq outro lugar(use a imaginação).
Ou, num modelo OO, a classe pai deveria definir este construtor, e reimplementado nas classes necessárias.


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Bom dia pessoal !

Persist, muito obrigada pela sua atenção, vou testar os ifs que vc me passou.


Bipe, eu implementei o código que vc me passou, mais está dando um erro de violção, olha todo código:


unit dmClasses;

interface

uses
SysUtils, Classes, formPadrao, formCadastro, formMovimento;

type
Tdm_Classes = class(TDataModule)
private
{ Private declarations }
public
{ Public declarations }

end;

{Declaracao da classe}
Tf_CadastroClass = class of Tf_Cadastro;


TChamarProgramas = class
public
class function LocalizarFormularioCadastro( const s : ShortString ) :
end;

var
dm_Classes: Tdm_Classes;


implementation

{$R *.dfm}

procedure Tdm_Classes.ClickMenu(Sender: TObject);
Var
f : Tf_Cadastro;
strClass: String;
begin
strClass := ´T´ + formName;
{Localiza o form formName}
f := TChamarProgramas.LocalizarFormularioCadastro(formName);
if f <> nil then {se achou exibe}
f.Show
else
{o erro está nessa linha...}
f := Tf_CadastroClass(GetClass(strClass)).Create(Application);
end;
end.

Obrigada !

Renata.


GOSTEI 0
Beppe

Beppe

15/07/2004

Renata, GetClass deve estar retornando nil, o que significa que a string passada não representa uma class registrada. Use FindClass no lugar, então uma exceção será levantada(´Class xxx not found.´). O erro de violaão é no GetClass?

Mas é estranho, pq seus passos anteriores estão certos. A não ser que vc tenha modificado um trecho do seu código, para ocorrer este erro. Se quiser posso te mandar um demo demonstrando o código.

Isso funciona sem problemas para mim, após RegisterClass(TForm3):
TForm1Class(FindClass(´TForm3´)).Create(Application).Show;


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

Beppe, funcionou belezinha !

muito obrigada pela atenção

[]´s

Renata Coimbra


GOSTEI 0
Beppe

Beppe

15/07/2004

O que vc precisou arrumar?


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

oops ! Esquecir de falar, Era só as classes que não estavam sendo registradas !

[]´s

:oops:


GOSTEI 0
Beppe

Beppe

15/07/2004

hehe...são uns esquecimentos assim que atrapalham o nosso trabalho... :(

T+


GOSTEI 0
Renata Coimbra

Renata Coimbra

15/07/2004

é verdade !

eu estava esquecendo de colocar na Initialization do form. :D

Obrigada de novo pela atenção.

[]´s

Renata.


GOSTEI 0
POSTAR