nome do form criado no tabsheet

Delphi

08/08/2005

Olá amiigos..

Na função abaixo eu crio um form dentro do tabsheet do form principal. Gostaria de saber como pegar o nome desse form no momento de fechá-lo:
procedure TForm1.CriaForm(pform: TFormClass; cap: string);
begin
  if T <> nil then
  begin
    PageControl1.ActivePageIndex := 0;
    FreeAndNil(T);
  end
  else
    begin
      T := TTabSheet.Create(PageControl1);
      T.Caption := cap;
      T.PageControl := PageControl1;
      with pForm.Create(T) do
      begin
        Parent := T;
        BorderStyle := bsNone;
        Align := alClient;
        Show;
        pagecontrol1.ActivePage := t;
      end;
   end;
end;

Para chama a procedure
criaform(TForm2, ´Formulario de Teste´);

e para fechar
begin
if T <> nil then
  begin
    PageControl1.ActivePageIndex := 0;
    FreeAndNil(T);
  end;
end;

Então é isso, gostaria de recuperar o nome do formulário antes de fecha-lo, porém não obtive sucesso até agora.

Grato pela ajuda
Sanses


Sanses

Sanses

Curtidas 0

Respostas

Marco Salles

Marco Salles

08/08/2005

with pForm.Create(T) do


[b:0c26b9c796]Sanses , porque a necessidade de se criar um Form dentro de um TabShet , se o proprio tabShet foi desenvolvido para similar Um Form [/b:0c26b9c796]:?:


GOSTEI 0
Sanses

Sanses

08/08/2005

Olá

É uma necessidade da minha aplicação, onde posso colocar vários form´s dentro de um só tabsheet. Alguem sabe responder como recuperar o nome do form atual? Os procedimentos do meu aplicativo estão descritos acima, Grato..

Sanses


GOSTEI 0
Marco Salles

Marco Salles

08/08/2005

É uma necessidade da minha aplicação, onde posso colocar vários form´s dentro de um só tabsheet.


Os procedimentos do meu aplicativo estão descritos acima, Grato..


Esta estranho , porque se esta rotina for executada mais de uma vez ela
destroe o TabSheet Criado :?: :?: :?:

if T <> nil then 
  begin 
    PageControl1.ActivePageIndex := 0; 
    FreeAndNil(T); 


então como é que voce vai criar vários Forms Dentro desse tabShet :?: :?: :?:
So se for de uma só vez seria isso :?: :?: :?:


GOSTEI 0
Isabelct

Isabelct

08/08/2005

e para fechar
begin
if T <> nil then
  begin
    PageControl1.ActivePageIndex := 0;
    FreeAndNil(T);
  end;
end;


Que tipo de objeto é T? ?

procedure TForm1.CriaForm(pform: TFormClass; cap: string);
begin
  if T <> nil then
  begin
    PageControl1.ActivePageIndex := 0;
    FreeAndNil(T);
  end
  else
    begin
      T := TTabSheet.Create(PageControl1);
      T.Caption := cap;
      T.PageControl := PageControl1;
      with pForm.Create(T) do
      begin
        Parent := T;
        BorderStyle := bsNone;
        Align := alClient;
        Show;
        pagecontrol1.ActivePage := t;
      end;
   end;
end;


Particularmente, não gosto de criar componentes dinâmicos com o with por causa disso, você perde a referência ao objeto. Eu sempre crio uma variável auxiliar (um exemplo para o seu caso FormAux: TForm) para armazenar o ponteiro da instância.

Quanto ao seu problema, não sei se entendi... Como assim pegar o nome do formulário? Vamos tentar algumas alternativas...

Você poderia manter um contador de forms criados, e no momento da criação, fazer algo do tipo:

 FormAux.Name = ´FormDinamico´ + IntToStr(Contador);
  Inc(contador);


E desta forma os nomes não se repetiriam. Então você poderia consultar ´FormAux.Name´ e pegar o nome do form.

Talvez não seja isso, e você queira armazenar múltiplas instâncias dos formulários. Para isso, dê uma olhada nos objetos TList e TObjectList. Eles são coleções, que podem armazenar ponteiros para objetos dinâmicos. Para recuperar os objetos à partir deles, será necessário fazer TypeCast (MeuObjectList[Indice] as TForm).

Enfim, espero ter ajudado de alguma forma...


GOSTEI 0
Sanses

Sanses

08/08/2005

Olá

Tem razão Isabelct, alterei meu código (tirei o with) e agora está funcionando. Muito obrigado pela ajuda.

[]´s
Sanses


GOSTEI 0
Marco Salles

Marco Salles

08/08/2005

alterei meu código (tirei o with) e agora está funcionando


O With não pode ser responsãvel pelo seu código não funcionar... :cry:

[b:2570849c73]O[color=darkred:2570849c73] Conceito fundamental aqui é a perda de referencia ao Objeto[/color:2570849c73][/b:2570849c73]

:!: :!: :!: :!:
:arrow: se for so para pegar o[b:2570849c73] nome do form Criado [/b:2570849c73], primeiro voce deve dar um Nome a ele
:arrow: Os códigos abaixo , devolve o nome do form e o destroe... Mas não são indicados :cry: :cry: :cry:

  with pForm.Create(T) do
      begin
        Parent := T;
        BorderStyle := bsNone;
        Name:=´ola´;
       .............
   


