Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 23-01-2007
SyncReuter SyncReuter is offline
Miembro
 
Registrado: ene 2007
Posts: 26
Poder: 0
SyncReuter Va por buen camino
Array de controles - Control has no parent window

Hola,

Alguien sabe cual es la forma correcta de definir un array de controles. Algo asi como:

Código Delphi [-]
LabD: array[1..8] of TLabel

Esa definición esta presente en protected de una clase X que deriva de TPanel. Ahora bien, en Create y Destroy tengo el siguiente codigo:

Create:

Código Delphi [-]
inherited Create(AOwner);
SetBounds(0, 0, cMCW, cMCH);
CreateObjects;

Destroy:

Código Delphi [-]
RemoveObjects;
inherited Destroy;

como podran notar en Create llamo a un procedimiento CreateObject que se encuentra declarado en Private dentro de la clase. El unico objectivo es crear los controles adiciones, que en este caso en particular son 8 etiquetas (TLabel). El codigo es el siguiente :

Código Delphi [-]
  x:=5;
  y:=21;
  for i:=1 to 8 do
    begin
      LabD[i]:=TLabel.Create(Self);
      with LabD[i] do
        begin
          Parent:=Self;
          AutoSize:=True;
          Caption:=CA_D[i];
          Alignment:=taCenter;
          Transparent:=True;
          ParentFont:=True;
          Width:=21;
          Height:=13;
          Top:=y;
          Left:=x;
          Inc(x, Width + 2);
        end;
    end;

En Destroy llamo a otro procedimiento RemoveObjects declarado tambien el Private que lo unico que hace es destruir los objectos que han sido creados.

Código Delphi [-]
var
  i: Integer;
begin
  for i:=8 downto 1 do
    begin
      LabD[i].Free;
      LabD[i]:=nil;
    end;
end;

Ahora bien...Cual es mi problema. Cuando intento pegar el componente dentro de la Form, delphito me lanza un cuadro de dialogo con lo siguiente :

Control has no parent window

El objetivo de usar array es unicamente para poder tratarlos por lotes los controles TLabel.

¿Alguien sabe a que se debe este problema?

Saludos desde Chile.
Responder Con Cita
  #2  
Antiguo 23-01-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Cita:
en protected de una clase X que deriva de TPanel.
Quizás el que no tiene Aowner es el propio panel en lugar de los labels...

Para el uso de controles... un TobjectList sería más cómodo.

Saludos.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #3  
Antiguo 23-01-2007
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Creo que el problema está en el procedimiento CreateObject, concretamente aquí:
Código Delphi [-]
      with LabD[i] do
Con el "with" estas dando a entender que utilice LabD[i], así que en la asignación que hay a continuación:
Código Delphi [-]
          Parent:=Self;
en realidad lo que estás haciendo es
Código Delphi [-]
          LabD[i].Parent := LabD[i].Self;
O puede que no, no lo he comprobado, pero es lo que se me ha ocurrido.

De todas formas, la sugerencia de utilizar un TObjectList es buena.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #4  
Antiguo 23-01-2007
SyncReuter SyncReuter is offline
Miembro
 
Registrado: ene 2007
Posts: 26
Poder: 0
SyncReuter Va por buen camino
Hola, bueno realice el cambio en el codigo para probar, las lineas me quedaron asi:

Código Delphi [-]
x:=5;
  y:=21;
  for i:=1 to 7 do
    begin
      LabD[i]:=TLabel.Create(Self);
      LabD[i].Parent:=Self;
      LabD[i].AutoSize:=True;
      LabD[i].Caption:=CA_D[i];
      LabD[i].Alignment:=taCenter;
      LabD[i].Transparent:=True;
      LabD[i].ParentFont:=True;
      LabD[i].Width:=21;
      LabD[i].Height:=13;
      LabD[i].Top:=y;
      LabD[i].Left:=x;
      x:=x + LabD[i].Width + 2;
    end;

Lo compile y lo volvi a colocar dentro de la Form obteniendo el mismo resultado "Control has no parent window" . Tengo que decir ademas, que tengo 4 botones definidos en un array cuya creacion no da problemas. con el codigo:

