Problemas com CreateForm

Delphi

22/03/2006

Bem, eu fiz uma procedure publica para criação de forms.
Exemplo de um trecho do código


procedure ShowForm (FormT:TComponentClass;Form:TForm);
...
Application.CreateForm(FormT,Form);
...

Bem, o procedimento esta funcionando, mas estou tendo um problema em relação ao parâmetro FormT, que é do tipo TComponentClass, pois ao chamar o método: Ex.: ShowForm(TfrmCliente,frmCliente);, o parametro onde eu passeo o TfrmCliente me retorna como nil, o formulário ateh abre numa boa, soh q qdo eu preciso me referenciar a este formulário, eu não consigo.

Obs: Já fiz testes aplicando o CreateForm sem utilizar esta minha rotina e funcionou blz, bem como eu quero, porém eu preciso chamar o form por esta rotina.


Mrmarcelojr

Mrmarcelojr

Curtidas 0

Respostas

Martins

Martins

22/03/2006

procedure CForm(Frm: TFormClass; nFrm: TForm);
begin
  Application.CreateForm(Frm, nFrm);
  nFrm.ShowModal;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
   CForm(TForm2, Form2);
end;


Boa sorte :!: .


GOSTEI 0
Paullsoftware

Paullsoftware

22/03/2006

procedure CForm(Frm: TFormClass; nFrm: TForm);
begin
  Application.CreateForm(Frm, nFrm);
  nFrm.ShowModal;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
   CForm(TForm2, Form2);
end;
Boa sorte :!: .


Martins, não seria viável tirar o form da memória criando ele no try finally
procedure CForm(Frm: TFormClass; nFrm: TForm);
begin
  Try
  Application.CreateForm(Frm, nFrm);
  nFrm.ShowModal;
  Finally
  nForm.Release;
  nForm:=Nil;
  end;
end;
:?: :?: :?:


GOSTEI 0
Mrmarcelojr

Mrmarcelojr

22/03/2006

procedure CForm(Frm: TFormClass; nFrm: TForm);
begin
  Application.CreateForm(Frm, nFrm);
  nFrm.ShowModal;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
   CForm(TForm2, Form2);
end;
Boa sorte :!: .


eu já faço isso, mas eu naum consigo passar nenhum comando para o formulário criado com este metodo. Ah, esqueci de dizer, eu utilizo MDI.


GOSTEI 0
Paullsoftware

Paullsoftware

22/03/2006

[quote:c4ff1f8108=´Martins´]
procedure CForm(Frm: TFormClass; nFrm: TForm);
begin
  Application.CreateForm(Frm, nFrm);
  nFrm.ShowModal;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
   CForm(TForm2, Form2);
end;
Boa sorte :!: .


eu já faço isso, mas eu naum consigo passar nenhum comando para o formulário criado com este metodo. Ah, esqueci de dizer, eu utilizo MDI.[/quote:c4ff1f8108]

ae, se vc usa MID tente dessa maneira:
// Verifica se o form a ser criado já esta carregado
function FormExiste(aberto: Tform): Boolean;
var
I:Integer;
begin
    FormExiste := false;
    for I := 0 to Screen.FormCount -1 do
    if Screen.Forms[i] = aberto then
    begin
    FormExiste := true;
    Break;
    end
end;
para chamar faz assim:
If FormExiste(FUSUARIOS) then
 begin
 FUSUARIOS.BringToFront;
 FUSUARIOS.Focused;
 end else
 begin
 FUSUARIOS := TFUSUARIOS.Create(Self);
 FUSUARIOS.Focused;
 end;
onde FUSUÁRIOS é meu formulario! :wink:


GOSTEI 0
Mrmarcelojr

Mrmarcelojr

22/03/2006

Exemplo. Quando crio o fomulário d cliente : CriaForm(TfrmCliente,frmCliente); e tento me fazer algua coisa neste formulario a partir de outro formulario. Ex.: frmCliente.edtCodi.Enabled:=False;. Aparece o seguinte erro.

´Access violation at adress 00540cff in module ´AProd.exe´. Read of adress 000003c4.´


GOSTEI 0
Mrmarcelojr

Mrmarcelojr

22/03/2006

[quote:a967631ec7=´mrmarcelojr´][quote:a967631ec7=´Martins´]
procedure CForm(Frm: TFormClass; nFrm: TForm);
begin
  Application.CreateForm(Frm, nFrm);
  nFrm.ShowModal;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
   CForm(TForm2, Form2);
end;
Boa sorte :!: .


eu já faço isso, mas eu naum consigo passar nenhum comando para o formulário criado com este metodo. Ah, esqueci de dizer, eu utilizo MDI.[/quote:a967631ec7]

ae, se vc usa MID tente dessa maneira:
// Verifica se o form a ser criado já esta carregado
function FormExiste(aberto: Tform): Boolean;
var
I:Integer;
begin
    FormExiste := false;
    for I := 0 to Screen.FormCount -1 do
    if Screen.Forms[i] = aberto then
    begin
    FormExiste := true;
    Break;
    end
end;
para chamar faz assim:
If FormExiste(FUSUARIOS) then
 begin
 FUSUARIOS.BringToFront;
 FUSUARIOS.Focused;
 end else
 begin
 FUSUARIOS := TFUSUARIOS.Create(Self);
 FUSUARIOS.Focused;
 end;
onde FUSUÁRIOS é meu formulario! :wink:[/quote:a967631ec7]

