Array
(
)

Como liberar esta variavel da memoria?

Titanius
   - 10 fev 2006

Olá, tenho a seguinte Variavel:
#Código


const
MaxJanelas = 20;
...
public
FormsPnl: array[0..MaxJanelas] of TJvEmbeddedInstanceFormPanel;


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

#Código

FormsPnl[Idx] := TJvEmbeddedInstanceFormPanel.Create(nil);
FormsPnl[Idx].FormLink := ((_FormLink as TForm).FindComponent(´FormLink´)) as TJvEmbeddedFormLink;
FormsPnl[Idx].Parent := FrmPrincipal;
FormsPnl[Idx].Align := alClient;
FormsPnl[Idx].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


Michael
   - 10 fev 2006

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.

#Código

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


[]´s


Titanius
   - 10 fev 2006

Olá Michael, segue o codigo
#Código


var
i: integer;
begin
for i := 0 to MaxJanelas do
begin
if UpperCase(FormsPnl[i].LinkedForm.Name) = UpperCase(Item.Hint) then
begin
FormsPnl[i].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


Titanius
   - 10 fev 2006

oops, eskeci de um end;.

#Código


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



Siam
   - 10 fev 2006

Tente inverter o for#Código

for i := MaxJanelas downto 0 do



Michael
   - 10 fev 2006


Citação:
Tente inverter o for#Código

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.

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

#Código
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


Titanius
   - 10 fev 2006

Valeu Galera...

Achei o problema, como tinha na minha array objetos nil, ele chegava nele e dava o erro, arrumei assim:
#Código


for i := 0 to MaxJanelas do
begin
if FormsPnl[i] <> nil then
begin
if UpperCase(FormsPnl[i].LinkedForm.Name) = UpperCase(Item.Hint) then
begin
FormsPnl[i].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:
#Código

FrmViewer := TFrmViewer.Create(nil);
CriaTab(TabBar1, ´Viewer 1´, FrmViewer);


e minha funcao eh assim:
#Código

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] = nil then
begin
Idx := i;
Break;
end
else
FormsPnl[i].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.´, [0]);
end;

FormsPnl[Idx] := TJvEmbeddedInstanceFormPanel.Create(nil);
FormsPnl[Idx].FormLink := ((_FormLink as TForm).FindComponent(´FormLink´)) as TJvEmbeddedFormLink;
FormsPnl[Idx].Parent := FrmPrincipal;
FormsPnl[Idx].Align := alClient;
FormsPnl[Idx].Visible := True;
_Tab.Tabs.Items[_Tab.Tabs.Count].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


Siam
   - 11 fev 2006


Citação:

Citação:
Tente inverter o for#Código


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.Certíssimo !