TComponentClass

Delphi

18/05/2005

Como chego no TComponentClass de um Formulario?
Desde já muito obrigado pela atenção.


Davicarrano

Davicarrano

Curtidas 0

Respostas

Davicarrano

Davicarrano

18/05/2005

Meu Formulario de clientes esta no Available Forms
eu tenho uma variavel com o nome dele
eu quero chamar ele no programa
entao eu tenho q usar a função Application.CreateForm
so que o 1º parametro é do tipo TComponentClass
entao eu tenho q achar o TComponentClass do formulario
eu fiz assim

NomeForm:=´form_Clientes´
Application.CreateForm(FindComponent(NomeForm),NomeForm);

mas ai da erro de tipos incompativeis TComponentClass e TComponent


GOSTEI 0
Marioguedes

Marioguedes

18/05/2005

O primeiro parâmetro é justamente a classe a qual o form em questão pertence.

TComponentClass não é uma propriedade do formulário e sim uma coisa chamada ´Referencia de Classe´. Isso possibilta fazer rotinas genéricas de instanciação de classes sem que necessariamente se conheça a classe que será usada, como é o caso de CreateForm.


GOSTEI 0
Massuda

Massuda

18/05/2005

...tenho q achar o TComponentClass do formulario ... mas ai da erro de tipos incompativeis TComponentClass e TComponent
Para obter informações sobre a classe de qualquer objeto, faça
var
  Componente: TComponent;
...
  Componente := FindComponent(´...NomeDoComponente...´);

  // nome da classe: Componente.ClassName
  // referência da classe: Componente.ClassType
No seu caso, poderia escrever assim
Application.CreateForm(FindComponent(NomeForm).ClassType, NomeForm); 



GOSTEI 0
Davicarrano

Davicarrano

18/05/2005

Massuda, eu testei o codigo que voce me recomendou e ainda deu erro de tipos incompativeis TComponentClass e TClass....


GOSTEI 0
Massuda

Massuda

18/05/2005

...deu erro de tipos incompativeis TComponentClass e TClass....
Desculpe... não havia testado isso antes. Nesse caso você pode fazer o typecast sem problemas...
Application.CreateForm(TComponentClass(FindComponent(NomeForm).ClassType), NomeForm);
Apenas não esqueça que o form de nome NomeForm precisa já ter sido criado ou você terá um erro de Access Violation ao executar o código.


GOSTEI 0
Davicarrano

Davicarrano

18/05/2005

Galera valeu pela ajuda
com a ajuda de vcs deu pra elaborar um esquema q funciona

esse codigo
Application.CreateForm(TComponentClass(FindClass(´T´+NomeForm)), NomeForm);

para criar o form e realmente so funciona se registrar a classe

initialization
RegisterClass(TfrmClientes);

no form frmClientes...
valeu galera...


GOSTEI 0
Marco Salles

Marco Salles

18/05/2005

:arrow: Amigo [b:ba530d1bf3]davicarrano[/b:ba530d1bf3] , tenho acompanhado de perto seus ultimos dois tópicos...

No primeiro tópico
http://forum.devmedia.com.br/viewtopic.php?t=63052&sid=a032bccda9d42905441bd9fa3ea27732

Citação do tópico
Só que eu criei uma função pra poder criar os formularios e eu passo pra essa função apenas o nome do formulario como parametro. Entao eu quero criar um formulário a partir de uma String que contém o nome dele. Como ficaria o Codigo pra isso.....



Neste Ultimo , voce chegou a uma conclusão:
Galera valeu pela ajuda com a ajuda de vcs deu pra elaborar um esquema q funciona esse codigo Application.CreateForm(TComponentClass(FindClass(´T´+NomeForm)), NomeForm);


[b:ba530d1bf3]O Problema que o segundo paramentro Deste Método , no meu entendimento , não é o Nome do Form [/b:ba530d1bf3].... :arrow: Fica então , um código , sem utilidade :cry: :cry: :cry:

Porque tanto faz Escrever

Application.CreateForm(TComponentClass(FindClass(´T´+frmClientes)), frmClientes); [/quote]

Ou

Application.CreateForm(TfrmClientes,frmClientes); 


Não sei se estou conseguindo atingir o[color=darkred:ba530d1bf3][b:ba530d1bf3] Ponto X[/b:ba530d1bf3][/color:ba530d1bf3] Da questão

Eu acho que seria maravilhoso , colocar tambem o segundo parametro No [color=darkred:ba530d1bf3][b:ba530d1bf3]Formato String [/b:ba530d1bf3][/color:ba530d1bf3], como voce consegui , fazer com o Primeiro

[b:ba530d1bf3]E Este que é o Ponto[/b:ba530d1bf3]... :wink: Feito isto , ai sim , voce realmente atingiu seu objetivo[color=darkred:ba530d1bf3][/color:ba530d1bf3]


GOSTEI 0
Davicarrano

Davicarrano

18/05/2005

no codigo anterior NomeForm está armazenando a string ´frmClientes´...


GOSTEI 0
Marco Salles

Marco Salles

18/05/2005

Application.CreateForm(TComponentClass(FindClass(´T´+frmClientes)), frmClientes);



no codigo anterior NomeForm está armazenando a string ´frmClientes´...


No primeiro parametro , sim , mas no segundo paramentro desse jeito
acho que não da..

Por exemplo:

Suponha um Edit1.text:=frmClientes

a instrução

Application.CreateForm(TComponentClass(FindClass(´T´+Edit1.Text)), Edit1.Text);


:arrow:
[b:b28aac6cb3]Cho que nen compila[/b:b28aac6cb3] :cry: :cry: :cry: :cry:

Entendeu aonde estou querendo chegar :?: :?: :?:


GOSTEI 0
Davicarrano

Davicarrano

