Fórum Destruir componentes #363573

08/09/2008

0

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

Responder

Posts

08/09/2008

Adoniram

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.


Responder

Gostei + 0

08/09/2008

Wdrocha

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??


Responder

Gostei + 0

08/09/2008

Wdrocha

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



Vlw


Responder

Gostei + 0

08/09/2008

Adoniram

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);


Responder

Gostei + 0

08/09/2008

Wdrocha

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


Responder

Gostei + 0

08/09/2008

Adoniram

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;



Responder

Gostei + 0

08/09/2008

Wdrocha

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...


Responder

Gostei + 0

08/09/2008

Adoniram

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


Responder

Gostei + 0

08/09/2008

Wdrocha

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...


Responder

Gostei + 0

08/09/2008

Adoniram

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]


Responder

Gostei + 0

08/09/2008

Wdrocha

obrigado...

Já enviei para o seu email....


Vlw


Responder

Gostei + 0

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

Aceitar