Fórum nome do form criado no tabsheet #291045
08/08/2005
0
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
Curtir tópico
+ 0Posts
08/08/2005
Marco Salles
[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
09/08/2005
Sanses
É 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
09/08/2005
Marco Salles
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
09/08/2005
Isabelct
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
09/08/2005
Sanses
Tem razão Isabelct, alterei meu código (tirei o with) e agora está funcionando. Muito obrigado pela ajuda.
[]´s
Sanses
Gostei + 0
09/08/2005
Marco Salles
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]
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
:idea: :idea:
Código:
No constructor Personalizado
Inc(Contador)
No detructor
Dec(Contador)
etc.....
Gostei + 0
09/08/2005
Sanses
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
09/08/2005
Massuda
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
10/08/2005
Sanses
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
Clique aqui para fazer login e interagir na Comunidade :)