Array
(
)

Problemas com CreateForm

Mrmarcelojr
   - 22 mar 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.


Martins
   - 22 mar 2006

#Código


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


#Código

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


Boa sorte :!: .


Paullsoftware
   - 22 mar 2006


Citação:
#Código


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


#Código

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
#Código

procedure CForm(Frm: TFormClass; nFrm: TForm);
begin
Try
Application.CreateForm(Frm, nFrm);
nFrm.ShowModal;
Finally
nForm.Release;
nForm:=Nil;
end;
end;
:?: :?: :?:


Mrmarcelojr
   - 22 mar 2006


Citação:
#Código


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


#Código

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.


Paullsoftware
   - 22 mar 2006


Citação:

Citação:
#Código


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


#Código

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.

ae, se vc usa MID tente dessa maneira:
// Verifica se o form a ser criado já esta carregado
#Código
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:
#Código
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:


Mrmarcelojr
   - 22 mar 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.´


Mrmarcelojr
   - 22 mar 2006


Citação:

Citação:

Citação:
#Código


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


#Código

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.

ae, se vc usa MID tente dessa maneira:
// Verifica se o form a ser criado já esta carregado
#Código
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:
#Código
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:

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!!!


Paullsoftware
   - 22 mar 2006


Citação:
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 :?: :?:


Thiago Vidal
   - 22 mar 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:
#Código

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.


Mrmarcelojr
   - 22 mar 2006


Citação:
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:
#Código

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);


Thiago Vidal
   - 22 mar 2006

#Código

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!


Martins
   - 22 mar 2006


Citação:
#Código

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 Thiago Vidal funciona direitino, pode testar q vai funcionar, boa Thiago, 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:


Mrmarcelojr
   - 22 mar 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


Martins
   - 22 mar 2006


Citação:
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:


Mmoreira
   - 24 dez 2006

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

#Código


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!!!