Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-02-2004
glp1 glp1 is offline
Registrado
 
Registrado: feb 2004
Posts: 9
Poder: 0
glp1 Va por buen camino
Dudas con el funcionamiento del RegisterClasses en Delphi 6.0

Buenas...
Tengo un paquete de runtime con estas unidades...

unit uListadosInit;

interface

implementation

uses
Classes,
uLstUsuariosApp{frmLstUsuariosApp},
uLstAlfabetico{frmLstAlfabetico},
uLstAplicaciones{frmLstAplicaciones},
uLstAppUsuario{frmLstAppUsuario},
uLstEquipos{frmLstEquipos},
uLstEstructura{frmLstEstructura},
uLstEtiquetas{frmLstEtiquetas},
uLstFichaAplicacion{frmLstFichaAplicacion},
uLstInternet{frmLstInternet},
uLstNoFunciona{frmLstNoFunciona},
uLstUbicacion{frmLstUbicacion},
uMDInventario{dmInventario: TDataModule};

initialization

RegisterClasses([TfrmLstUsuariosApp,TfrmLstAlfabetico,TfrmLstAplicaciones,
TfrmLstAppUsuario,TfrmLstEquipos,TfrmLstEstructura,TfrmLstEtiquetas,
TfrmLstFichaAplicacion,TfrmLstInternet,TfrmLstNoFunciona,TfrmLstUbicacion]);

finalization

UnRegisterClasses([TfrmLstUsuariosApp,TfrmLstAlfabetico,TfrmLstAplicaciones,
TfrmLstAppUsuario,TfrmLstEquipos,TfrmLstEstructura,TfrmLstEtiquetas,
TfrmLstFichaAplicacion,TfrmLstInternet,TfrmLstNoFunciona,TfrmLstUbicacion]);

end.


Cuando intento buscar la clase TfrmLstAlfabetico en my app:

procedure TfrmInventario.mListadosAlfabeticoClick(Sender: TObject);
var
FChildForm: TForm;
AClass : TFormClass;
begin
result := nil;
FChildForm := TForm( Application.Mainform.FindComponent('uLstAlfabetico') );
if not Assigned(FChildForm) then
begin
AClass := TFormClass( GetClass('TfrmLstAlfabetico') );
if AClass <> nil then
begin
LockWindowUpdate(Application.MainForm.Handle);
...

La funcion getClass devuelve nil, parece como si el registerClasses no funcione pq el getClass 1º comprueba si esta registrada y entonces la obtiene, esto con delphi 5.0 funciona pero con delphi 6.0 ya no funciona o eso me parece, que es lo que me falta o hago mal?
Gracias, salu2...
Responder Con Cita
  #2  
Antiguo 25-02-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Yo probé este sencillo código en Delphi 6, y funciona sin problemas:
Código:
procedure TForm1.Button1Click(Sender: TObject);
var
  AClass: TPersistentClass;
begin
  AClass := GetClass('TForm1');
  if AClass <> Nil Then
    ShowMessage('AClass <> Nil');
end;

initialization
  RegisterClasses([TForm1]);

finalization
  UnRegisterClasses([TForm1]);

¿Estas usando alguna vez en el proyecto la unit que registra las clases?
¿Si pones un BreakPoint en la línea del RegisterClass se detiene ahí?
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #3  
Antiguo 25-02-2004
glp1 glp1 is offline
Registrado
 
Registrado: feb 2004
Posts: 9
Poder: 0
glp1 Va por buen camino
si.
si, se detiene pero no la encuentra, es codigo que funciona en Delphi 5, pero que al pasarlo a delphi 6 ya no me funciona, pero no se pq...?
Responder Con Cita
  #4  
Antiguo 25-02-2004
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
¿Te funciona el código que puse en este hilo?
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #5  
Antiguo 25-02-2004
glp1 glp1 is offline
Registrado
 
Registrado: feb 2004
Posts: 9
Poder: 0
glp1 Va por buen camino
si, funciona
Responder Con Cita
  #6  
