Fórum Macro em delphi #142184

28/02/2003

0

Oi. Estou usando o seguinte código para poder usar objetos de forma dinamica em delphi:


var
i: Integer;
begin
for i := 0 to PrincipalForm.ComponentCount - 1 do
if PrincipalForm.Components[i] is TLabel then
TLabel(PrincipalForm.Components[i]).Caption := ´TESTANDO´;
end

Funcionou belezinha, mas agora preciso destruir esses objetos pq senão toda hora que o evento onshow do form rodar ele irá criar os campos.
Assim, no onclose estou usando:

procedure TfrmIncluir.FormClose(Sender: TObject; var Action: TCloseAction);
VAR i : integer;
begin

for i := 0 to FRMINCLUIR.ComponentCount - 1 do
BEGIN
if FRMINCLUIR.Components[i] is TDBEDIT then
begin
TDBEdit(FRMINCLUIR.Components[i]).free;
end;
END;

end;

Mas aparece a mensagem de erro :
Project LdsErp.exe raised exception class EListError with message ´List index out of bounds (112)´. Process stopped. Use Step or Run to continue.

Alguém pode me ajudar a resolver.
Desde já agradeço.


Doug_chagas

Doug_chagas

Responder

Posts

28/02/2003

Marcelo Saviski

[size=14:04919a89dc][color=blue:04919a89dc][b:04919a89dc]Experimente[/b:04919a89dc][/color:04919a89dc][/size:04919a89dc]
for i := 0 to FRMINCLUIR.ComponentCount - 1 do 
BEGIN 
if FRMINCLUIR.Components[i] is TDBEDIT then 
begin 
(FRMINCLUIR.Components[i] as TDBEdit).free; 
end; 
END; 



Responder

Gostei + 0

28/02/2003

Doug_chagas

[quote:ab244a93a9=´Marcelo Saviski´][size=14:ab244a93a9][color=blue:ab244a93a9][b:ab244a93a9]Experimente[/b:ab244a93a9][/color:ab244a93a9][/size:ab244a93a9]
for i := 0 to FRMINCLUIR.ComponentCount - 1 do 
BEGIN 
if FRMINCLUIR.Components[i] is TDBEDIT then 
begin 
(FRMINCLUIR.Components[i] as TDBEdit).free; 
end; 
END; 
[/quote:ab244a93a9]

Continua aparecendo o mesmo erro de out of bounds


Responder

Gostei + 0

28/02/2003

Carnette

Desculpa ignorancia...mas, vc está construindo objetos TLABEL e destruindo objetos TEDIT ???...por acaso vc construi os objetos TEDIT ??


Responder

Gostei + 0

28/02/2003

Marcelo Saviski

:arrow: [b:b38ff45f46][color=orange:b38ff45f46]Mais ou menos quantos DBEdit´s tem no Formulário?[/color:b38ff45f46][/b:b38ff45f46] :?:


Responder

Gostei + 0

28/02/2003

Doug_chagas

Desculpa ignorancia...mas, vc está construindo objetos TLABEL e destruindo objetos TEDIT ???...por acaso vc construi os objetos TEDIT ??


To construindo os 2 tipos de objetos e tenho que destruir ambos. Mas na hora de dar Ctrl+c para o forum copiei a parte errada do fonte, mas acho que deu pra enterder.

Só não entendo, pq debugando ele passa pela instrução .free um monte de vezes sem dar erro e depois aparece o erro.

Achei que pudesse ser que ele tentava dar free em um i > component count, mas coloque componentcount -10 e mesmo assim não funcionou.

Valew


Responder

Gostei + 0

28/02/2003

Doug_chagas

[quote:d7689f50f8=´Marcelo Saviski´]:arrow: [b:d7689f50f8][color=orange:d7689f50f8]Mais ou menos quantos DBEdit´s tem no Formulário?[/color:d7689f50f8][/b:d7689f50f8] :?:[/quote:d7689f50f8]

Depende da tabela. Pq eu leio o nº de campos da tabela e crio dbedit pra cada campo.

+- uns 100


