Como liberar esta variavel da memoria?

10/02/2006

Olá, tenho a seguinte Variavel:
const
MaxJanelas = 20;
...
 public
  FormsPnl: array[0..MaxJanelas&93; of TJvEmbeddedInstanceFormPanel; 


Ou seja, é uma variavel que guardará o objeto EmbeddedInstanceFormPanel, pois bem.. eu crio assim:

   FormsPnl&91;Idx&93; := TJvEmbeddedInstanceFormPanel.Create(nil);
   FormsPnl&91;Idx&93;.FormLink := ((_FormLink as TForm).FindComponent(´FormLink´)) as TJvEmbeddedFormLink;
   FormsPnl&91;Idx&93;.Parent := FrmPrincipal;
   FormsPnl&91;Idx&93;.Align := alClient;
   FormsPnl&91;Idx&93;.Visible := True;


Sem problemas, quanto a isso...

Mas, como eu faço para tirar da memoria o FormsPnl[1] por exemplo.

Tentei:
(FormsPnl[i] as TJvEmbeddedInstanceFormPanel).Free;
FormsPnl[i].Free;
FormsPnl[i] := nil;

e nada, dá erro de memoria...

como eu faria isso? Estou criando certo? tem um jeito melhor para criar isso e depois liberar da memoria?

Obrigado a todos,

[]s


Titanius

Respostas

10/02/2006

Michael

Olá!

Qual é exatamente o erro? Access Violation?

Outra coisa: parece que vc está destruindo os forms em um loop, certo? Poste o código usado nesse loop.

Ah, vc definiu a array com 21 elementos, e não com 20, como aparentemente deveria ser. Não posso afirmar sem ver o código, mas isso pode ser a causa do erro.

FormsPnl: array[0..MaxJanelas&93; of TJvEmbeddedInstanceFormPanel; // 0 .. 20 = 21


[]´s


Responder Citar

10/02/2006

Titanius

Olá Michael, segue o codigo
var
 i: integer;
begin
 for i := 0 to MaxJanelas do
 begin
  if UpperCase(FormsPnl[i&93;.LinkedForm.Name) = UpperCase(Item.Hint) then
  begin
   FormsPnl&91;i&93;.Free <<-- ERRO
 end;
 end;



O erro eh violação de acesso de memoria...

Não tem como criar isso de outra forma não? mais facil?

[]s


Responder Citar

10/02/2006

Titanius

oops, eskeci de um end;.

var
 i: integer;
begin
 for i := 0 to MaxJanelas do
 begin
  if UpperCase(FormsPnl[i&93;.LinkedForm.Name) = UpperCase(Item.Hint) then
  begin
  FormsPnl&91;i&93;.Free;
  end;
 end;
end;



Responder Citar

10/02/2006

Siam

Tente inverter o [b:6f54f51712]for[/b:6f54f51712]
for i := MaxJanelas downto 0 do



Responder Citar

10/02/2006

Michael

Tente inverter o [b:e6071e33c0]for[/b:e6071e33c0]
for i := MaxJanelas downto 0 do


Isso não faz diferença aqui pq a array não diminui de tamanho quando um objeto é liberado da memória.

[b:e6071e33c0]Titanius[/b:e6071e33c0], o erro ocorre logo na primeira iteração do loop? Ou na última? Tente isso:

for I := Low(FormsPnl) to High(FormsPnl) do
...


O erro não é no Free, pois mesmo que o objeto fosse nil o método checa antes de chamar o Destroy da classe.

[]´s


Responder Citar

10/02/2006

Titanius

Valeu Galera...

Achei o problema, como tinha na minha array objetos nil, ele chegava nele e dava o erro, arrumei assim:
 for i := 0 to MaxJanelas do
 begin
  if FormsPnl[i&93; <> nil then
  begin
   if UpperCase(FormsPnl&91;i&93;.LinkedForm.Name) = UpperCase(Item.Hint) then
   begin
    FormsPnl&91;i&93;.Free;
   end;
  end;
 end;


Beleza, porem tenho um probleminha.. Como viram, eu coloco o nome do Form, no Hint do Item, para depois eu poder fazer o if, porém, eu crio o form em runtime, e o nome sempre fica assim:

NomeForm_1
NomeForm_2
NomeForm_3

eu chamo a funcao assim:
 FrmViewer := TFrmViewer.Create(nil);
 CriaTab(TabBar1, ´Viewer 1´, FrmViewer);


e minha funcao eh assim:
function CriaTab(_Tab: TJvTabBar; _Caption: string; _FormLink: TForm; const _ImgIdx: integer = 3; const _Focar: Boolean = True): Boolean;
var
 Idx, i: integer;
begin
 try
  IncluindoTab := True;
  // Crio o Tab
  with _Tab.AddTab(Trim(_Caption)) do
  begin
   Hint := Trim(_FormLink.Name);
   Enabled := True;
   ImageIndex := _ImgIdx;
   Visible := True;
   Selected := _Focar;
   ShowHint := False;
  end;
  with FrmPrincipal do
  begin
   Idx := -1;
   for i := 0 to MaxJanelas do
   begin
    if FormsPnl[i&93; = nil then
    begin
     Idx := i;
     Break;
    end
    else
     FormsPnl&91;i&93;.Visible := False;
   end;
   if Idx = -1 then
   begin
    Mensagem(1, ´Número máximo de janelas alcançado. Por favor feche alguma janela e tente novamente.´, &91;0&93;);
   end;

   FormsPnl&91;Idx&93; := TJvEmbeddedInstanceFormPanel.Create(nil);
   FormsPnl&91;Idx&93;.FormLink := ((_FormLink as TForm).FindComponent(´FormLink´)) as TJvEmbeddedFormLink;
   FormsPnl[Idx&93;.Parent := FrmPrincipal;
   FormsPnl&91;Idx&93;.Align := alClient;
   FormsPnl&91;Idx&93;.Visible := True;
   _Tab.Tabs.Items&91;_Tab.Tabs.Count&93;.Hint := (_FormLink as TForm).Name;
   IdxEmUso := Idx;
  end;

  Application.ProcessMessages;
  IncluindoTab := False;
  Result := True;
 except
  Result := False;
 end;
end;


O nome do form sempre ta vindo um antes do que esta realmente o nome..

Alguma ideia de como eu faco isso?

Bem, minha ideia eh a seguinte, tenhi uma Bar onde fica o titulo dos forms, e um Painel do JEDI que eu vinculo o Form, e me exibe o form nele, pois bem, fiz isso tudo pra eu poder criar uma Aba no TabBar, com o Caption passado, e crio o JVEmbeddedForm e vinculo ele no Form que eu acabei de criar, para que seja exibido ele...

Bem, consegui dessa forma, será que tem como fazer melhor? Melhorar o codigo?

Obrigado.

[]s


Responder Citar

11/02/2006

Siam

[quote:9d7ebe0a78=´siam´]Tente inverter o [b:9d7ebe0a78]for[/b:9d7ebe0a78]
for i := MaxJanelas downto 0 do




Isso não faz diferença aqui pq a array não diminui de tamanho quando um objeto é liberado da memória.[/quote:9d7ebe0a78]Certíssimo !


Responder Citar