Excluir componentes!

Delphi

04/09/2005

Amigos, tenho uma aplicação que cria alguns label´s em tempo de execução. Criei um botão que exclui todas Label´s criadas com o seguinte código:
procedure TForm1.SpeedButton2Click(Sender: TObject);
var
iCont:integer;
begin
  for iCont:=0 to Panel3.ControlCount-1 do
    if Panel3.Controls[iCont] is Tlabel then
        Tlabel(panel3.Controls[iCont]).destroy;

end;

O Problema é que se eu crio apenas uma label, ela é excluida sem problemas! Porém quando crio mais de uma da um erro de Access Violation!

Oque será?


Caezar

Caezar

Curtidas 0

Respostas

Marco Salles

Marco Salles

04/09/2005

Oque será?


Problema como o Indice , Pois ICont No For esta sempre crescendo e a mediada que voce esta destruindo Componentes Panel1.Controls[iCont]
Este em sentido Oposto , isto é diminuindo
Voce tem que criar uma lógica para evitar que se faça acesso a Panel1.Controls[iCont] que não existe mais

[b:09a5a4fe01]Talves resolva...[/b:09a5a4fe01]

procedure TForm1.Button1Click(Sender: TObject);
var
iCont:integer;
fim:Integer;
begin
Fim:=Panel1.ControlCount;
iCont:=0;
  While  iCont <= (Fim-1) do
    begin
      if Panel1.Controls[iCont] is Tlabel then
        begin
          Tlabel(panel1.Controls[iCont]).destroy;
          Fim:=Fim-1;
        end
      else
       iCont:=iCont+1;
    end;
end;



GOSTEI 0
Caezar

Caezar

04/09/2005

Perfeito!!!!
Não tinha pensado que o número de componentes estava diminuindo!
Obrigado.
Se você não se incomoda tenho uma outra duvida:
Nessa minha aplicação que crial Label´s em tempo de execução com esse código:
procedure TForm1.Image1Click(Sender: TObject);
var
slabel:TLabel;

begin
 iNome:=iNome + 1;
 slabel:=TLabel.Create(Application);
 slabel.Parent:=Panel3;
 slabel.Name:=´Pt´ + IntToStr(inome);
 slabel.Top:=pty;
 slabel.Left:=ptx;
 slabel.Font.Color:=clRed;
 slabel.Font.Style:=[fsBold];
 slabel.AutoSize:=True;
 slabel.Cursor:=crHandPoint;
 slabel.Transparent:=true;
 slabel.OnClick:= identLabel;
 slabel.PopupMenu:=PopupMenu1;
 CaptionLabel(slabel);
end;

O Top eo Left são definidos por variaveis que retomam a posição do ponteiro do mouse, e o evento Popmenu aponta para o PopupMenu1 onde adcionei dois botões um deles é o renomiar e nele coloquei o seguinte evento:
procedure TForm1.Renomiarponto1Click(Sender: TObject);
var
sRenome:String;
begin
 sRenome:=InputBox(´Ponto´,´Indentifique o Ponto.´,´´,);
 TLabel(sender).Caption:=sRenome;
end;

O Problema é que quando eu clico com o botão direito e aperto o botão renomiar, ele dá um erro de Access Violation.
Parece ele não está recuperando qual a Label que cliquei com o botão direito!

Obrigado amogos!


GOSTEI 0
Massuda

Massuda

04/09/2005

Perocrra a lista de controles de trás para frente...
procedure TForm1.SpeedButton2Click(Sender: TObject);
var
  iCont:integer;
begin
  for iCont:=Panel3.ControlCount-1 downto 0 do
    if Panel3.Controls[iCont] is Tlabel then
        Tlabel(panel3.Controls[iCont]).Free;
end;
O problema acontece porque a cada label excluído os controles seguintes a ele mudam de posição na lista.

Outro ponto... é recomendável usar Free ao invés de Destroy.


GOSTEI 0
Caezar

Caezar

04/09/2005

Obrigado aos dois!
Ambas as dicas deram certo!
E a respeito de minha outra dúvida mencionada a cima?
Alguma dica??


GOSTEI 0
Massuda

Massuda

04/09/2005

Parece ele não está recuperando qual a Label que cliquei com o botão direito!
O Sender que a procedure TForm1.Renomiarponto1Click recebe é o TMenuItem e não o TLabel.

Você vai ter que bolar outra forma de saber qual label foi clicado... agora não tenho nenhuma sugestão.


GOSTEI 0
Marco Salles

Marco Salles

