Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Localizar controles creados en runtime (https://www.clubdelphi.com/foros/showthread.php?t=51193)

salvica 07-12-2007 21:39:30

Localizar controles creados en runtime
 
Hola a tod@s
Recurro al foro por aquello de que 2000 ojos ven más que dos (miopes por cierto) ;)

Tengo un form con la siguiente estructura:
Código Delphi [-]
Form
  |
  | ( controles creados en tiempo de diseño )
  |
  + Panel_DATOS_00
  |      |
  |      + Panel_HORA_00
  |      + ESBFloatEdit_T_SECO_00
  |      + ESBFloatEdit_T_HUMEDO_00
  |      + ESBPosEdit_HUMEDAD_00
  |
  | ( controles creados en tiempo de ejecución, del 01 al 24 )
  |
  + Panel_DATOS_01
  |      |
  |      + Panel_HORA_01
  |      + ESBFloatEdit_T_SECO_01
  |      + ESBFloatEdit_T_HUMEDO_01
  |      + ESBPosEdit_HUMEDAD_01
  |
  + Panel_DATOS_02
  |      |
  |      + Panel_HORA_02
  |      + ESBFloatEdit_T_SECO_02
  |      + ESBFloatEdit_T_HUMEDO_02
  |      + ESBPosEdit_HUMEDAD_02
 ...
  |
  + Panel_DATOS_24
         |
         + Panel_HORA_24
         + ESBFloatEdit_T_SECO_24
         + ESBFloatEdit_T_HUMEDO_24
         + ESBPosEdit_HUMEDAD_24
Los controles "cero-cero" los creo en diseño, y los controles "cero-uno" a "dos-cuatro" en tiempo de ejecución, exactamente en el evento OnCreate del form.

Bien, hasta aquí no hay problema.
El problema se presenta cuando quiero rellenar los controles desde los datos almacenados en una tabla, para ello tengo la siguiente función:
Código Delphi [-]

procedure TForm_Garita.MYSQL_PasarDatosAControles;
const
  strTabla = 'partes_garita';
var
  Panel_DATOS           : TPanel;
  ESBFloatEdit_T_SECO   : TESBFloatEdit;
  ESBFloatEdit_T_HUMEDO : TESBFloatEdit;
  ESBPosEdit_HUMEDAD    : TESBPosEdit;
  numHora  : integer;
  strHora  : string;
  strClave : string;
begin
{ preparar la clave del registro buscado }
  strClave := FormatDateTime('yyyymmdd', FECHA_GARITA);
  with ZQuery do begin
     { viene preparada de Form_Main }
       SQL.Clear;
       SQL.Add( 'SELECT * ' );
       SQL.Add( '  FROM ' + strTabla );
       SQL.Add( ' WHERE clave="' + strClave + '"' );
     { abrir la tabla activa }
       Open;
       if not IsEmpty then begin
        { el registro existe }
          for numHora:=0 to 24 do begin
            { para cada hora, buscar los controles }
              strHora               := IntToCadena( numHora, 2 );
              Panel_DATOS           := FindComponent('Panel_DATOS_'          +strHora) as TPanel;
              ESBFloatEdit_T_SECO   := FindComponent('ESBFloatEdit_T_SECO_'  +strHora) as TESBFloatEdit;
              ESBFloatEdit_T_HUMEDO := FindComponent('ESBFloatEdit_T_HUMEDO_'+strHora) as TESBFloatEdit;
              ESBPosEdit_HUMEDAD    := FindComponent('ESBPosEdit_HUMEDAD_'   +strHora) as TESBPosEdit;
              if( Panel_DATOS<>nil ) then begin
                { el contenedor existe y se encuentra }
                  if( ESBFloatEdit_T_SECO<>nil ) then begin
                    { el control existe y se encuentra, rellenarlo }
                      ESBFloatEdit_T_SECO.AsFloat         := FieldByName( 'TS_'+strHora ).AsFloat;
                      ESBFloatEdit_T_SECO.BlankWhenZero   := FieldByName( 'TS_'+strHora ).IsNull;
                      ESBFloatEdit_T_HUMEDO.AsFloat       := FieldByName( 'TH_'+strHora ).AsFloat;
                      ESBFloatEdit_T_HUMEDO.BlankWhenZero := FieldByName( 'TH_'+strHora ).IsNull;
                      ESBPosEdit_HUMEDAD.AsInteger        := FieldByName( 'HU_'+strHora ).AsInteger;
                      ESBPosEdit_HUMEDAD.BlankWhenZero    := FieldByName( 'HU_'+strHora ).IsNull;
                  end;
              end;
          end;
       end;
     { cerrar la tabla activa }
       Close;
  end; { del with Query do }
{}
end;
no se porqué no me localiza los controles creados y aparecen en blanco.

He probado a anteponer a FindComponent el nombre del form, self, o el contenedor (Panel_DATOS) y lo máximo que he conseguido ha sido que me cargue los controles creados en diseño, el resto siguen en "el limbo"

Para verificar los nombres, he añadido el evento OnMouseMove para que muestre los nombres de los controles y lo hace perfectamente
Código Delphi [-]
procedure TForm_Garita.TODOS_OnMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  if( Sender is TPanel )
      then Form_Comun.Panel_SUPERIOR.Caption := TPanel(Sender).Name
      else if( Sender is TESBFloatEdit )
               then Form_Comun.Panel_SUPERIOR.Caption := TESBFloatEdit(Sender).Name
               else if( Sender is TESBPosEdit )
                        then Form_Comun.Panel_SUPERIOR.Caption := TESBPosEdit(Sender).Name
                        else Form_Comun.Panel_SUPERIOR.Caption := '*** DESCONOCIDO***';