paullsoftware,

Fiz como voce me mostrou, ms continua dando o mesmo erro quando tento passar algum comando para o form criado.....

estou ficando malucoo...eu preciso urgentemente fazer isso funcionarr!!!


GOSTEI 0
Paullsoftware

Paullsoftware

22/03/2006

Exemplo. Quando crio o fomulário d cliente : CriaForm(TfrmCliente,frmCliente); e tento me fazer algua coisa neste formulario a partir de outro formulario. Ex.: frmCliente.edtCodi.Enabled:=False;. Aparece o seguinte erro. ´Access violation at adress 00540cff in module ´AProd.exe´. Read of adress 000003c4.´

justo, normalmente isso ocorre quando vc usar o showModal... testou o código que te mostrei :?: :?:


GOSTEI 0
Thiago Vidal

Thiago Vidal

22/03/2006

na verdade, a solução do seu problema é bem mais simples... o que está acontecendo, é que você está passando o form ´por valor´ e o correto deveria ser ´por referência´ para poder acessá-lo após a criação.

segue exemplo:
procedure CriaForm(FormClass: TComponentClass; var Form: TForm);
begin
  Applicattion.CreateForm(FormClass, Form);
// ou melhor ainda:
// Form := FormClass.Create(Application);
end;


a diverença, está no [u:9daa7b5429]var[/u:9daa7b5429] que retorna a referencia ao form criado, e não o deixa perdido como nos exemplos anteriores.

o erro de access violation ocorre porque a variavel Form continuava como nil mesmo após a chamada da rotina.

talvez seja ainda melhor usar FormClass: TFormClass, para restringir classes de Form, pq TComponentClass é mais abrangente.

não sei se fui muito claro, mas se tiver mais dúvidas sobre o assunto, pode me contatar.


GOSTEI 0
Mrmarcelojr

Mrmarcelojr

22/03/2006

na verdade, a solução do seu problema é bem mais simples... o que está acontecendo, é que você está passando o form ´por valor´ e o correto deveria ser ´por referência´ para poder acessá-lo após a criação. segue exemplo:
procedure CriaForm(FormClass: TComponentClass; var Form: TForm);
begin
  Applicattion.CreateForm(FormClass, Form);
// ou melhor ainda:
// Form := FormClass.Create(Application);
end;
a diverença, está no [u:fc37cbf851]var[/u:fc37cbf851] que retorna a referencia ao form criado, e não o deixa perdido como nos exemplos anteriores. o erro de access violation ocorre porque a variavel Form continuava como nil mesmo após a chamada da rotina. talvez seja ainda melhor usar FormClass: TFormClass, para restringir classes de Form, pq TComponentClass é mais abrangente. não sei se fui muito claro, mas se tiver mais dúvidas sobre o assunto, pode me contatar.



thiago_vidal

seguinte fera, agora apareceu o seguinte erro quando eu chamo o procedimento: ´Types of actual and formal var parameters must be identical´.

Chamei o procedimento da seguinte forma: CriaForm(TfrmCliente,frmCliente);


GOSTEI 0
Thiago Vidal

Thiago Vidal

22/03/2006

procedure CriaForm(FormClass: TFormClass; var Form);
begin
  Application.CreateForm(FormClass, Form);
end;


desculpa, não tinha testado no Delphi...

o correto é var Form apenas, sem o : TForm na frente.

acho que agora vai, testei aqui!

um abraço!


GOSTEI 0
Martins

Martins

22/03/2006

procedure CriaForm(FormClass: TFormClass; var Form);
begin
  Application.CreateForm(FormClass, Form);
end;
desculpa, não tinha testado no Delphi... o correto é var Form apenas, sem o : TForm na frente. acho que agora vai, testei aqui! um abraço!


Assim como postado pelo [b:ebae2285af]Thiago Vidal[/b:ebae2285af] funciona direitino, pode testar q vai funcionar, boa [b:ebae2285af]Thiago[/b:ebae2285af], vc está passando o From como Reference, o colega tb deveria ter especificado q se tratava de uma aplica MDI, mas tudo bem valew, problema solucionado.

:wink:


GOSTEI 0
Mrmarcelojr

Mrmarcelojr

22/03/2006

Ae tiago, problema solucionado....vlw mesmo...
Ah, e desculpem por naum ter posto que se tratava de MDI...esqueci!!! :oops:

brigadão a todos! :D


GOSTEI 0
Martins

Martins

22/03/2006

Ae tiago, problema solucionado....vlw mesmo... Ah, e desculpem por naum ter posto que se tratava de MDI...esqueci!!! :oops: brigadão a todos! :D

relaxa :wink:


GOSTEI 0
Mmoreira

Mmoreira

22/03/2006

Pessoal,
Estou tendo a seguinte dificuldade em adaptar para minha necessidade:

procedure Abre_Form_MDI( FormClass: TFormClass; var Form );
begin
  if Form = nil then
  Application.CreateForm(FormClass, Form);
end;


Nao compila, da o seguinte erro: ´Incompatible types´


Se eu tiro a condição IF ai funciona perfeitamente ... o problema é que eu gostaria de impedir que o mesmo Form fosse criado mais de uma vez.

Eu até poderia fazer esta verificação fora da Procedure mas para ficar mais simples gostaria de deixar tudo dentro da Procedure mesmo se possivel.

valew!!!


GOSTEI 0
POSTAR