Código Delphi [-]
x:=3;
  for i:=1 to 4 do
    begin
      BtnNave[i]:=TPrcBtnNave.Create(Self);
      with BtnNave[i] do
        begin
          Parent:=Self;
          Width:=15;
          Height:=15;
          Top:=3;
          //with ArrowOptions do
            begin
              case i of
                1: begin
                     Left:=x;
                     inc(x, Width + 1);
                     BtnNaveType:=bntPYear;
                   end;
                2: begin
                     Left:=x;
                     x:=cMCW - Width - 3;
                     BtnNaveType:=bntPMonth;
                   end;
                3: begin
                     Left:=x;
                     Dec(x, Width + 1);
                     BtnNaveType:=bntNYear
                   end;
                4: begin
                     Left:=x;
                     BtnNaveType:=bntNMonth;
                   end;
                end;
              //PosArrow:=paCenter;
              //ShowArrow:=True;
            end;

          Tag:=i;
          OnClick:=BtnNaveClick;
        end;
    end;

me tiene loco este maldito problema. Ya llevo mas de 5 horas cascandome la cabeza, la clase la hago una y otra vez obteniendo el mismo resultado.

Estoy usando Delphi 2005 Professional con el Update3

A todo esto de que forma trabaja TObjectList?

Gracias por su tiempo, saludos
Responder Con Cita
  #5  
Antiguo 23-01-2007
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Yo creo que hay algo de código que no nos pones y que es el causante del error.

Ahora bien, ya te han dicho que posiblemente quien se queja de no tener padre sea el panel y no las etiquetas. Puedes salir de dudas asignando la propiedad Name, tanto del panel como de las etiquetas y demás controles que crees, al principio del constructor, inmediatamente después de inherited. De esa forma, el mensaje de error dirá el nombre de la componente que da el problema.

Por otra parte puedes hacer una depuración del código de tu componente. Intenta primero crear una componente en tiempo de ejecución y mira si te da el mismo error; así sabrás exactamente en qué línea se produce.

Si eso no da resultado entonces el error sólo se produce en tiempo de diseño, lo cual hace un poco más difícil la depuración, pero puede hacerse.



Ahora, cambiando un poco de tema. Self no es una propiedad, sino un parámetro (escondido) que se pasa a cualquier método de un objeto, de manera que lo que se indica del with, no aplica. Self siempre será el objeto al que pertenece el método.

Finalmente, si el número de etiquetas es fijo, yo no me complicaría usando un TObjectList; te hará más difícil la escritura al tener que hacer moldeos de tipo para ajustar las propiedades de sus elementos.

// Saludos
Responder Con Cita
  #6  
Antiguo 24-01-2007
[basti] basti is offline
Miembro Premium
 
Registrado: ago 2004
Posts: 388
Poder: 20
basti Va por buen camino
Como bien te dijeron antes, el problema es que el panel no tiene Owner en el constructor.

Lo que puedes hacer es quitar la creación de etiquetas del Create.

Luego sobreescribes el método Loaded:
Código Delphi [-]

  protected:
     procedure Loaded; override;

.
.
.
procedure TControlNuevo.Loaded;
begin
  CreateObjects;
end;

Loaded se ejecuta cuando el componente ya está creado e insertado en el Form, así ya tiene Owner.
Responder Con Cita
  #7  
Antiguo 24-01-2007
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Yo no estaría tan seguro de que ese sea el problema, pues yo hice la prueba y no pude reproducir el error. Pero por otra parte, el error se produce cuando se hace una operación que requiere que la ventana del padre ya esté creada. Por ello el método más adecuado sería CreateWnd y no Loaded.

// Saludos
Responder Con Cita
  #8  
Antiguo 24-01-2007
SyncReuter SyncReuter is offline
Miembro
 
Registrado: ene 2007
Posts: 26
Poder: 0
SyncReuter Va por buen camino
Hola nuevamente,

