Destruir componentes

Delphi

08/09/2008

Bom dia pessoal....
Eu tow criando componentes em tempo de execução....até aew blz...mas na hora de destruir....tah dando Acess Violation....

Eis o código...

Procedure DestroyComponentes();

Var I : Integer;

  Begin

     With FrmConfiguracaoEmail Do

        Begin

           For I := ComponentCount - 1 Downto 0 Do

              If (Components[I] Is TLabel) Or (Components[I] Is TEdit) Or (Components[I] Is TComboBox) Or (Components[I] Is TButton) Then

                  Components[I].Free;

        End;

  End;


Onde estaria o erro???
Após percorrerer todo o laço q o erro acontece...


Vlw pessoal....


Wdrocha

Wdrocha

Curtidas 0

Respostas

Adoniram

Adoniram

08/09/2008

Como vc cria os componentes?
Se o Owner for o proprio form não precisa destruí-los. Se não for, pq vc não atribui o form como Owner. São componentes visuais.

Já havia respondido esse tópico, mas minha resposta não apareceu na listagem. Talvez eu tenha feito besteira na hora de postar, caso ela apareça duas vezes favor ignorar a segunda.

Espero ter ajudado.


GOSTEI 0
Wdrocha

Wdrocha

08/09/2008

Estou criando da seguinte maneira...

//******************************************************************************
Procedure CriaBotao ();
  Begin

     With FrmConfiguracaoEmail Do

        Begin

           AjustaBotao(BtConcluir, 154, 146, 75, 40, ´Concluir´);

           BtConcluir.OnClick := BtConcluirClick;

           AjustaBotao(BtCancelar, 241, 146, 75, 40, ´Cancelar´);

           BtCancelar.OnClick := BtCancelarClick;

           AjustaBotao(BtServidor, 388, 146, 75, 40, ´Servidor +´);

           BtServidor.OnClick := BtServidorClick;

        End;

  End;
//******************************************************************************
Procedure AjustaLabel (Var Lb : TLabel; ALeft, ATop, AWidth, AHeigth : Integer; Caption : String);
  Begin

     Lb := TLabel.Create(FrmConfiguracaoEmail);

     Lb.Parent := FrmConfiguracaoEmail;

     Lb.Transparent := True;

     Lb.Caption := Caption;

     Lb.SetBounds(ALeft, ATop, AWidth, AHeigth);

     Lb.Font.Size := 12;

     Lb.Font.Name := ´Arial´;

     Lb.Font.Style := [fsBold];

  End;
//******************************************************************************
Procedure CriaLabel();
  Begin

     With FrmConfiguracaoEmail Do

        Begin

           AjustaLabel(LbUsuario, 7, 39, 139, 19, ´Usuário´);

           AjustaLabel(LbSenha, 6, 90, 55, 19, ´Senha´);

           AjustaLabel(LbRemetente, 242, 37, 163, 19, ´Email do Remetente´);

           AjustaLabel(LbServidor, 242, 89, 173, 19, ´Endereço do Servidor´);

        End;
  End;



Obrigado pela ajuda....na hora da criação não acontece erro algum....essas procedures ele cria os componentes....


Será q tem algum erro??


GOSTEI 0
Wdrocha

Wdrocha

08/09/2008

Já ia esquecendo...
os componentes são : TLabel, TButton, TComboBox e TEdit.



Vlw


GOSTEI 0
Adoniram

Adoniram

08/09/2008

acho que é desnecessária a rotina de destruição, visto que no construtor vc passa o form como Owner.
Só uma dica, remove o var que está antes da variavel do componente, pois como é um componente não precisa ser um parametro variável, ou seja de
Procedure AjustaLabel (Var Lb : TLabel; ALeft, ATop, AWidth, AHeigth : Integer; Caption : String);

vai ficar

Procedure AjustaLabel (Lb : TLabel; ALeft, ATop, AWidth, AHeigth : Integer; Caption : String);


GOSTEI 0
Wdrocha

Wdrocha

08/09/2008

Deixa eu explicar melhor....

Eu preciso destruir pq eu preciso criar outros componentes na tela.....

E depois q eu não precisar mais dos componentes q eu criar....quero destruir e recriar os que foram destruídos anteriormente....



Por isso preciso destruir os componentes criados...E qto ao Var na procedure eu os componentes precisam ter referência na memória para q eu possa criá-los, caso contrário da erro....


Já tentei tirar o var.....e dá erro..

Vlw


GOSTEI 0
Adoniram

Adoniram

08/09/2008