Responder

Gostei + 0

28/02/2003

Carnette

cara tenho uma idéia...pra vc não precisar ficar se preocupando em destruir os objetos...


pq vc não chama o form em tempo de execução assim:

Application.ProcessMessages;
FormTal := TFormTal.Create(Self);
try
FormTal.showmodal;
finally
FormTal.Free;
end;


não sei se vc manja disso..mas, fica muito mais fácil..pois, toda vez que voce fecha o FormTal, todo é liberado...e começa do zero


Responder

Gostei + 0

28/02/2003

Doug_chagas

cara tenho uma idéia...pra vc não precisar ficar se preocupando em destruir os objetos... pq vc não chama o form em tempo de execução assim: Application.ProcessMessages; FormTal := TFormTal.Create(Self); try FormTal.showmodal; finally FormTal.Free; end; Fiz uns teste e esta dando certo. Valew não sei se vc manja disso..mas, fica muito mais fácil..pois, toda vez que voce fecha o FormTal, todo é liberado...e começa do zero



Responder

Gostei + 0

28/02/2003

Anonymous

Olá, eu faria assim:

no evento OnClose do formulário escreva assim:

se for Label:
TLabel(Form1.Controls[0]).Free;
se for Edit
TEdit(Form1.Controls[0]).Free;

você destruindo o componente ancestral, os herdeiros automaticamente são destruidos também!

Veja se funciona.

Mande uma respota, para mim saber, se resolveu também!

Até mais!


Responder

Gostei + 0

28/02/2003

Anonymous

Desculpa aí, coloquei errado!

é assim:

crie uma variável do tipo TWinControl;
exemplo:

var
cWControl: TWinControl;
begin
while cWControl.ControlCount > 0 do
cWControl.Controls[0].Free;
end;

Vê se funciona!


Responder

Gostei + 0

28/02/2003

Anonymous

Para destruir os objetos que fazem parte de uma lista, devem ser iniciado pelo final. Ex.:

Este exemplo destrói todos os componentes criados, mas se quiser excluir determinados componentes poderá colocar a verificação antes de destrui-lo.

for i := FRMINCLUIR.ComponentCount-1 dowto 0 do
Tcomponent(FRMINCLUIR.Components[i]).free;

Espero que o ajude.
Slater
compcker@ig.com.br


Responder

Gostei + 0

01/03/2003

Anonymous

Todo o seu código está correto, tem apenas uma falha:

procedure TfrmIncluir.FormClose(Sender: TObject; var Action: TCloseAction);
VAR i : integer;
begin
for i := 0 to FRMINCLUIR.ComponentCount - 1 do
BEGIN
if FRMINCLUIR.Components[i] is TDBEDIT then
begin
TDBEdit(FRMINCLUIR.Components[i]).free;
end;
END;
end;

Onde você põe FRMINCLUIR.ComponentCount - 1 vai dar erro num certo momento pois você pode ´estourar´ o intervalo.

Suponha que você tem 20 componenetes e vai apagar os últimos 10. Na primeira passagem, o [b:371aea6ca6]i[/b:371aea6ca6] vale 0, e assim por diante, até chegar na posição 10. A partir da posição 10 os itens serão apagados, mas o FRMINCLUIR.ComponentCount não sofrerá um refresh. Ou seja, na 16a. passagem, você tentará excluir o componente 16, mas no form existirão apenas 15. Para contornar esse problema, faça a contagem de trás pra frente. Assim:

procedure TfrmIncluir.FormClose(Sender: TObject; var Action: TCloseAction);
VAR i : integer;
begin
for i := FRMINCLUIR.ComponentCount-1 downto 0 do
BEGIN
if FRMINCLUIR.Components[i] is TDBEDIT then
begin
TDBEdit(FRMINCLUIR.Components[i]).free;
end;
END;
end;

Note bem a linha de cabeçalho do [b:371aea6ca6]for[/b:371aea6ca6], que sofreu a alteração para contar de trás pra frente. Utilize esse recurso sempre que o seu parâmetro de contagem puder ser eliminado.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar