Qual maneira de destruir tabsheet com forms criados dinamica
olá pessoal
tenho no sistema uma tela onde crio tabsheets dinamicamente. Dentro de cada tabsheet é criado um form. Esse form cria dentro dele tb dinamicamento um segundo form e esse por sua vez cria outro form3.
então fico com uma cascata mais ou menos assim:
Todos os forms são do tipo normal.
São criados assim:
Assim terei varios tabsheets, um para cada cliente, sendo q através do findcomponent consigo saber os forms de um cliente para fechá-los e após excluir o tabsheet.
O que fiz mas acabou não dando certo, é no FormPrincipal que tem o pagecontrol com os tabsheets ter um botão Fechar. Nele está o código para ´fechar´ o tabsheet selecionado.
Implementei da seguinte maneira:
Fecho o form1 que está logo abaixo do tabsheet,
no evento form1.Onclosequery eu fecho o form2,
no envento form2.Onclosequery eu fecho o form3.
o código para fechar é o mesmo para todos e não tenho nos forms nenhuma rotina no evento Onclose.
então eu preciso fechar e liberar memória, observando que eu posso fechar esse cliente e criar ele novamente logo após.
e após fechar os forms, qual a maneira de excluir o tabsheet selecionado?
obrigado
Diogo
tenho no sistema uma tela onde crio tabsheets dinamicamente. Dentro de cada tabsheet é criado um form. Esse form cria dentro dele tb dinamicamento um segundo form e esse por sua vez cria outro form3.
então fico com uma cascata mais ou menos assim:
|TabSheet1 | Tabssheet2 | ... |Form1| |Form2| |Form3|
Todos os forms são do tipo normal.
São criados assim:
...
// Tabsheet com o form1
if TabSht = nil then
begin
TabSht := TTabSheet.Create(Self);
TabSht.Name := ´TS´+IntToStr(CdCliente);
TabSht.Caption := NmCliente;
TabSht.PageControl := PgCtrlCliente;
PgCtrlCliente.ActivePage := TabSht;
frm1 := TFrm1F.Create(Self);
frm1.Parent := TabSht;
frm1.Name := ´frm1´+IntToStr(CdCliente);
frm1.show;
end;
...
{No Onshow do primeiro form1 eu crio o Form2}
frm2 := TFrm2F.Create(self);
frm2.Name := ´frm2´+IntToStr(CdCliente);
frm2.Parent := PnlProgs;
frm2.show;
...
{E finalmente crio o form3 no form2.onshow}
frm3 := TFrm3F.Create(self);
frm3.Name := ´frm3´+IntToStr(CdCliente);
frm3.Parent := PnlProgs;
frm3.show;
...Assim terei varios tabsheets, um para cada cliente, sendo q através do findcomponent consigo saber os forms de um cliente para fechá-los e após excluir o tabsheet.
O que fiz mas acabou não dando certo, é no FormPrincipal que tem o pagecontrol com os tabsheets ter um botão Fechar. Nele está o código para ´fechar´ o tabsheet selecionado.
Implementei da seguinte maneira:
Fecho o form1 que está logo abaixo do tabsheet,
no evento form1.Onclosequery eu fecho o form2,
no envento form2.Onclosequery eu fecho o form3.
o código para fechar é o mesmo para todos e não tenho nos forms nenhuma rotina no evento Onclose.
...
{exemplo de como fecho o form1.. o codigo é o mesmo pra todos, só muda o form}
if Self.FindComponent(´frm1´+IntToStr(CdCliente)) <> nil then
TForm(Self.FindComponent(´frm1´+IntToStr(CdCliente))).Close;
...então eu preciso fechar e liberar memória, observando que eu posso fechar esse cliente e criar ele novamente logo após.
e após fechar os forms, qual a maneira de excluir o tabsheet selecionado?
obrigado
Diogo
Diogoalles
Curtidas 0
Respostas
Massuda
22/09/2005
Talvez o mais fácil seja usar o mecanismo de Owner do Delphi.
Faça o Owner do frm1, frm2 e frm3 ser o TabSheet (ao invés de Self como você está fazendo) assim que o TabSheet é destruído ele se encarrega de destruir os forms.
...note que você não pode excluir o TabSheet ativo.
Faça o Owner do frm1, frm2 e frm3 ser o TabSheet (ao invés de Self como você está fazendo) assim que o TabSheet é destruído ele se encarrega de destruir os forms.
qual a maneira de excluir o tabsheet selecionado
Pode fazer assim...var Tab: TTabSheet; ... Tab := PageControl1.ActivePage; if Tab <> nil then begin PageControl1.ActivePageIndex := 0; Tab.Free; end; ...
GOSTEI 0
Diogoalles
22/09/2005
Blz
Funcionou
Obrigado !
Funcionou
Obrigado !
GOSTEI 0
Diogoalles
22/09/2005
Massuda
To com problema com os forms q são criados.
Eu crio e fecho eles e sem fechar o form principal crio novamente, exatamente como está o meu codigo acima só que em vez de ´self´ coloco ´owner´ e em ambos os casos dá AV.
Acho q o problema está na criação dele para que ele seja destruido e criado novamente.
Poderia me ajudar?
obrigado
Diogo
To com problema com os forms q são criados.
Eu crio e fecho eles e sem fechar o form principal crio novamente, exatamente como está o meu codigo acima só que em vez de ´self´ coloco ´owner´ e em ambos os casos dá AV.
Acho q o problema está na criação dele para que ele seja destruido e criado novamente.
Poderia me ajudar?
obrigado
Diogo
GOSTEI 0
Massuda
22/09/2005
...só que em vez de ´self´ coloco ´owner´...
Não entendi... será que dava para você postar aqui seu código?GOSTEI 0
Diogoalles
22/09/2005
Estou fazendo assim para criar os forms:
Os forms estão em ´cascata´
Tenho o formPrincipal que tem o PageControl
O PageControl recebe os tabsheets
O tabsheet criado contém o form1
O form1 criado contém o form2
e o form2 contém o form3.
Para fechar faço o seguinte:
No formPrincipal tenho um botão que ´fecha´ o tabsheet ativo, antes de fehar o tabsheet ativo ele fecha os forms em cascata... 1º o form3, depois o form2 e depois o form1, por fim exclui o tabsheet.
obrigado
Diogo
...
// Tabsheet com o form1
if TabSht = nil then
begin
TabSht := TTabSheet.Create(TabSht);
TabSht.Name := ´TS´+IntToStr(CdCliente);
TabSht.Caption := NmCliente;
TabSht.PageControl := PgCtrlCliente;
PgCtrlCliente.ActivePage := TabSht;
frm1 := TFrm1F.Create(TabSht);
frm1.Parent := TabSht;
frm1.Name := ´frm1´+IntToStr(CdCliente);
frm1.show;
end;
...
{No Onshow do primeiro form1 eu crio o Form2}
frm2 := TFrm2F.Create(Owner);
frm2.Name := ´frm2´+IntToStr(CdCliente);
frm2.Parent := PnlProgs;
frm2.show;
...
{E finalmente crio o form3 no form2.onshow}
frm3 := TFrm3F.Create(Owner);
frm3.Name := ´frm3´+IntToStr(CdCliente);
frm3.Parent := PnlProgs;
frm3.show;
...Os forms estão em ´cascata´
Tenho o formPrincipal que tem o PageControl
O PageControl recebe os tabsheets
O tabsheet criado contém o form1
O form1 criado contém o form2
e o form2 contém o form3.
Para fechar faço o seguinte:
No formPrincipal tenho um botão que ´fecha´ o tabsheet ativo, antes de fehar o tabsheet ativo ele fecha os forms em cascata... 1º o form3, depois o form2 e depois o form1, por fim exclui o tabsheet.
... // procedure Fechar Tabsheet ... // a rotina para fechar o form3 está no form2.OncloseQuery if Owner.FindComponent(´frm3´+IntToStr(CdCliente)) <> nil then begin TForm(Owner.FindComponent(´frm3´+IntToStr(CdCliente))).Close; TForm(Owner.FindComponent(´frm3´+IntToStr(CdCliente))).Free; end; ... // a rotina para fechar o form2 está no form1.OncloseQuery if Owner.FindComponent(´frm2´+IntToStr(CdCliente)) <> nil then begin TForm(Owner.FindComponent(´frm2´+IntToStr(CdCliente))).Close; TForm(Owner.FindComponent(´frm2´+IntToStr(CdCliente))).Free; end; // e a rotina para fechar o form1 está no formPrincipal onde em seguida também é excluido o tabsheet. if Owner.FindComponent(´frm1´+IntToStr(CdCliente)) <> nil then begin TForm(Owner.FindComponent(´frm1´+IntToStr(CdCliente))).Close; TForm(Owner.FindComponent(´frm1´+IntToStr(CdCliente))).Free; end; // exclui o tabsheet selecionado após fechar seus forms parent. TabSht := Frm550F.PgCtrlPac.ActivePage; FreeAndNil(TabSht); ...
obrigado
Diogo
GOSTEI 0
Massuda
22/09/2005
A princípio, acho que não tem necessidade de você ficar dando Close e Free nos foms que estão dentro do TabSheet pois eles serão destruídos junto com o TabSheet (lembre-se de por Action=caFree no OnClose dos forms).
Com relação ao AV, um modo disso acontecer seria o TabSht estar com valor não nil depois de você destruir o TabSheet. A variável TabSht é global?
Tenho a impressão de que a variável TabSht que aparece no trecho que fecha a TabSheet é uma variável local e não é a mesma que aparece na rotina que cria o TabSheet.
Com relação ao AV, um modo disso acontecer seria o TabSht estar com valor não nil depois de você destruir o TabSheet. A variável TabSht é global?
Tenho a impressão de que a variável TabSht que aparece no trecho que fecha a TabSheet é uma variável local e não é a mesma que aparece na rotina que cria o TabSheet.
GOSTEI 0
Michael
22/09/2005
Olá colega!
Reparei nesta linha no seu código:
O Owner da TabSheet é ela mesma?
[]´s
Reparei nesta linha no seu código:
TabSht := TTabSheet.Create(TabSht)
O Owner da TabSheet é ela mesma?
[]´s
GOSTEI 0
Diogoalles
22/09/2005
Michael,
Não entendi bem essa questão do Owner, mas os tabsheets são criados dentor do pagecontrol que está localizado no formPrincipal.
a varável TabSht é global, declarada no form principal:
Não entendi bem essa questão do Owner, mas os tabsheets são criados dentor do pagecontrol que está localizado no formPrincipal.
a varável TabSht é global, declarada no form principal:
.... var Frm550F : TFrm550F; TabSht : TTabSheet; implementation uses ... ...
GOSTEI 0
Michael
22/09/2005
O [b:bb815e3229]Owner [/b:bb815e3229](proprietário, em inglês), é o componente que fica responsável por liberar outros pertencentes a ele da memória, quando este for destruído.
No seu código, eu notei que vc criou um TabSheet informando que o seu proprietário é ele mesmo. Teoricamente isto não é um erro, e até imagino que seja compilado, mas sinceramente não posso prever os efeitos desta abordagem durante a execução do código.
Uma dica: não use variáveis globais, pq não é uma maneira elegante de se programar. Se vc precisa que uma variável tenha um escopo maior, redeclare-as na seção Public ou Private do formulário, convertendo-as assim em campos da classe do form. É uma regra da etiqueta de programação. ;-)
[]´s
No seu código, eu notei que vc criou um TabSheet informando que o seu proprietário é ele mesmo. Teoricamente isto não é um erro, e até imagino que seja compilado, mas sinceramente não posso prever os efeitos desta abordagem durante a execução do código.
Uma dica: não use variáveis globais, pq não é uma maneira elegante de se programar. Se vc precisa que uma variável tenha um escopo maior, redeclare-as na seção Public ou Private do formulário, convertendo-as assim em campos da classe do form. É uma regra da etiqueta de programação. ;-)
[]´s
GOSTEI 0
Massuda
22/09/2005
...Não entendi bem essa questão do Owner...
O que o Michael quis dizer é que é estranho um componente ter como Owner ele mesmo, mas o que acaba acontecendo é que durante a execução, no instante que a linha...TabSht := TTabSheet.Create(TabSht);
TabSht := TTabSheet.Create(nil);
a varável TabSht é global, declarada no form principal:
Sendo assim, nos trechos que você postou não tem como ocorrer AV. Entretanto, observe que a função FindComponent [b:4feb070320]pode[/b:4feb070320] retornar nil, o que resultaria num AV.GOSTEI 0
Michael
22/09/2005
...é executada, TabSht é nil, .
Tem razão Massuda.
De qualquer forma, não me agrada a idéia de se usar uma mesma variável em lugares diferentes do código, com funções diferentes. Fica difícil de se traçar o que está acontecendo.
[]´s
GOSTEI 0
Diogoalles
22/09/2005
ô pessoal, me desculpem.. é que digitei errado e não estava entedendo o que estavam me dizendo:
não é isso:
o CORRETO é esse:
então só pra ver se entendi direito, a forma de criação dos forms dentro do tabsheet está correta?
não preciso nenhuma rotina de close e free para os forms? no caso é só eleminar o tabashhet ?
obrgiado
Diogo
não é isso:
TabSht := TTabSheet.Create(TabSht);
o CORRETO é esse:
TabSht := TTabSheet.Create(PgCtrlCliente); // é o pagecontrol o owner.
então só pra ver se entendi direito, a forma de criação dos forms dentro do tabsheet está correta?
não preciso nenhuma rotina de close e free para os forms? no caso é só eleminar o tabashhet ?
obrgiado
Diogo
GOSTEI 0
Massuda
22/09/2005
...a forma de criação dos forms dentro do tabsheet está correta?
Pelo trecho que você postou, parece que sim....não preciso nenhuma rotina de close e free para os forms? no caso é só eleminar o tabashhet ?
Como o Owner de cada form (se eu entendi direito) é o TabSheet, então quando o TabSheet for destruído ele se encarregará de destruir os forms.GOSTEI 0