Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Error "A control cannot have itself as its parent" (https://www.clubdelphi.com/foros/showthread.php?t=90258)

leg128 05-05-2016 17:40:56

Error "A control cannot have itself as its parent"
 
Buenos dias, les comento... estoy tratando de crear objetos(botones, edit y demas cosas que se me ocurran) en una grilla.. cuando ejecuto el programa recibo este error al hacer la llamada a mi procedimiento
"A control cannot have itself as its parent"

la llamada es
Código:

  stgboton(1, StringGrid1, 'hola', EventoClick, 5 );
el procedimiento es este
Código:

procedure stgboton(objeto:integer; Grid : TStringGrid; txtcaption:string; evento:TNotifyEvent; columna:integer);
var
 i: Integer;
  Btn: TObject;

begin
 for i := Grid.FixedRows to Grid.RowCount -2 do
  begin
    if objeto = 1 then
    begin
    with TButton (btn) do
    begin
      Create(nil);
      Caption  := txtboton;
      Width    := 87;
      Name      := 'Button' + IntToStr(i);
      BoundsRect:= Grid.CellRect(Columna, i);
      ControlStyle := [csClickEvents];
      onclick    := evento;
      Tag      :=  i;
      parent:= grid;
    end;
    Grid.Objects[Columna,i] := Btn;

    end;
  end;
end;

Alguna idea de como puedo solucionarlo? saludos.

Caminante 05-05-2016 18:51:38

Hola
Porque pones TButton(btn)??? No veo que crees el objeto (btn) en ninguna parte.

AgustinOrtu 05-05-2016 19:09:29

No estas asignando ningun valor a la variable Btn, a la que luego le aplicas un casting a TButton usando el with

gatosoft 05-05-2016 20:53:03

De cualquier forma el no instanciar una variable generaría un Access Violation #000000... no un "A control cannot have itself as its parent"

Yo creo (no tengo compilador a la mano) que el problema está en la utilizacion del With (Ya nuestro amigo Al Gonzalez en algún hilo habló de su uso y abuso)

Asumo que al hacer el Create(nil); quieres asignarlo a tu btn... pues no funciona asi.

Código Delphi [-]
with TButton (btn) do
    begin
       Create(nil);
       Caption   := txtboton;
       Width     := 87;
       Name      := 'Button' + IntToStr(i);
       BoundsRect:= Grid.CellRect(Columna, i);
       ControlStyle := [csClickEvents];
       onclick    := evento;
       Tag       :=  i;
       parent:= grid;
    end;

La linea create dentro del with equivale a hacer:

Código Delphi [-]
TButton (btn).Create(nil);

instancia un objeto pero no lo asigna a la variable btn.

Lo que está ocurriendo es que dentro del with está asignando las variables a otro objeto, y segun parece, se está haciendo al StringGrid, de forma que en la linea parent:= grid, genera el error que te está enviando


Creo que deberias hacer algo como:

Código Delphi [-]
btn:= TButton.Create(nil);
with TButton (btn) do
    begin
       Caption   := txtboton;
       Width     := 87;
       Name      := 'Button' + IntToStr(i);
       BoundsRect:= Grid.CellRect(Columna, i);
       ControlStyle := [csClickEvents];
       onclick    := evento;
       Tag       :=  i;
       parent:= grid;
    end;

Saludo,

AgustinOrtu 05-05-2016 21:01:44

Cita:

De cualquier forma el no instanciar una variable generaría un Access Violation #000000... no un "A control cannot have itself as its parent"
Esto tiene truco, como descubri hace un tiempo

Es eso, o bien en esa ejecucion se presento esa oportunidad y btn podria apuntar a cualquier lado

ecfisa 06-05-2016 01:12:45

Cita:

Empezado por leg128 (Mensaje 504968)
Buenos dias, les comento... estoy tratando de crear objetos(botones, edit y demas cosas que se me ocurran) en una grilla...

...

Alguna idea de como puedo solucionarlo? saludos.

No miré a fondo tu código, pero en principio la forma de creación:
Código Delphi [-]
...
  with TButton (btn) do
  begin
    Create(nil);
    ...
es incorrecta, usando with podrías hacer:
Código Delphi [-]
  with TButton.Create(nil)  do
  ...
Por otro lado usar como el tipo de parámetro a la clase TObject va a limitar las propiedades disponibles y la totalidad de los eventos.

Te pongo un ejemplo usando un parámetro con otro tipo de clase que te va a permitir crear muchos controles (no los que se te ocurran :)), pero sí unos cuantos descendientes ella:
Código Delphi [-]
...
procedure TForm1.FormCreate(Sender: TObject);
var
  c : Integer;
  sg: TStringGrid;
begin
  sg := StringGrid1;
  sg.ColCount := 7;
  sg.FixedColor := clLime;
  for c := 0 to sg.ColCount-1 do
    sg.ColWidths[c] := 90;
end;

procedure TForm1.EventoClick(Sender: TObject);
begin
  ShowMessage(Format('Click en %s',[TWinControl(Sender).Name]));
end;


type
  TWinControlEx = class(TWinControl);

procedure TForm1.CrearWinControl(WcClass: TWinControlClass; Columna: Integer;
  Evento: TNotifyEvent);
var
  wc: TWinControl;
  sg: TStringGrid;
  r : Integer;
  Rect: TRect;
begin
  sg := StringGrid1;
  for r := sg.FixedRows to sg.RowCount-1 do
  begin
    if Assigned(sg.Objects[Columna,r]) then Continue;
    wc              := WcClass.Create(nil);
    wc.Name         := Format('%s%d',[Copy(WcClass.ClassName, 2, MaxInt), r]);
    Rect            := sg.CellRect(Columna, r);
    InflateRect(Rect, -2, -2);
    wc.BoundsRect   := Rect;
    wc.ControlStyle := [csClickEvents];
    TWinControlEx(wc).OnClick := Evento;
    TWinControlEx(wc).Caption := wc.Name;
    wc.Tag          := r;
    wc.Parent       := sg;
    sg.Objects[Columna, r] := wc;
  end;
end;

procedure TForm1.btnCreateClick(Sender: TObject);
begin
  CrearWinControl(TButton     , 1, EventoClick);
  CrearWinControl(TEdit       , 2, EventoClick);
  CrearWinControl(TMemo       , 3, EventoClick);
  CrearWinControl(TPanel      , 4, EventoClick);
  CrearWinControl(TCheckBox   , 5, EventoClick);
  CrearWinControl(TRadioButton, 6, EventoClick);
end;

procedure TForm1.btnFreeClick(Sender: TObject);
var
  sg  : TStringGrid;
  c, r: Integer;
begin
  sg := StringGrid1;
  for c := sg.FixedCols to sg.ColCount - 1 do
    for r := sg.FixedRows to sg.RowCount - 1 do
      if Assigned(sg.Objects[c, r]) then
      begin
        sg.Objects[c,r].Free;
        sg.Objects[c,r] := nil;
      end;
end;

Salida:


Saludos :)

leg128 06-05-2016 01:45:11

Muchas gracias muchachos, tengo ganas de llorar de la emoción! :D :D El ejemplo de ecfisa y la correccion de [gatosoft] funcionaron de 10...Gracias
Saludos


La franja horaria es GMT +2. Ahora son las 16:54:52.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi