Como liberar tabsheet criada dinamicamente?

Delphi

14/03/2005

Olá pessoal.

Estou pensando em desenvolver um sistema com a interface sugerida na matéria ´Sua aplicação com visual arrojado´, da revista clube delphi edição 60.
Vi dois problemas na matéria do Luciano Pimenta:

1º: Ele coloca uma imagem de close na aba de tela de boas vindas, mas não mostra como fazer para ativar o evento ao clicar em cima da imagem.
2º: Não mostrou como fechar uma tabsheet criada dinâmicamente.

Quando tento destruir um tabsheet já existente, não dá erro, mas se tento destruir um tabsheet criado dinâmicamente, dá erro de violação de memória!

Alguém pode me ajudar?

Abraços.


Wilder_lopes

Wilder_lopes

Curtidas 0

Respostas

Massuda

Massuda

14/03/2005

Talvez [url=http://forum.clubedelphi.net/viewtopic.php?t=59887]este tópico recente[/url] seja útil para você.


GOSTEI 0
Wilder_lopes

Wilder_lopes

14/03/2005

olá Massuda.

Eu já tinha pesquisado esse tópico. Ele não ajudou pq não mostrou a solução.
As dicas q deram não funcionaram para o caso do botão q acionava o fechamento do tabsheet ser no próprio tabsheet.

Fico no aguardo, se algúem puder ajudar!

abraços!


GOSTEI 0
Sanses

Sanses

14/03/2005

Ola Wilder, tb foi baseado no exemplo da revista que iniciei o outro tópico sobre como fechar o tabsheet criado dinamicamente.

Não fosse só este problema, tem mais imagine se vc for criar 25 forms em toda a sua aplicação !!!!! Teria que repetir o código 25 vezes....

Coloquei um outro post pedindo ajuda sobre como fazer para que no evento click do botão, seja passado apenas o nome do form para aquela rotina de criação, assim seria mais enxuto e fucional. O que acha? Mas não consegui fazer isso até agora.

Quanto a fechar o tabsheet criado dinamicamente, bem acho que um objeto não pode destruir-se

Qualquer coisa estamos ai, se eu conseguir realizar o que disse acima, posto pra vc.

Sanses


GOSTEI 0
Wilder_lopes

Wilder_lopes

14/03/2005

Olá Sanses.

Acredito que vc teria mesmo q fazer a chamada 25 vezes para o código, uma para cada clique no menu. Mas não é necessário repetir 25 vezes a mesma coisa. vc pode fazer uma função que vai receber como parâmetro o nome do form. Revi o seu tópico e vc pode fazer exatamente o seguinte:

function Novoform(pform : tform); 
begin 
  if Tab = nil then 
  begin 
    Tab := TTabSheet.Create(PageControl1); 
    Tab.Caption := ´Teste´; 
    Tab.PageControl := PageControl1; 
    with (pForm as TForm).Create(Tab) do 
    begin 
      Parent := Tab; 
      BorderStyle := bsNone; 
      Align := alClient; 
      Show; 
    end; 
  end; 
  
  PageControl1.ActivePage := Tab; 
end;



Aproveitei o seu próprio código postado e só fiz algumas alterações.

Quanto aos tabsheets, até aceito q eles não possam se fechar, mas eu fiz o seguinte:

1 - criei o tabsheet dinamicamente.
2 - no evento close dele, mudo o tabsheet com foco e chamo um procedimento no form principal para liberá-lo. no caso, o form principal é q vai tentar fechá-lo.

O estranho é que se o tabsheet não for criado dinamicamente funciona.

abraços.
[/code:1:40a2a487c3][code:1:40a2a487c3]



GOSTEI 0
Lucianopimenta

Lucianopimenta

14/03/2005

Ola Wilder,

caso vc queira fechar o TabSheet no formulário principal, basta fazer assim:

(Form.Parent as TTabSheet).Free;

Se vc quiser fechar com um botão no Form:

(Self.Parent as TTabSheet).Free;


GOSTEI 0
Wilder_lopes

Wilder_lopes

14/03/2005

Luciano,

Muito obrigado. Funcionou.

Parabéns pela matéria!


GOSTEI 0
Sanses

Sanses

14/03/2005

Se puderem me ajudar ficarei grato, pois mesmo com as dicas não consegui realizar. Quanto ao procedimento que abre o novo form, fiz o seguinte:
[b]no botão:[/b]

begin
CriaForm(Form1);
end;

[b]o procedimento[/b]

procedure Tfrmshservidor.CriaForm(pform: tform);
begin
  if T = nil then
  begin
    T := TTabSheet.Create(PageControl1);
    T.Caption := ´Teste´;
    T.PageControl := PageControl1;
    with (pForm as TForm).Create(T) do
    begin
      Parent := T;
      BorderStyle := bsNone;
      Align := alClient;
      Show;
    end;
  end;
  PageControl1.ActivePage := T;
end;

mas dá access violation.

E quanto a dica do luciano, não entendi direito como colocar aquele comando no form que será fechado...

Agradeço a ajuda
Sanses


GOSTEI 0
Massuda

Massuda

14/03/2005

Sanses:

Tenho a impressão que o problema todo é o membro T usado para saber se o tabsheet já foi criado e que o AV ocorre na segunda vez que tenta criar o tabsheet.

Se for isso, no código que destrói o seu tabsheet, tem como você fazer algo do tipo
SeuForm.T := nil;



GOSTEI 0
Sanses

Sanses

14/03/2005

Correto, mas na criação ele já verifica se esta como nil. Além disso, o AV ocorre na primeira vez que chamo a função para criar o form.

Obrigado pela atenção
Sanses


GOSTEI 0
Sanses

Sanses

14/03/2005

Amigos

Debugando a aplicação notei que o erro ocorre por causa do Tform e Form. no exemplo do Wilder se for passado form1 por exemplo não funciona (AV) e se for passado Tform1 funciona, porém não consegui fazer esta passagem de parametros atravez de tform
erro:
with (pForm as TForm).Create(T) do

era pra realizar a passagem do form para Tform, mas não está passando

Aguardo ajuda
Obrigado
Sanses


GOSTEI 0
Massuda

Massuda

14/03/2005

era pra realizar a passagem do form para Tform, mas não está passando
O problema é que o parâmetro pForm precisa conter um valor diferente de nil, ou seja, precisa ser um form já criado.

Para evitar isso, experimente criar o form pela classe dele...
procedure CriaForm(AClass: TFormClass); 
begin 
  if T = nil then 
  begin 
    T := TTabSheet.Create(PageControl1); 
    T.Caption := ´Teste´; 
    T.PageControl := PageControl1; 
    with AClass.Create(T) do 
    begin 
      Parent := T; 
      BorderStyle := bsNone; 
      Align := alClient; 
      Show; 
    end; 
  end; 
  
  PageControl1.ActivePage := T; 
end;
Assim para criar o form você faz CriaForm(TForm1).

Quanto ao AV ao destruir o tabsheet... seu pagecontrol contem apenas tabsheet criadas dinamicamente?


GOSTEI 0
Sanses

Sanses

14/03/2005

obrigado pela resposta, vou testar.
O pagecontrol tem somente 1 tabsheet criado na inicialização, não dinâmico, mas serão um total de 3 ao final do projeto. O restante será dinâmico.

Sanses


GOSTEI 0
Sanses

Sanses

14/03/2005

Valew Massuda, funcionou perfeitamente. Obrigado!!

Mais uma coisa, se não for abusar da sua boa vontade, sobre a dica do Luciano para fechar o form pelo proprio form, eu não entendi onde será colocado o código, pois se for colocado no form 1 não compila, vc tem idéia de como fazer??

Mais uma vez obrigado por sua ajuda. Resolveu o principal problema do tópico.
Sanses


GOSTEI 0
Massuda

Massuda

14/03/2005

... sobre a dica do Luciano para fechar o form pelo proprio form, eu não entendi onde será colocado o código, pois se for colocado no form 1 não compila, vc tem idéia de como fazer??
Form1 é o form embutido no tabsheet né? Nesse caso, se tiver um botão nesse form para o form ´cometer suicídio´, o código do OnClick desse botão seria
(Self.Parent as TTabSheet).Free;
mas, como precisa nil´zar o valor de T no form onde está o pagecontrol (senão você não consegue criar novos tabsheets) você precisa acessar o tabsheet, talvez fosse mais fácil fazer no OnClick desse botão
FreeAndNil(SeuForm.T);



GOSTEI 0
Sanses

Sanses

14/03/2005

Pois é, acho tb que seria isso, mais não sei o que está acontecendo, mas o form 1 não enxerga o T do form principal, mesmo com user unit...

alias, nem o T nem o pagecontrol....


Sanses
Ps. hoje eu xuto o barde!!!


GOSTEI 0
Wilder_lopes

Wilder_lopes

14/03/2005

Fala Pessoal.

Caramba, tá rolando um problema bizarro agora.

Tá criando dinâmicamente as novas abas corretamente mas na hora de destruir a aba tá dando erro de AV. Usando o (Self.Parent as TTAbsheet).Free só funciona sem o problema quando deixo os forms como auto-create. Por isso o teste q eu tinha feito funcionou.

Agora que realmente comecei a desenvolver e os forms não são auto-create, deu o problema.

Eu criei um array para controlar os forms q já instanciei. Fiz isso pra no caso de eu clicar em ´cadastro de cliente´ pela segunda vez, em vez de criar outro form, apenas apontar para a aba certa. Isso tudo está funcionando. Fui debugando e vi que o erro não acontece no momento da destruição da aba, e sim, na linha logo após que nada mais é do que o comando ´end;´ da procedure do click do botão.
O mais sinistro de tudo é que se eu clicar no botão de clientes duas vezes (a 1ª cria o form e a aba e a 2ª apeans direciona a aba já que o form já foi criado), o erro não acontece.

Algumas vezes não dá o erro nem clicando uma vez só. às vezes abro e fecho umas n vezes sem problemas e somente na n+1 é q ocorre.

Já viram problema como esse? muito, muito esquisito!

Obrigado!


GOSTEI 0
Wilder_lopes

Wilder_lopes

14/03/2005

Acabei de descobrir um detalhe:

Só tá dando o erro se o form for herdado.

Eu criei um form com características básicas, como a rotina de fechamento da aba, por exemplo, e depois criei outro herdando dele.
Estava testando criando o form filho e dava o problema.
Testei com o form pai agora e não deu o erro. o detalhe, é que não coloquei nada de diferente no form filho.
Será bug do delphi 2005?

Abraços...


GOSTEI 0
POSTAR