Macro em delphi
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.
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
Curtidas 0
Respostas
Marcelo Saviski
28/02/2003
[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;
GOSTEI 0
Doug_chagas
28/02/2003
[quote:ab244a93a9=´Marcelo Saviski´][size=14:ab244a93a9][color=blue:ab244a93a9][b:ab244a93a9]Experimente[/b:ab244a93a9][/color:ab244a93a9][/size:ab244a93a9]
[/quote:ab244a93a9]
Continua aparecendo o mesmo erro de out of bounds
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;
Continua aparecendo o mesmo erro de out of bounds
GOSTEI 0
Carnette
28/02/2003
Desculpa ignorancia...mas, vc está construindo objetos TLABEL e destruindo objetos TEDIT ???...por acaso vc construi os objetos TEDIT ??
GOSTEI 0
Marcelo Saviski
28/02/2003
:arrow: [b:b38ff45f46][color=orange:b38ff45f46]Mais ou menos quantos DBEdit´s tem no Formulário?[/color:b38ff45f46][/b:b38ff45f46] :?:
GOSTEI 0
Doug_chagas
28/02/2003
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
GOSTEI 0
Doug_chagas
28/02/2003
[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
Depende da tabela. Pq eu leio o nº de campos da tabela e crio dbedit pra cada campo.
+- uns 100
GOSTEI 0
Carnette
28/02/2003
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
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
GOSTEI 0
Doug_chagas
28/02/2003
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
GOSTEI 0
Anonymous
28/02/2003
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!
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!
GOSTEI 0
Anonymous
28/02/2003
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!
é 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!
GOSTEI 0
Anonymous
28/02/2003
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
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
GOSTEI 0
Anonymous
28/02/2003
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.
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.
GOSTEI 0