Abrir formulário utilizando TFormClass
Como faço para abrir um form MDI utilizando apenas o TFormClass?
Mrmarcelojr
Curtidas 0
Respostas
Mrmarcelojr
02/05/2006
[b:714f812712]up[/b:714f812712]
Gente, eu preciso muito desta solução....urgente mesmo......
Gente, eu preciso muito desta solução....urgente mesmo......
GOSTEI 0
Massuda
02/05/2006
Já experimentou [url=http://forum.clubedelphi.net/search.php]pesquisar[/url] o fórum por TFormClass?
GOSTEI 0
Mrmarcelojr
02/05/2006
Já experimentou pesquisar o fórum por TFormClass?
Jah....mas o que eu quero esta dificil de achar. Bem, meu problema é o seguinte, eu tenho uma função pra criar forms MDI em runtime (procedure CriaForm(FormClass:TFormClass;var Form);). Bem, essa rotina funciona perfeitamente, mas surgiu uma situação aqui. Eu não posso chamar essa função diretamente, intaum eu guardo o FormClass em uma variável para depois coloca-la no parametro correspondente no método CriaForm. Até ai beleza, mas como eu faço para armazear o var Form, pois ele não tem tipo nenhum, é apenas uma variável, por isso eu achei que seria mais fácil se eu cria-se o form apenas com o FormClass, mas se existir uma forma de eu armazenar o valor do var Form, será mais util.
ps.:Eu jah tentei usar uma variavel do tipo Variant pra armazenar, mas sem sucesso.
GOSTEI 0
Bruno77
02/05/2006
ai beleza!!
eu consigo assim
onde [b:d7321de062]form[/b:d7321de062] sera sua variavel passada em var form, deste forma a variavel ira armazenar a referencia do seu form.
eu consigo assim
Tform(form) := TFormClass.Create(nil);
onde [b:d7321de062]form[/b:d7321de062] sera sua variavel passada em var form, deste forma a variavel ira armazenar a referencia do seu form.
GOSTEI 0
Mrmarcelojr
02/05/2006
ai beleza!!
eu consigo assim
Código:
Tform(form) := TFormClass.Create(nil);
onde form sera sua variavel passada em var form, deste forma a variavel ira armazenar a referencia do seu form.
Mas esta variavel [b:621e989284]form[/b:621e989284] é de que tipo?
GOSTEI 0
Massuda
02/05/2006
Não tenho idéia de como você implementou, mas não poderia usar uma função ao invés de uma procedure......isso elimina o problema de ter que usar um parâmetro sem tipo (que é o caso da sua procedure) bem como evita ter que fazer typecasts ao chamar a procedure (caso você usasse parametros com tipo).
function CriarFormPelaClasse(const AClasse: TFormClass): TForm; begin Result := AClasse.Create(Application); end;
GOSTEI 0
Mrmarcelojr
02/05/2006
Bem, vou tentar explicar minha situação, quem sabe aparece uma luz e eu mude minha ideia.
Bem, eu quero criar uma tela da vizualização, essa mesma tela vai servir para qualquer tipo de cadastro, por exemplo, quando eu chamo o formulario de clientes, antes de abrir o frmClientes, eu abro essa tela consulta para mostrar os clientes. Nessa tela tenho botões de editar, novo, vizualizar. Ao clicar por exemlpo em novo, eu abro a tela de cliente chamando a função [b:ccafff62b6]CriaForm(TfrmCliente, frmCliente)[/b:ccafff62b6] (do metodo [b:ccafff62b6]CriaForm(FormClas:TFormClass;var Form)[/b:ccafff62b6]. Se eu colocar estes valores em tempo de projeto, a tela funciona, mas quero preencher estes valores em tempo de execução, pois esta tela de consulta serve para qualquer outra tela da cadastro. Na minha frmConsulta eu tenho uma variavel publica do tipo TFormClass para ser usada na CriaForm, mas e quanto ao var Form? É ai q estou perdido.
Soh para complicar um pouco, eu criei um outro metodo para chamar essa minha tela de consulta. TelaConsulta(CDS:TClientDataSet;[b:ccafff62b6]FormClass:TFormClass[/b:ccafff62b6]);. Reparem na FormClass, com este parametro eu preencho a variavel publica FormClass da frmConsulta, que mais tarde será usada para chamar o CriaForm, e o problema fica por conta do [b:ccafff62b6]var Form[/b:ccafff62b6] da CriaForm.
Ufa!!!.....acho que até eu fiquei meio perdido agora, mas tentei me explicar, pois o que estou querendo naum só simplesmente criar um form MDI, é algo um pouco mais ´sombriu´..... :lol:
Grato.
Bem, eu quero criar uma tela da vizualização, essa mesma tela vai servir para qualquer tipo de cadastro, por exemplo, quando eu chamo o formulario de clientes, antes de abrir o frmClientes, eu abro essa tela consulta para mostrar os clientes. Nessa tela tenho botões de editar, novo, vizualizar. Ao clicar por exemlpo em novo, eu abro a tela de cliente chamando a função [b:ccafff62b6]CriaForm(TfrmCliente, frmCliente)[/b:ccafff62b6] (do metodo [b:ccafff62b6]CriaForm(FormClas:TFormClass;var Form)[/b:ccafff62b6]. Se eu colocar estes valores em tempo de projeto, a tela funciona, mas quero preencher estes valores em tempo de execução, pois esta tela de consulta serve para qualquer outra tela da cadastro. Na minha frmConsulta eu tenho uma variavel publica do tipo TFormClass para ser usada na CriaForm, mas e quanto ao var Form? É ai q estou perdido.
Soh para complicar um pouco, eu criei um outro metodo para chamar essa minha tela de consulta. TelaConsulta(CDS:TClientDataSet;[b:ccafff62b6]FormClass:TFormClass[/b:ccafff62b6]);. Reparem na FormClass, com este parametro eu preencho a variavel publica FormClass da frmConsulta, que mais tarde será usada para chamar o CriaForm, e o problema fica por conta do [b:ccafff62b6]var Form[/b:ccafff62b6] da CriaForm.
Ufa!!!.....acho que até eu fiquei meio perdido agora, mas tentei me explicar, pois o que estou querendo naum só simplesmente criar um form MDI, é algo um pouco mais ´sombriu´..... :lol:
Grato.
GOSTEI 0
Mrmarcelojr
02/05/2006
Não tenho idéia de como você implementou, mas não poderia usar uma função ao invés de uma procedure......isso elimina o problema de ter que usar um parâmetro sem tipo (que é o caso da sua procedure) bem como evita ter que fazer typecasts ao chamar a procedure (caso você usasse parametros com tipo).
function CriarFormPelaClasse(const AClasse: TFormClass): TForm; begin Result := AClasse.Create(Application); end;
Isso vai me retornar um TForm, e o que eu faço com esse TForm (sem brincadeirinhas maliciosas :lol: ). Poderia me dar alguns exemplos de utilização dessa função?
GOSTEI 0
Massuda
02/05/2006
...Poderia me dar alguns exemplos de utilização dessa função?
Hoje você faz assim...CriaForm(TfrmCliente, frmCliente);
frmCliente := CriarFormPelaClasse(TfrmCliente);
Desculpe, mas não entendi o que você escreveu sobre tela de visualização.
GOSTEI 0
Mrmarcelojr
02/05/2006
eu não posso usar [b:158f369ddd]TForm:=AClasse.Create(Application);[/b:158f369ddd] pois o formulário ainda não foi criado, e o melhor método q vi ateh agora para se trabalhar com MDI é CriaForm(FormClass:TFormClass;var Form); pois assim ele cria o formulario numa boa e posso estar me referenciando ao formulario criado em qualquer parte do sistema(desde que ele já tenha cido criado).
..Apenas cria o form.
Bem, resumidamente, o q quero fazer é armazenar os valores de FormClass e var Form. O FormClass é fácil, soh estou tendo problemas com o var Form, pois não sei como declarar a variável.
[b:158f369ddd]Eu não posso chamar meu form diretamente, pois eu vou chamar ele depois, e conforme os valores que tiverem nas variáveis.....[/b:158f369ddd]
...mas, como já escrevi antes, eu não tenho idéia se sua CriaForm apenas cria o form ou faz mais alguma coisa...
..Apenas cria o form.
Bem, resumidamente, o q quero fazer é armazenar os valores de FormClass e var Form. O FormClass é fácil, soh estou tendo problemas com o var Form, pois não sei como declarar a variável.
[b:158f369ddd]Eu não posso chamar meu form diretamente, pois eu vou chamar ele depois, e conforme os valores que tiverem nas variáveis.....[/b:158f369ddd]
GOSTEI 0
Massuda
02/05/2006
eu não posso usar ... pois o formulário ainda não foi criado...
Não entendi... nestas linhas de código...function CriarFormPelaClasse(const AClasse: TFormClass): TForm; begin Result := AClasse.Create(Application); end; ..... frmCliente := CriarFormPelaClasse(TfrmCliente);
GOSTEI 0
Mrmarcelojr
02/05/2006
...o que pode dar errado nesse código se o form ainda não foi criado?
O problema é que não posso usar o frmCliente:=algumacoisa pq frmCliente não existe.....mas tudo bem, jah discutimos esta arquitetura que eu estava testando, mas decidimos mudar. Então agradeço o esforço de todos, e assim que eu estiver algum tempo livre, estarei estudando o caso e disponibilizando aqui no forum.
Muitissimo agradecido.
GOSTEI 0
Massuda
02/05/2006
...não posso usar o frmCliente:=algumacoisa pq frmCliente não existe...
Como não existe? Não existir é diferente de não ter valor. Se não existir, nem compila, mas se não tiver valor, bem... a finalidade dessa CriaForm é atribuir um valor a essa frmCliente.GOSTEI 0
Vitor Rubio
02/05/2006
...não posso usar o frmCliente:=algumacoisa pq frmCliente não existe...
Cara, veja bem, você está com dificuldades nos conceitos de Orientação a objetos.
Quando você tem uma variavel do tipo Tform, ou do tipo de uma descendente qualquer de tform (toda form criada por você é uma descendente da form basica Tform) vc tem apenas um ponteiro, que pode apontar para qualquer objeto do tipo tform instanciado (criado com o create) na memoria.
o codigo abaixo vai funcionar legal, porque ele vai passar a como parametro uma variavel ou objeto do tipo classe, ou seja, referencia uma classe. Essa classe pode ser qualquer classe de suas forms, desde que estejam no seu uses e que vc tenha acesso a elas.
essa função simplesmente faz o mesmo que a procedure, com a diferença de que a var da form não precisa ser passada como parametro, mas recebe o resultado da função.
ela simplesmente faz:
suaVariavelForm := criaform(ClasseQueTemQueSerCriada);
depois diso vc pode fazer suaVariavelForm.showmodal;
function CriarFormPelaClasse(const AClasse: TFormClass): TForm; begin //aclasse é um tipo de classe de form criado por vc, o T<qualquercoisa> Result := AClasse.Create(Application); //result vai receber um ponteiro para um objeto do tipo dessa classe instanciado na memoria end; //que sera passado para sua variavel frmCliente := CriarFormPelaClasse(TfrmCliente);
procure na ferramenta de busca pelo meu nome, deve ter uns dois tópicos falando sobre o assunto, onde eu não sabia nada e os colegas deram uma força tremenda.
isso consequentemente vai te levar a pesquisar um outro tópico muito interessante, o dos factory methods, procure por isso. Espero ter ajudado ^^
GOSTEI 0
Mrmarcelojr
02/05/2006
Quando eu falei q frmCliente não existe, eu me referi q ele ainda não foi criado. E quanto á finalidade do CriaForm eu sei, e este era o grande problema, pois eu não poedria chamar diretamente esse metodo. Na verdade é q ninguem intendeu o q eu gostaria de fazer, mas tudo bem, na verdade até eu estava ficando meio perdido jah, por isso resolvemos mudar de estratégia.
Muito grato a todos.
Muito grato a todos.
GOSTEI 0
Vitor Rubio
02/05/2006
sim, eu sei que ele não esta criado, não é esse o objetivo da função criaform? cria-lo para depois usá-lo?
vc pode chamar esse metodo sim, contanto que referencie a alguma propriedade da form depois de cria-la. Até com a sua procedure anterior daria certo.
eu entendi mais ou menos o que vc quer fazer até porque já precisei criar coisa parecida, por exemplo, usar factory methods, criar uma form pela classe, apenas pelo NOME da classe como string, apenas pelo NOME da form, com string tambem, isso tudo sem nem precisar ter a unidade da form no seu uses.
tambem já fiz uns esquemas legais com forms mdi child onde, quando vc as fechava, elas realmente fechavam e eram destruidas, e quando vc minimizava, ao invez de ir lá pra baixo, ela sumia e criava um botão numa toolbar que ao ser clicado, desaparecia e voltava a mostrar a form minimizada. Isso mesclado ao esquema de criar a form certa dependendo da situação dá bastante flexibilidade.
por exemplo, vc pode gravar os nomes das forms numa tabela de relatorios do seu bd, e dependendo do ´nome´ do relatorio que o usuario for clicar, cria e mostra a form correspondente.
vc pode chamar esse metodo sim, contanto que referencie a alguma propriedade da form depois de cria-la. Até com a sua procedure anterior daria certo.
eu entendi mais ou menos o que vc quer fazer até porque já precisei criar coisa parecida, por exemplo, usar factory methods, criar uma form pela classe, apenas pelo NOME da classe como string, apenas pelo NOME da form, com string tambem, isso tudo sem nem precisar ter a unidade da form no seu uses.
tambem já fiz uns esquemas legais com forms mdi child onde, quando vc as fechava, elas realmente fechavam e eram destruidas, e quando vc minimizava, ao invez de ir lá pra baixo, ela sumia e criava um botão numa toolbar que ao ser clicado, desaparecia e voltava a mostrar a form minimizada. Isso mesclado ao esquema de criar a form certa dependendo da situação dá bastante flexibilidade.
por exemplo, vc pode gravar os nomes das forms numa tabela de relatorios do seu bd, e dependendo do ´nome´ do relatorio que o usuario for clicar, cria e mostra a form correspondente.
GOSTEI 0