Fórum Qual maneira de destruir tabsheet com forms criados dinamica #296513
22/09/2005
0
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
Curtir tópico
+ 0Posts
22/09/2005
Massuda
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.
var Tab: TTabSheet; ... Tab := PageControl1.ActivePage; if Tab <> nil then begin PageControl1.ActivePageIndex := 0; Tab.Free; end; ...
Gostei + 0
22/09/2005
Diogoalles
Funcionou
Obrigado !
Gostei + 0
27/09/2005
Diogoalles
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
27/09/2005
Massuda
Gostei + 0
27/09/2005
Diogoalles
...
// 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
27/09/2005
Massuda
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
27/09/2005
Michael
Reparei nesta linha no seu código:
TabSht := TTabSheet.Create(TabSht)
O Owner da TabSheet é ela mesma?
[]´s
Gostei + 0
27/09/2005
Diogoalles
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
27/09/2005
Michael
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
27/09/2005
Massuda
TabSht := TTabSheet.Create(TabSht);
TabSht := TTabSheet.Create(nil);
Gostei + 0
27/09/2005
Michael
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
27/09/2005
Diogoalles
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
27/09/2005
Massuda
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)