Antiguo 26-02-2004
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Smile Cargar el paquete

¡Hola a todos!

Cita:
Empezado por glp1
...paquete de runtime...
RegisterClasses([TfrmLstUsuariosApp,TfrmLstAlfabetico...
Cuando intento buscar la clase TfrmLstAlfabetico en my app...La funcion getClass devuelve nil, parece como si el registerClasses no funcione pq el getClass 1º comprueba si esta registrada y entonces la obtiene...que es lo que me falta...?...
Quizás lo que te falta es que el paquete se cargue/instale, o bien hacer referencia en una claúsula Uses, a la unidad donde se encuentra la llamada a RegisterClasses.

Espero esto sea de utilidad. Seguimos en contacto.

Al González .
Responder Con Cita
  #7  
Antiguo 26-02-2004
glp1 glp1 is offline
Registrado
 
Registrado: feb 2004
Posts: 9
Poder: 0
glp1 Va por buen camino
Hola, tengo una unidad de inicializacion por cada paquete donde hago el RegisterClasses de todas las clases de las unidades que contiene ese paquete, por ahi pasa y aparentemente las registra, pero cuando hago el getClass de la unidad que quiero utilizar entonces me devuelve un nil (vamos como si no la hubiera registrado).
En la unidad de inicializacion , tengo en las uses todas las unidades de las clases que registro.
gracias
Responder Con Cita
  #8  
Antiguo 26-02-2004
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
Cita:
Empezado por glp1
Hola, tengo una unidad de inicializacion por cada paquete donde hago el RegisterClasses de todas las clases de las unidades que contiene ese paquete, por ahi pasa y aparentemente las registra, pero cuando hago el getClass de la unidad que quiero utilizar entonces me devuelve un nil (vamos como si no la hubiera registrado).
En la unidad de inicializacion , tengo en las uses todas las unidades de las clases que registro.
Pero la pregunta no es si tus unidades de inicialización incluyen las unidades de las clases. Esto se da por sentado ya que de lo contrario no compilaría tu aplicación. La pregunta es si éstas unidadas están en el uses de alguna otra unidad en tu proyecto.

Por otro lado, dices que el flujo de la aplicación sí pasa por el RegisterClasses pero el GetClass posterior falla. ¿Qué pasa si, para probar, usas un GetClass inmediatamente después del RegisterClasses:

Código:
RegisterClasses(...);
Assert(GetClass(una de tus clases) <> nil, '¡Es nil!');
// Saludos
Responder Con Cita
  #9  
Antiguo 27-02-2004
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Es decir...

¡Buen día a todos!

Complementando lo que nos dice Román.

Es decir, ¿estás seguro de que cuando se ejecuta tu programa, éste ejecuta las sentencias RegisterClasses que nos mencionas?

Una cosa es que los paquetes llamen a RegisterClasses, cuando son cargados por el entorno de Delphi. Y otra muy distinta, que la aplicación también llame a RegisterClasses cuando comienza a ejecutarse. Quizás ésto último no sucede.

De todas formas, me gustaría saber más sobre este caso.

Espero esto sea de utilidad. Seguimos en contacto.

Al González .
Responder Con Cita
  #10  
Antiguo 27-02-2004
glp1 glp1 is offline
Registrado
 
Registrado: feb 2004
Posts: 9
Poder: 0
glp1 Va por buen camino
Cita:
Empezado por roman
Pero la pregunta no es si tus unidades de inicialización incluyen las unidades de las clases. Esto se da por sentado ya que de lo contrario no compilaría tu aplicación. La pregunta es si éstas unidadas están en el uses de alguna otra unidad en tu proyecto.

Por otro lado, dices que el flujo de la aplicación sí pasa por el RegisterClasses pero el GetClass posterior falla. ¿Qué pasa si, para probar, usas un GetClass inmediatamente después del RegisterClasses:

Código:
RegisterClasses(...);
Assert(GetClass(una de tus clases) <> nil, '¡Es nil!');
// Saludos
Que sigue valiendo nil
Responder Con Cita
  #11  
Antiguo 27-02-2004
glp1 glp1 is offline
Registrado
 
Registrado: feb 2004
Posts: 9
Poder: 0
glp1 Va por buen camino
Cita:
Empezado por Al González
¡Buen día a todos!

Complementando lo que nos dice Román.

Es decir, ¿estás seguro de que cuando se ejecuta tu programa, éste ejecuta las sentencias RegisterClasses que nos mencionas?

Una cosa es que los paquetes llamen a RegisterClasses, cuando son cargados por el entorno de Delphi. Y otra muy distinta, que la aplicación también llame a RegisterClasses cuando comienza a ejecutarse. Quizás ésto último no sucede.

De todas formas, me gustaría saber más sobre este caso.

Espero esto sea de utilidad. Seguimos en contacto.

Al González .
La aplicacion llama al RegisterClasses cuando comienza a ejecutarse
Responder Con Cita
  #12  
Antiguo 27-02-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Creo que a lo que van roman y delphi.com.ar es a la posibilidad que el optimizador haya eliminado la llamada a registerclass en tu ejecutable, o bien que la unidad no esté incluida en el uses de ninguna otra, por lo que la clase no existirá en el proyecto...

Cómo estas seguro que eso no ha ocurrido?

Creo que facilmente podes hacer algo como lo indicado en el código sigiuente para tener un test completo:

Código:
Procedure TForm1.Button1Click(Sender : TObject);

Var
  Instancia : TClase;  
  {si esto compila estoy seguro que la unidad ha sido incluida en el uses }
  PunteroClase : TObjectClass;

Begin
  Instancia := TClass.Create(Parametros);
  Instancia.Free;  // para que el optimizador no quite la variable Instancia del camino...
  PunteroClase := GetClass('TClass')
  Assert(PunteroClase <> nil, '¡Es nil!');
  if PunteroClase = nil Then
  Begin
    // intentamos de nuevo registrar la clase, a ver que ocurre...
    RegisterClass(TClass);
    Assert(GetClass('TClass') <> nil, '¡Sigue siendo nil, RegisterClass ya no sirve!');
  End;
end;
Creo que podria ayudar a entender que ocurre...
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #13  
Antiguo 27-02-2004
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
jachguate:

Te darás cuenta de que el código

Código:
  if PunteroClase = nil Then
  Begin
    // intentamos de nuevo registrar la clase, a ver que ocurre...
    RegisterClass(TClass);
    Assert(GetClass('TClass') <> nil, '¡Sigue siendo nil, RegisterClass ya no sirve!');
  End;
jamás se va a ejecutar. No hay manera que se salte el Assert. A menos claro que tenga deshabilitado el uso de Assert.

Realmente este problema es muy extraño. La pregunta que le hice era tan sólo por no dejar pero si realmente GetClass devuelve nil inmediatamente después de RegisterClass pues creo que tu segundo Assert (el que jamás se ejecuta) realmente es cierto: '¡Sigue siendo nil, RegisterClass ya no sirve!'.

// Saludos
Responder Con Cita
  #14  
Antiguo 27-02-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Cool

ups... es cierto...

es la rápidez con la que respondi...

Basta con hacer entonces:
Código:
Procedure TForm1.Button1Click(Sender : TObject);

Var
  Instancia : TClase;  
  {si esto compila estoy seguro que la unidad ha sido incluida en el uses }
  PunteroClase : TObjectClass;

Begin
  Instancia := TClass.Create(Parametros);
  Instancia.Free;  // para que el optimizador no quite la variable Instancia del camino...
  PunteroClase := GetClass('TClass')
  if PunteroClase = nil Then 
    ShowMessage('¡Es nil!');
  if PunteroClase = nil Then
  Begin
    // intentamos de nuevo registrar la clase, a ver que ocurre...
    RegisterClass(TClass);
    Assert(GetClass('TClass') <> nil, '¡Sigue siendo nil, RegisterClass ya no sirve!');
  End;

end;

lo siento de nuevo y mil gracias roman por la corrección...
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #15  
Antiguo 28-02-2004
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡ClassNameIs es sensible al tamaño!

¡Buen día a todos!

En vista de lo intrigante de este caso, decidí escudriñar un poco en la mejor referencia que hay de Delphi: el código fuente de su biblioteca.

GetClass llama indirectamente al método clase ClassNameIs heredado de TObject. Me di cuenta que éste es sensible al tamaño. De hecho si hago esta prueba:
Código:
RegisterClasses ([TForm1]);
C := GetClass ('TForM1');
C obtiene un valor Nil, porque se llama a GetClass con un parámetro que no es exactamente el mismo nombre que se le dio a la clase registrada.

No estoy seguro si en Delphi 5 era insensible al tamaño (habría que ver el código de TObject.ClassNameIs en la unidad System.pas de Delphi 5). Pero esa pudiera ser la causa del problema aquí planteado.

Si este no fuera el caso, todavía cabe la posiblidad de que GetClass devuelva Nil por algo que encontré en el método TRegGroups.GetClass de la unidad Classes.pas:
Código:
function TRegGroups.GetClass(const AClassName: string): TPersistentClass;
var
  I: Integer;
begin
  Result := nil;
  for I := 0 to FGroups.Count - 1 do
    with TRegGroup(FGroups [ I ]) do
    begin
      if Active then Result := GetClass(AClassName);
      if Result <> nil then Exit;
    end;
end;
Tal vez ese If Active evalúa a False.

Seguiremos investigando .

Al González .

Última edición por Al González fecha: 28-02-2004 a las 03:49:58.
Responder Con Cita
  #16  
Antiguo 28-02-2004
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
Cita:
Empezado por Al González
Me di cuenta que éste es sensible al tamaño.
No en mi caso (Delphi 7). ¿Qué versión manejas?

Cita:
Empezado por Al González
De hecho si hago esta prueba:
Código:
RegisterClasses ([TForm1]);
C := GetClass ('TForM1');
C obtiene un valor Nil
Misma prueba y C <> nil.

// Saludos
Responder Con Cita
  #17  
Antiguo 28-02-2004
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
Cita:
Empezado por yo mismo
La pregunta es si éstas unidadas están en el uses de alguna otra unidad en tu proyecto.
Esta pregunta nunca se respondió.

¿De casualidad no estarás tratando de cargar dinámicamente los paquetes?

De ser así acuérdate de que debes usar la opción "Build with runtime packages"

// Saludos
Responder Con Cita
  #18  
Antiguo 28-02-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
[quote=Al González
Me di cuenta que éste es sensible al tamaño.[/quote]

En primer lugar yo diria sensible a Mayusculas y minusculas. Al principio no sabia exactamente lo que querias decir.

He realizado la prueba en delphi 4 c/s y c <> nil;

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #19  
Antiguo 01-03-2004
glp1 glp1 is offline
Registrado
 
Registrado: feb 2004
Posts: 9
Poder: 0
glp1 Va por buen camino
Buenas, parece que he encontrado una posible solucion:

initialization
ActivateClassGroup(Tcontrol);
RegisterClasses( [ TFClass1, TFClass2 ]);

El sistema permite que las clases puedan ser cargadas y grabadas para ser registradas en grupos separados. Esto permite distinguir al IDE entre las clases VCL y CLX. Esta llamada activa un grupo de clases que contiene la clase especifica.
Aunque yo en la app solo utilizo VCL, se esta haciendo un lio con las clases VCL y CLX.

Vamos, si utilizo ActivateClassGroup(TControl), se evita el problema.
Gracias a todos.
Responder Con Cita
  #20  
Antiguo 01-03-2004
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
¡Ah! Muy interesante. Por fin comienza a aparecer cierta lógica en este asunto. No sé porque se está confundiendo con las componentes, yo jamás uso nada de Kylix y me limito a desactivar las componentes desde que instalo Delphi. ¿Tú las tienes activadas?

// Saludos
Responder Con Cita
Respuesta



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


La franja horaria es GMT +2. Ahora son las 05:00:02.


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