Entendi.
Peguei o seu código e criei uma aplicação com ele. Funcionou perfeitamente. Dá uma olhada e vê se existe algo de diferente.
Eu estou usando Delphi 7 com service pack 1.

Desculpe quetionar assim já que eu não sei o objetivo da aplicação, mas pq vc não utiliza um PageControl, um notebook ou panels ao invés de criar e destruir componentes em runtime?

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
     LbUsuario,
     LbSenha,
     LbRemetente,
     LbServidor : Tlabel;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
//******************************************************************************
Procedure AjustaLabel (Lb : TLabel; ALeft, ATop, AWidth, AHeigth : Integer; Caption : String);
  Begin

     Lb := TLabel.Create(Form1);

     Lb.Parent := Form1;

     Lb.Transparent := True;

     Lb.Caption := Caption;

     Lb.SetBounds(ALeft, ATop, AWidth, AHeigth);

     Lb.Font.Size := 12;

     Lb.Font.Name := ´Arial´;

     Lb.Font.Style := [fsBold];

  End;
//******************************************************************************
Procedure CriaLabel();
  Begin

     With Form1 Do

        Begin

           AjustaLabel(LbUsuario, 7, 39, 139, 19, ´Usuário´);

           AjustaLabel(LbSenha, 6, 90, 55, 19, ´Senha´);

           AjustaLabel(LbRemetente, 242, 37, 163, 19, ´Email do Remetente´);

           AjustaLabel(LbServidor, 242, 89, 173, 19, ´Endereço do Servidor´);

        End;
  End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CriaLabel();
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  I:Integer;
begin
  for I := Componentcount-1 downto 0 do
    if (Components[I] is Tlabel)then
      Components[I].Free;
end;



GOSTEI 0
Wdrocha

Wdrocha

08/09/2008

Eu tow usando o Vista Ultimate....


Não uso PageControl, um notebook ou panels pq é uma aplicação para deficientes físicos.....e tem q ser o mais simples possível.....com o mínimo de cliques....e evitar cliques em lugares mt pequenos como abas....


Vou testar pra ver se encontro o erro aq...

se eu fizer assim no onclick do botão q chama estas procedures dá certo...

     CriaNovosComponentes();

     DestroyComponentes;

     CriaNovosComponentes();



Não imagino o q deve estar acontecendo....mas vou continuar procurando pq isso aew...fiz só pra testar....e é uma gambiarra.....rsrs

não quero deixar assim....

Vlw...


GOSTEI 0
Adoniram

Adoniram

08/09/2008

Onde vc está chamando essa rotina para destruir os componentes?


GOSTEI 0
Wdrocha

Wdrocha

08/09/2008

No Onclick do botão responsável por criar os novos componentes e destruir os atuais....

segue o código
//******************************************************************************
Procedure DestroyComponentes();

Var I : Integer;

  Begin

     With FrmConfiguracaoEmail Do

        Begin

           For I := ComponentCount - 1 Downto 0 Do

              If (Components[I] Is TLabel) Or (Components[I] Is TEdit) Or (Components[I] Is TComboBox) Or (Components[I] Is TButton) Then

                  Components[I].Free;

        End;

  End;
//******************************************************************************

Destrói label, edit e combobox q foram criado no onCreate do Form....

E tbm é chamada a seguinte procedure...

//******************************************************************************
Procedure CriaNovosComponentes();
  Begin

     With FrmConfiguracaoEmail Do

        Begin

           AjustaLabel(LbServidor, 6, 15, 139, 19, ´Servidor´);

           AjustaLabel(LbEnderecoServidor, 6, 72, 55, 19, ´Endereco´);

           AjustaBotao(BtConcluir, 154, 146, 75, 40, ´Concluir´);

           BtConcluir.OnClick := ConcluirServidor;

           AjustaBotao(BtCancelar, 241, 146, 75, 40, ´Cancelar´);

           BtCancelar.OnClick := CancelarServidor;

           AjustaEdit(EdServidor, 6, 33, 300, 27);

           AjustaEdit(EdEndereco, 6, 90, 300, 27);

        End;

  End;
//******************************************************************************


E no OnClick do botão para destruir os componentes atuais e criar os novos..

//******************************************************************************
Procedure TFrmConfiguracaoEmail.BtServidorClick(Sender: TObject);
  Begin

     DestroyComponentes;

     CriaNovosComponentes();

  End;
//******************************************************************************



Vlw...


GOSTEI 0
Adoniram

Adoniram

08/09/2008