end;
¿alguna idea?

Gracias de antemano
salvica

fjcg02 07-12-2007 23:23:11

Cita:

Empezado por salvica (Mensaje 251256)
He probado a anteponer a FindComponent el nombre del form, self, o el contenedor (Panel_DATOS) y lo máximo que he conseguido ha sido que me cargue los controles creados en diseño, el resto siguen en "el limbo"

Por cierto, cuando creas los componentes, pones el parent, que sea el form donde los pones ?

Prueba y cuentanos. Pon parte del código que crea los paneles.

Saludos

salvica 08-12-2007 11:19:31

Hola fjcg02, gracias por contestar
Cita:

Empezado por fjcg02 (Mensaje 251277)
Por cierto, cuando creas los componentes, pones el parent, que sea el form donde los pones ?

Prueba y cuentanos. Pon parte del código que crea los paneles.

Saludos

El código de creación de los controles es el siguiente:
Código Delphi [-]
  repeat
  { crear el contenedor de datos horarios }
    Panel_DATOS := TPanel.Create(Form_Garita);
    with Panel_DATOS do begin
         Parent      := Panel_DATOS_00.Parent;
         ... resto de configuración del control
         OnMouseMove := TODOS_OnMouseMove;
    end;
  { crear el visualizador de la hora del dato }
    Panel_HORA  := TPanel.Create(Form_Garita);
    with Panel_HORA do begin
         Parent      := Panel_DATOS;
         ... resto de configuración del control
         OnMouseMove := TODOS_OnMouseMove;
    end;
    ESBFloatEdit_T_SECO     := TESBFloatEdit.Create(Form_Garita);
    with ESBFloatEdit_T_SECO do begin
         Parent             := Panel_DATOS;
         ... resto de configuración del control
         OnEnter            := TODOS_OnEnter;
         OnExit             := TODOS_OnExit;
         OnKeyPress         := ESBFloatEdit_T_SECO_OnKeyPress;
         OnMouseMove        := TODOS_OnMouseMove;
    end;
    ESBFloatEdit_T_HUMEDO   := TESBFloatEdit.Create(Form_Garita);
    with ESBFloatEdit_T_HUMEDO do begin
         Parent             := Panel_DATOS;
         ... resto de configuración del control
         OnEnter            := TODOS_OnEnter;
         OnExit             := TODOS_OnExit;
         OnKeyPress         := ESBFloatEdit_T_HUMEDO_OnKeyPress;
         OnMouseMove        := TODOS_OnMouseMove;
    end;
    ESBPosEdit_HUMEDAD      := TESBPosEdit.Create(Form_Garita);
    with ESBPosEdit_HUMEDAD do begin
         Parent             := Panel_DATOS;
         ... resto de configuración del control
         OnEnter            := TODOS_OnEnter;
         OnExit             := TODOS_OnExit;
         OnKeyPress         := ESBPosEdit_HUMEDAD_OnKeyPress;
         OnMouseMove        := TODOS_OnMouseMove;
    end;
    Inc( NumHora );
  until( NumHora>24 );

Saludos
salvica


jachguate 08-12-2007 11:35:47

Has omitido el código donde les asignas el nombre... así que supondré que los nombres están bien escritos; entonces la única razón por la que la función FindComponent no los encuentra es porque estás ejecutandola dentro del código de un componente que no es el owner de los objetos creados en tiempo de corrida, es decir... aquel apuntado por Form_Garita en el momento de crearlos.

Probablemente estás creando otra instancia de dicha clase y la confusión viene por allí.

Recomiendo que si el método que crea los controles es parte de la clase TForm_Garita, en lugar de usar la variable Form_Garita, uses la variable implicita Self.

Hasta luego.

;)

salvica 08-12-2007 11:59:18

Hola jachguate
Cita:

Empezado por jachguate (Mensaje 251332)
Has omitido el código donde les asignas el nombre... así que supondré que los nombres están bien escritos; entonces la única razón por la que la función FindComponent no los encuentra es porque estás ejecutandola dentro del código de un componente que no es el owner de los objetos creados en tiempo de corrida, es decir... aquel apuntado por Form_Garita en el momento de crearlos.

Probablemente estás creando otra instancia de dicha clase y la confusión viene por allí.

Recomiendo que si el método que crea los controles es parte de la clase TForm_Garita, en lugar de usar la variable Form_Garita, uses la variable implicita Self.

Hasta luego.

;)

Si, los nombres están bien escritos (por lo menos en el evento OnMouseMove aparecen bien), probaré cambiar Form_Garita por Self y ya contaré
Saludos
Salvica

salvica 08-12-2007 12:12:40

Perdona jachguate, me preguntabas el "donde los creo" y se me pasó, los creo en el evento OnCreate del form y los cargo desde el procedimiento de más arriba que llamo desde el evento OnShow del mismo form
Saludos
salvica

jachguate 08-12-2007 12:58:11

Bien, si es así, podes (y debés) usar Self como owner.

Hasta luego.

;)

salvica 08-12-2007 17:05:06

Cita:

Empezado por jachguate (Mensaje 251338)
Bien, si es así, podes (y debés) usar Self como owner.

Hasta luego.

;)

Gracias jachguate, exactamente con Self funciona como debe :rolleyes:

Generalmente, cuando hago cosas nuevas, sigo las indicaciones del libro Programación con Delphi 4 de Francisco Charte, pero esta vez pensaba que lo sabía :(, y el resultado han sido tres días perdidos.


Saludos
salvica


La franja horaria es GMT +2. Ahora son las 12:35:50.

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