04/09/2005

caezar escreveu: Parece ele não está recuperando qual a Label que cliquei com o botão direito! O Sender que a procedure TForm1.Renomiarponto1Click recebe é o TMenuItem e não o TLabel. Você vai ter que bolar outra forma de saber qual label foi clicado... agora não tenho nenhuma sugestão.


Obrigado aos dois! Ambas as dicas deram certo! E a respeito de minha outra dúvida mencionada a cima? Alguma dica??



type
  TForm1 = class(TForm)
   ..............................
    procedure AMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);

var
Indice:Integer;


var
slabel:TLabel;


procedure TForm1.AMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
 indice:=TLabel(sender).ComponentIndex;
end;



begin
 iNome:=iNome + 1;
 .....................................................
  slabel.OnMouseMove:=AMouseMove; //acrecente.. 
 //Acreditando que iNome Começe com zero ????? Ou crie outra variavel a
//para controlar isto
 slabel.ComponentIndex:=iNome-1;
end;


procedure TForm1.renomear1Click(Sender: TObject);
begin
Showmessage(inttostr(indice));
sRenome:=InputBox(´Ponto´,´Indentifique o Ponto.´,´´);
   TLabel(Panel1.Controls[indice]).Caption:=sRenome;

end;



GOSTEI 0
Caezar

Caezar

04/09/2005

Amigo,
Tentei o jeito que vc me explicou mas não deu certo!
Então baseado na sua idéia fiz o seguinte:

implementation

{$R *.dfm}
var
sLabel:TLabel;


begin 
 iNome:=iNome + 1; 
 ..................................................... 
  slabel.OnMouseMove:=AMouseMove; //acrecente.. 
 //Acreditando que iNome Começe com zero ????? Ou crie outra variavel a 
//para controlar isto 
 slabel.ComponentIndex:=iNome-1; 
end;


procedure TForm1.AMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  sLabel:=TLabel(sender);
end;


procedure TForm1.RenomiarExecute(Sender: TObject);
var
sRenome:String;
begin
  sRenome:=InputBox(´Ponto´,´Indentifique o Ponto.´,´´,);
  TLabel(sLabel).Caption:=sRenome;
end;



GOSTEI 0
Marco Salles

Marco Salles

04/09/2005

Amigo, Tentei o jeito que vc me explicou mas não deu certo!


[b:8daeb40556]Tenho conficção absoluta que da certo sim[/b:8daeb40556]

[b:8daeb40556]Então baseado na sua idéia fiz o seguinte[/b:8daeb40556]:


Código: 
implementation 

{$R *.dfm} 
var 
sLabel:TLabel; 


Código: 
begin 
 iNome:=iNome + 1; 
 ..................................................... 
  slabel.OnMouseMove:=AMouseMove; //acrecente.. 
 //Acreditando que iNome Começe com zero ????? Ou crie outra variavel a 
//para controlar isto 
 slabel.ComponentIndex:=iNome-1; 
end; 


Código: 
procedure TForm1.AMouseMove(Sender: TObject; Shift: TShiftState; X, 
  Y: Integer); 
begin 
  sLabel:=TLabel(sender); 
end; 


Código: 
procedure TForm1.RenomiarExecute(Sender: TObject); 
var 
sRenome:String; 
begin 
  sRenome:=InputBox(´Ponto´,´Indentifique o Ponto.´,´´,); 
  TLabel(sLabel).Caption:=sRenome; 
end;


[b:8daeb40556]Também da certo...[/b:8daeb40556]

[b:8daeb40556]A idéia inicial Não deu certo para voce Com certeza devido a Isto :[/b:8daeb40556]

//Acreditando que iNome Começe com zero ????? Ou crie outra variavel a //para controlar isto slabel.ComponentIndex:=iNome-1;


Eu não sei qual o Valor inicial de sua variável Inome e nem Precisamente como ela se comporta em seu aplicativo...Eu Deveria ter criado outra variável independente para que slabel.ComponentIndex Recebesse esta variavel de controle independende...

Mas tudo bem , Da maneira que voce fez Também da certo , porque se baseia na idéia de :

Voc
ê vai ter que bolar outra forma de saber qual label foi clicado


E é isso a idéia que tentei te passar e pelo visto voce aprendeu rapidinho :lol: :lol: :lol:


GOSTEI 0
Caezar

Caezar

04/09/2005

Realmente faltou um pouco de lógica!
Obrigado pela ajuda!!!!!!!!!!!!!!!


GOSTEI 0
POSTAR