Joguei o seu código aqui e funcionou direitinho.
faz o seguinte, se puder, manda o fonte dessa tela (form + pas) para adonirammedeiros@yahoo.com.br.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons;

type
  TFrmConfiguracaoEmail = class(TForm)
    BitBtn1: TBitBtn;
    procedure btnServidorClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }

    LbUsuario,
    LbSenha,
    LbRemetente,
    LbServidor,
    LbEnderecoServidor:TLabel;

    BtConcluir,
    BtCancelar: TButton;

    EdServidor,
    EdEndereco :TEdit;



  public
    { Public declarations }
  end;

var
  FrmConfiguracaoEmail: TFrmConfiguracaoEmail;

implementation

{$R *.dfm}

//******************************************************************************
Procedure AjustaBotao (Lb : Tbutton; ALeft, ATop, AWidth, AHeigth : Integer; Caption : String);
  Begin

     Lb := TButton.Create(FrmConfiguracaoEmail);

     Lb.Parent := FrmConfiguracaoEmail;

     Lb.Caption := Caption;

     Lb.SetBounds(ALeft, ATop, AWidth, AHeigth);

     Lb.Font.Size := 12;

     Lb.Font.Name := ´Arial´;

     Lb.Font.Style := [fsBold];

  End;
//******************************************************************************
Procedure AjustaEdit (Lb : TEdit; ALeft, ATop, AWidth, AHeigth : Integer);
  Begin

     Lb := TEdit.Create(FrmConfiguracaoEmail);

     Lb.Parent := FrmConfiguracaoEmail;

     Lb.SetBounds(ALeft, ATop, AWidth, AHeigth);

     Lb.Font.Size := 12;

     Lb.Font.Name := ´Arial´;

     Lb.Font.Style := [fsBold];

  End;
//******************************************************************************
Procedure AjustaLabel (Lb : TLabel; ALeft, ATop, AWidth, AHeigth : Integer; Caption : String);
  Begin

     Lb := TLabel.Create(FrmConfiguracaoEmail);

     Lb.Parent := FrmConfiguracaoEmail;

     Lb.Transparent := True;

     Lb.Caption := Caption;

     Lb.SetBounds(ALeft, ATop, AWidth, AHeigth);

     Lb.Font.Size := 12;

     Lb.Font.Name := ´Arial´;

     Lb.Font.Style := [fsBold];

  End;
//******************************************************************************
Procedure CriaLabel();
  Begin

     With FrmConfiguracaoEmail Do

        Begin

           AjustaLabel(LbUsuario, 7, 39, 139, 19, ´Usuário´);

           AjustaLabel(LbSenha, 6, 90, 55, 19, ´Senha´);

           AjustaLabel(LbRemetente, 242, 37, 163, 19, ´Email do Remetente´);

           AjustaLabel(LbServidor, 242, 89, 173, 19, ´Endereço do Servidor´);

        End;
  End;



//******************************************************************************
Procedure CriaNovosComponentes();
  Begin

     With FrmConfiguracaoEmail Do

        Begin

           AjustaLabel(LbServidor, 6, 15, 139, 19, ´Servidor´);

           AjustaLabel(LbEnderecoServidor, 6, 72, 55, 19, ´Endereco´);

           AjustaBotao(BtConcluir, 154, 146, 75, 40, ´Concluir´);

           AjustaBotao(BtCancelar, 241, 146, 75, 40, ´Cancelar´);

           AjustaEdit(EdServidor, 6, 33, 300, 27);

           AjustaEdit(EdEndereco, 6, 90, 300, 27);

        End;

  End;
//******************************************************************************
Procedure DestroyComponentes();

Var I : Integer;

  Begin

     With FrmConfiguracaoEmail Do

        Begin

           For I := ComponentCount - 1 Downto 0 Do

              If (Components[I] Is TLabel) Or (Components[I] Is TEdit) Or (Components[I] Is TComboBox) Or (Components[I] Is TButton)
              and (Components[I] <> BitBtn1) Then

                  Components[I].Free;

        End;

  End;
//******************************************************************************


procedure TFrmConfiguracaoEmail.btnServidorClick(Sender: TObject);
begin
  CriaNovosComponentes();
  DestroyComponentes;
  CriaNovosComponentes();
end;


procedure TFrmConfiguracaoEmail.FormCreate(Sender: TObject);
begin
  CriaNovosComponentes();
end;

end.
[/code]


GOSTEI 0
Wdrocha

Wdrocha

08/09/2008

obrigado...

Já enviei para o seu email....


Vlw


GOSTEI 0
POSTAR