[b:2570849c73]Se for para destrui-lo[/b:2570849c73]

if T <> nil then
  begin
     if T.componentCount > 0 Then
       begin
          showmessage(T.Components[0].Name);
         T.Components[0].Free;
      end;
    PageControl1.ActivePageIndex := 0;
   end;


[b:2570849c73]Bem voltemos ao conceito...[/b:2570849c73]

Eu sempre crio uma variável auxiliar (um exemplo para o seu caso FormAux: TForm)


Var 
T:TTabSheet;
FormAux:TForm


procedure CriaForm(var pform:TForm; cap: string);
begin
  if T <> nil then
  begin
    Form1.PageControl1.ActivePageIndex := 0;
    FreeAndNil(T);
  end
  else
    begin
      T := TTabSheet.Create(Form1.PageControl1);
      T.Caption := cap;
      T.PageControl := Form1.PageControl1;
      pForm:=TForm.Cretate(T)
     with pForm do
      begin
        Parent := T;
        BorderStyle := bsNone;
        Name:=´ola´;
        Align := alClient;
        Show;
        Form1.pagecontrol1.ActivePage := t;
      end;
   end;
end;

Para chamar

procedure TForm1.Button1Click(Sender: TObject);
begin
criaform(FormAux, ´Formulario de Teste´);
end;


[b:2570849c73]Para destruir[/b:2570849c73]

procedure TForm1.Button2Click(Sender: TObject);
begin
if T <> nil then
  begin
    PageControl1.ActivePageIndex := 0;
     if assigned(formAux) then
       showmessage(TForm(FormAux).Name);
    freeandnil(FormAux);
  end;
end;


Claro que tem ooutras maneiras de criar um formulário definindo ate mesmo um [b:2570849c73]Constructor personalizado [/b:2570849c73], onde se pode inserir a idéia do Contador Personalizado

Você poderia manter um contador de forms criados, e no momento da criação, fazer algo do tipo:


:idea: :idea:
Código:
No constructor Personalizado
Inc(Contador)

No detructor
Dec(Contador)

etc.....


GOSTEI 0
Sanses

Sanses

08/08/2005

Olá

Bem, veja só, o nome dos formulários não foram alterados, portanto tenho: Form2, Form3... o que eu preciso é saber qual o formulário que foi carregado no tabsheet criado em T para fecha-lo adequadamente.

Vou explicar melhor o porque disso. esta aplicação recebe mensagens na rede via sockets. Quando eu destruo o tabsheet com free e nil, apenas libero o form criado da memória, assim como o tabsheet criado. Depois disso, recebo mensagens de violação. Nas pesquisas que realizei cheguei a conclusão de que tais mensagens poderiam estar sendo exibidas por que o free and nil não redireciona a fila de mensagens para o form principal da aplicação, o que a meu ver resultaria em access violation, pois a aplicação cliente não sabe quando o form vai ser destruído. Já o ´release´ redireciona a fila de mensagens para a aplicação, fazendo com que a mesma passe a responder sem que excessões sejam levantadas.

Minha verdadeira intenção com este poste era conseguir dar um release no form antes de destruir o tabsheet, mas também não funcionaria pois no caso o proprietário do form é o tabsheet, portanto ele teria que ser fechado com release, o que não é possível.

Alterando o código a princípio, excluindo o with, funcionou, mas foi só criar um tabsheet e fecha-lo que os erros de access violation começaram a aparecer.

Sanses


GOSTEI 0
Massuda

Massuda

08/08/2005

...cheguei a conclusão de que tais mensagens poderiam estar sendo exibidas por que o free and nil não redireciona a fila de mensagens para o form principal da aplicação ... Já o ´release´ redireciona a fila de mensagens para a aplicação, fazendo com que a mesma passe a responder sem que excessões sejam levantadas.
Desculpe me intrometer, mas isso está errado.

Tanto no caso de destruir o form usando Free e usando Release a fila de mensagens (mantida pelo Windows) é destruída junto com a janela (aqui no sentido de um objeto do Windows). A diferença entre Free e Release é que Release irá processar todas as mensagens pendentes na fila enquanto Free simplesmente irá descartar essas mensagens.

Exceções de access violation estão relacionadas com tentar utilizar um objeto que já foi destruído (referência/ponteiro inválido) ou que é nil. Os trechos de códigos que você postou aparentemente estão OK, portanto a causa do problema deve estar em outro lugar.

Experimente pela causa da exceção fazendo, por exemplo, execução passo-a-passo ou tentando localizar o endereço onde a exceção está sendo gerada (veja, por exemplo, meu post [url=http://forum.clubedelphi.net/viewtopic.php?t=62323]neste tópico[/url]).


GOSTEI 0
Sanses

Sanses

08/08/2005

Olá Massuda

Bem o problema é que não acontece sempre. Vou explicar melhor, as vezes abro um form no tabsheet normalmente e fecho e não acontece nada. As vezes abro e fecho e depois de algum tempo começo a receber mensagens de erro (várias mas todas com o mesmo número de erro. Por isso pensei que fossem as mensagens que não haviam sido direcionadas e conforme o sistema recebe informação via sockets, os erros vão aparecendo. Mas como disse, as vezes tem erro, as vezes não. Por isso está tão dificil de achar.

Grato
Sanses


GOSTEI 0
POSTAR