Gracias por responder tan pronto, les cuento lo siguiente: De lo que realmente estamos seguro aca es que el error sale unicamente en tiempo de diseño. Por que? El componente que estoy creando se llama TPrcMonthCalendar y tengo otro componente que se llama TPrcDateEdit que es un TEdit con un boton insertado en el interior del control. Cuando el usuario hace clic en el botón la clase PrcMonthCalendar se visualiza sin problemas. El drama esta unicamente al momento de insertar el calendario dentro de la Form. ¿Se entiende?

Hare las pruebas pertinente con CreateWnd y Loaded. Es importante señalar que el drama es unicamente con los componentes TLabel NO asi con los botones de navegacion (PriorMonth, PriorYear.....etc) y los botones de control del calendario (BtnOK, BtnCancel) y por supuesto los botones correspondientes a los dias del mes.

Ahora me pondre manos a la obra y colocar la llamada CreateObjects en CreateWnd o Loaded.

Muchas gracias por su tiempo, saludos
Responder Con Cita
  #9  
Antiguo 24-01-2007
SyncReuter SyncReuter is offline
Miembro
 
Registrado: ene 2007
Posts: 26
Poder: 0
SyncReuter Va por buen camino
Bueno aqui estamos de nuevo. Les cuesto. Agrege el siguiente procedimiento a la clase en la sección protected

Código Delphi [-]
Procedure CreateWnd; Override;

con el siguiente codigo:

Código Delphi [-]
procedure TPrcMonthCalendar.CreateWnd;
begin
  inherited;
  AjustWH;
  CreateObjects;
end;

...Las etiquetas se crearon de la siguiente forma:

Código Delphi [-]
x:=5;
  y:=21;

  for i:=1 to 7 do
    begin
      FLabD[i]:=TLabel.Create(Self);
      with FLabD[i] do
        begin
          Name:='Lab'+IntToStr(i);
          FLabD[i].Parent:=Self;
          Caption:=CA_D[i];
          AutoSize:=True;
          Alignment:=taCenter;
          Transparent:=True;
          Left:=x;
          Top:=y;
          Width:=21;
          Height:=13;
          inc(x, Width + 2);
        end;
    end;

Ahora todo funciona a la perfección . Para terminar debo señalar lo siguiente. Al momento de alterar las propiedades de las etiquetas y botones internos del componente se producia un error grave en delphi, observando la clase completamente me doy cuenta que tenia un procedimiento dentro de Paint que alteraba las propiedades de las etiquetas y botones la cual es necesario para el cambio de estilo del calendario, entonces...para alterar las propiedades (utilizando For... para recorrer el array) coloque una bifurcación if..then preguntando si el elemento contenido en el array era <> a nil... como lo indico en la fracción de codigo:

Código Delphi [-]
for i:=1 to 42 do
    if FBtnD[i]<>nil then
      with FBtnD[i] do
        begin
          GetBtnStateData(TD_MONTHCALENDAR_DM_NORMAL_BSTATE, StateNormal);
          GetBtnStateData(TD_MONTHCALENDAR_DM_FOCUS_BSTATE, StateFocus);
          GetBtnStateData(TD_MONTHCALENDAR_DM_DISABLED_BSTATE, StateDisabled);
          GetBtnStateData(TD_MONTHCALENDAR_DM_DOWN_BSTATE, StateDown);
        end;

...con ello ahora el control se puede colocar dentro de la form sin causar problema alguno...al = que al momento de quitarlo.

La destrucción de los controles internos se genero justo antes de ejecutar el inherited Destroy;



Bueno no me queda mas que AGRADECER a cada uno de ustedes por sus lineas. Desde Chile reciban un gran abrazo.

GRACIAS!!!
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
error con el parent window antonio peña Varios 1 04-10-2006 11:18:50
QReport has no parent window david duarte Impresión 1 19-01-2006 16:06:07
Ayuda: Control Has No Parent Window pelaorb68 Varios 10 20-12-2005 21:36:26
Como Asignar Variable Tipo Array de Tform a otro Array del Mismo tipo morfeo21 Varios 5 17-08-2004 18:39:51
Opciones de Parent pepelu1975 OOP 7 26-05-2004 19:35:36


La franja horaria es GMT +2. Ahora son las 02:30:48.


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
Copyright 1996-2007 Club Delphi