18/05/2005

eu testei este codigo e funcionou...


GOSTEI 0
Marco Salles

Marco Salles

18/05/2005

eu testei este codigo e funcionou...



Veja amigo... Eu tb Testei e olhe o erro que dá

[URL=http://www.imageshack.us][img:9ec021a496]http://img282.echo.cx/img282/6246/imagemerropassagemparametro4xn.jpg[/img:9ec021a496][/URL]

[b:9ec021a496]Erro que deveria da mesmo.. Não sei como voce consegui[/b:9ec021a496] :?: :?:


GOSTEI 0
Davicarrano

Davicarrano

18/05/2005

eu testei usando o edit1.text e nao deu certo mesmo... aconteceu este erro q vc escreveu.... mas substitua o edit1.text por uma variavel do tipo string contendo o nome do formulario que funciona... faça o teste...

por exemplo:

var nomeform:string;
...
nomeform:=´form2´;

Application.CreateForm(TComponentClass(FindClass(´T´+nomeform)), nomeform);


Esse tipo de discussao tira muitas duvidas da gente...
Obrigado Marco Salles, pela atenção ...


GOSTEI 0
Marco Salles

Marco Salles

18/05/2005

Amigo é meu interresse Também.. A Discussão acresecenta sempre algo Novo

Veja , coloquei a Variavel String . conforme voce sugeriu

Não da erro de compilação

Mas na hora de executar eu obtive erro

o Meu código Foi:

procedure TForm1.Button1Click(Sender: TObject);
var
 nomeform:string;
begin
 nomeform:=´form2´;
 Application.CreateForm(TComponentClass(FindClass(´T´+nomeform)), nomeform);
 Form2.show;
end;


Qual o código que voce esta usando para Apresentar o Formulário Supostamente Criado Por voce Usando a Variavel NomeForm :?: :?:

Coloque aqui , Por gentileza


GOSTEI 0
Davicarrano

Davicarrano

18/05/2005

procedure TForm1.Button1Click(Sender: TObject);
var
nomeform:string;
begin
nomeform:=´form2´;
Application.CreateForm(TComponentClass(FindClass(´T´+nomeform)), nomeform);
TForm(nomeform).show;
end;


e no fim do Form2 eu coloquei

initialization
RegisterClass(TForm2);


Lembrando que la em Project - Options, eu tirei o form 2 do Auto-Create e coloquei no Availables Forms
Olha se assim vai funcionar...


GOSTEI 0
Massuda

Massuda

18/05/2005

procedure TForm1.Button1Click(Sender: TObject); var nomeform:string; begin nomeform:=´form2´; Application.CreateForm(TComponentClass(FindClass(´T´+nomeform)), nomeform); TForm(nomeform).show; end;
Apesar desse código funcionar, do ponto de vista da linguagem, ele está incorreto (avise se quiser detalhes).

Postei no [url=http://forum.clubedelphi.net/viewtopic.php?t=63052]seu outro tópico[/url] uma função que criava um form a partir do nome da classe do form (é exatamente o que você está fazendo). Dê uma olhada e veja a diferença que existe entre elas.

Tem um problema com o seu código que é um memory leak que ocorre cada vez que o form é criado; a memória utilizada pela string que você passa como argumento é perdida quando o form é criado. Dependendo do uso da função no programa isso pode representar algumas dezenas de bytes por chamada que vão sendo consumidos da memória e nunca são retornados.


GOSTEI 0
Marco Salles

Marco Salles

18/05/2005

Tem um problema com o seu código que é um memory leak que ocorre cada vez que o form é criado; a memória utilizada pela string que você passa como argumento é perdida quando o form é criado.


:?: :?: :?: :?:
Mas o Delphi tem Garbage Collection Que Desaloca memoria do tipo Nativos(Como Strings e Inteiros)

:arrow: Mas quanto a :

Apesar desse código funcionar, do ponto de vista da linguagem, ele está incorreto (avise se quiser detalhes).


[b:9d247c150b]Por gentileza , coloquer os detalhes.. Eu to batendo nesta Tecla ha muito Tempo...[/b:9d247c150b] :lol:


GOSTEI 0
Massuda

Massuda

18/05/2005

[quote:63dd391436=´Marco Salles´]Mas o Delphi tem Garbage Collection Que Desaloca memoria do tipo Nativos(Como Strings e Inteiros)[/quote:63dd391436]O Delphi gerencia a memória utilizada por strings do tipo AnsiString (o padrão) usando um mecanismo de referência contada. Esse mecanismo funciona bem enquanto você tratar a variável como string, PString ou PChar. Se você fizer um typecast, por exemplo, para pointer, existe a possibilidade do Delphi perder o controle de referências e você terminar com um memory leak. No caso, TApplication.CreateForm irá tratar a string como um pointer, abrindo a possibilidade de perder o controle de referências.

[quote:63dd391436=´Marco Salles´]Por gentileza , coloquer os detalhes...[/quote:63dd391436]Este código...
procedure TForm1.Button1Click(Sender: TObject); 
var 
  nomeform:string; 
begin 
  nomeform:=´form2´; 
  Application.CreateForm(TComponentClass(FindClass(´T´+nomeform)), nomeform); 
  TForm(nomeform).show; 
end;
...funciona por dois motivos:[list:63dd391436][*:63dd391436]O método TApplication.CreateForm recebe como segundo parâmetro qualquer tipo de variável, porisso é possível passar uma string para receber o form criado pelo método.[*:63dd391436]Para mostrar o form, foi usado um typecast para TForm; quando o programador faz um typecast, ele está dizendo ao compilador para ignorar o fato de uma string não ser compatível com um objeto TForm e simplesmente tratar a string como um TForm.[/list:u:63dd391436]


GOSTEI 0
POSTAR