Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 02-11-2003
Marcela Marcela is offline
Miembro
 
Registrado: may 2003
Posts: 30
Poder: 0
Marcela Va por buen camino
Cool Formas

Hola a todos, les agradeceria me pudieran informar como hago para convertir una variable de tipo string, en la cual tengo el nombre de una forma que debo abrir, y luego abrir dicha forma.
Gracias

Se me olvidaba decirles que la idea es llamar las formas hijas, pues estoy trabajando con MDI.

Última edición por Marcela fecha: 02-11-2003 a las 02:31:30.
Responder Con Cita
  #2  
Antiguo 02-11-2003
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
Código:
procedure TForm1.Button1Click(Sender: TObject);
var
MiWindow:TForm;
begin
  MiWindow:=Form2;
  MiWindow.show;
end;
Un Saludo.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #3  
Antiguo 02-11-2003
Marcela Marcela is offline
Miembro
 
Registrado: may 2003
Posts: 30
Poder: 0
Marcela Va por buen camino
Tienes toda la razon y te agradezco, pero el problema esta en que la variable es de tipo string, viene de un query
NombreForma := QueryNombreForma.AsString;

Ahora quiero abrir esta forma que se como se llama porque es el resultado de un query, pero no se como decir que en esa variable esta el nombre de la forma y que esa forma es la que necesito abrir.

Gracias de antemano,
Responder Con Cita
  #4  
Antiguo 02-11-2003
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
Si el formulario ya está creado entonces basta que busques su nombre en la variable global Forms.

Pero si lo que deseas es crear el formulario a partir de su nombre te recomiendo que en lugar de guardar el nombre del formulario guardes el nombre de la clase del formulario, esto es, en lugar de guardar 'MiForm' guardes 'TMiForm'.

Una vez hecho esto puedes obtener la referencia de clase necesaria para poder construir el formulario usando la función GetClass de la unidad Classes.pas:

Código:
var
  FormaClase: TFormClass;
  Forma: TForm;

begin
  FormaClase := TFormClass(GetClass(NombreForma));
  if FormaClase <> nil then
  begin
    Forma := TFormaClase.Create(Self);
    Forma.Show;
  end;
end;
Para que lo anterior funcione, la clase debe estar previamente registrada, lo cual conviene hacerlo en la sección initialization de cada formulario que desees construir de esta manera:

Código:
initialization
  RegisterClass(TMiForma);
end.
// Saludos
Responder Con Cita
  #5  
Antiguo 05-11-2003
Marcela Marcela is offline
Miembro
 
Registrado: may 2003
Posts: 30
Poder: 0
Marcela Va por buen camino
Nuevamente, si el formulario ya esta creado, y lo debo llamar desde la forma madre, realmente no se donde se coloca el initialization, perdoneme pero soy algo novata.
var
FormaClase : TFormClass;
Forma : TForm;

begin
FormaClase := TFormClass(GetClass(NombreForma));
If FormaClase <> nil then
begin
Forma:= TFormaClase.Create(Self);
Forma.Show;
end
Esto no me funciona porque me imagino que no he podido saber donde coloco el initialization.
Por fis, gracias por la ayuda y recuerden que soy novata

Responder Con Cita
  #6  
Antiguo 05-11-2003
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:
Marcela comentó:
Esto no me funciona porque me imagino que no he podido saber donde coloco el initialization.
La estructura general de una unidad pascal es:

Código:
unit nombre de la unidad;

interface

uses Lista de unidades necesarias en la interfaz

  {
    Sección de interfaz 
    
    Aquí se colcan las declaraciones de tipos, las variables y
    constantes globales y los encabezados de funciones y 
    procedimientos que implemente la unidad.
}

implementation

uses  Lista de unidades necesarias en la interfaz

  {
    Sección de implementación

    Aquí se coloca el código para implementar las funciones y
    procedimientos declarados en la interfaz así como la
    implementación de los métodos de clases declaradas en la
    interfaz.
  }

initialization
  {
     Sección de inicio

     Aquí se coloca el código que se ejecuta al principio
     de la aplicación cuando Delphi procesa la unidad.

     Esta sección es opcional pero si se incluye la sección final
     también deberá incluirse ésta aunque no tenga código.
  }

finalization
  {
     Sección final

     Aquí se coloca el código que se ejecuta al fiinal de la
    aplicación cuando Delphi procesa la finalización de unidades.

     Esta sección es opcional.
  }

end.
// Saludos
Responder Con Cita
  #7  
Antiguo 05-11-2003
Ruben_Cu Ruben_Cu is offline
No confirmado
 
Registrado: oct 2003
Ubicación: Mariel, Cuba
Posts: 271
Poder: 0
Ruben_Cu Va por buen camino
Hola Marcela, la sección de inicialización es opcional por lo que puede o no formar parte de la Unit, se coloca dentro de bloque de implementación, aquí trascribo lo copiado de la ayuda de Delphi para mas claridad
Código:
implementation
 
uses  { List of units goes here }
 
  { Implementation section goes here }
 
initialization
  RegisterClass(TMiForma);
end. 


finalization
  { Finalization section goes here }
 
end.
Saludos y suerte en tu batalla.
Responder Con Cita
  #8  
Antiguo 06-11-2003
Marcela Marcela is offline
Miembro
 
Registrado: may 2003
Posts: 30
Poder: 0
Marcela Va por buen camino
Lamento molestar tanto, pero hice todo y nada. Auxilio
procedure TMDI….
var
Hija: Tform;
Str_Forma: String;
FormaClase: TFormClass;
begin
Try
:
begin
Qad_Forma.Close;
Qad_Forma.Parameters.ParamByName('Numero').Value := Int_NumeroForma;
Qad_Forma.Open;
:
begin
Str_Forma := 'T' + Qad_FormaORES_FORMA.Value;
FormaClase := TFormClass(GetClass(Str_Forma));
Hija := TFormaClase.Create(Self);
Hija.Show;
end;
end;
:
end;

Initialization
RegisterClass(TFormaClase);

Hice todo esto, pero me sale un Error, "no declarado identificador TFormaClase", por fis que estoy haciendo mal si de acuerdo a un filtro en un query, tengo guardada en una tabla el nombre de l forma.
Responder Con Cita
  #9  
Antiguo 06-11-2003
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:
Marcela comentó:
Hice todo esto, pero me sale un Error, "no declarado identificador TFormaClase"
El error te lo marca el compilador en la línea

Código:
Hija := TFormaClase.Create(Self);
Te sobra la T.

// Saludos
Responder Con Cita
  #10  
Antiguo 08-11-2003
Marcela Marcela is offline
Miembro
 
Registrado: may 2003
Posts: 30
Poder: 0
Marcela Va por buen camino
Unhappy

Hola nuevamente, sale errores, ya no se para donde coger, me va tocar buscar otras alternativas.

esto pasa cuando ejecuta la linea de Initialization
RegisterClass(FormaClase);

Project Inicial.exe raised exception class EAccessViolation with message 'Access violation at address 0053E4B2 in module "Inicial.exe". Read of address 000002C'. Process stopped. Use Step or Run to continue.

El proyecto Inicial.exe ejecuto la clase de la excepción EAccessViolation con el mensaje 'la violación de Acceso a dirección 0053E4B2 en el módulo "Inicial.exe." Lea de dirección 000002C.' El proceso detuvo. Use el Paso o Corra para continuar.

si elimino esta linea , entonces el error se ejecuta en la linea:
Hija := FormaClase.Create(Self);

No se que hacer?, gracias por su colaboración, y perdonen que sea tan cansona.
Responder Con Cita
  #11  
Antiguo 09-11-2003
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 te recomendaría, ahora que sabes cuál es la sección initialization releer mi primer mensaje en este hilo y tener cuidado con lo que estás escribiendo.

Sé que estás empezando con Delphi y el tema de las referencias de clase no es un tema básico, sin embargo no me queda claro si ya buscaste en la ayuda de Delphi acerca de ello y conviene que le des una leída para que los errores que te aparecen no parezcan tan en chino.

Te hago un resumen:

Las referencias de clase (en inglés class references) son algo así como meta clases-- Una variable cuyo tipo es una referencia de clase, es una variable cuyos valores son tipos de clases.

Considera este caso concreto:

Código:
type
  TForm = class
    ...
  end;

  TFormClass = class of TForm;
Esto es un resumenn de las declaraciones que se encuentran en la unidad forms.pas.

Aquí, TForm es un tipo de datos, particularmente una clase. Como cualquier otro tipo de datos puedes declarar variables de este tipo:

Código:
var
  Forma: TForm;
Por otro lado, TFormClass es una referencia de clase (una meta clase). También es un tipo de datos en el sentido de que puedes declarar variables de este tipo:

Código:
var
  FormaClase: TClassForm;
Pero la diferencia es que los valores que variables de este tipo pueden tomar son, a su vez, tipos de datos. No cualquier tipo de datos sino sólo aquellos que sean clases (como TForm) y de hecho no cualquier clase sino sólo TForm o descendientes de TForm.

Así, puedes asignar:

FormaClase := TForm1;

ya que la clase TForm1 es un descendente de TForm.

Observa aquí el punto importante:

Una asignación como

FormaClase := Forma;

donde Forma es como la declarada arriba, no es válida ya que Forma es un objeto de la clase TForm, es decir una variable de tipo TForm, más no es el tipo TForm.

¿Para qué sirven estas referencias de clase?

Recuerda cómo se construye un objeto, por ejemplo Forma:

Forma := TForm.Create(...);

Observa que antes del punto está un tipo de datos, una clase, TForm. Como una referencia de clase toma como valor un tipo de datos puedes sustituir TForm en la asignación anterior por una referencia de clase, cuyo valor sea igual a TForm:

Código:
FormaClase := TForm;
Forma := FormaClase.Create(...);
Pero si FormaClase no tiene un valor asignado entonces es nil y no se puede hacer nada con ella. Es decir, si usas

Forma := FormaClase.Create(...);

sin haber antes asignado TForm a FormaClase es como si hicieras

nil.Create(...);

lo que provoca un error de violación de acceso.

Regresando a tú problema específico. El procedimiento RegisterClass toma como parámetro una referencia de clase. Como FormaClase es de tipo referencia de clase el compilador no te marca ningún error. Sin embargo, seguramente FormaClase no ha sido inicializada, es nil, de manera que cuando pones

RegisterClass(FormaClase);

es como si pusieras

RegisterClass(nil);

y de ahí la violación de acceso.

Ahora bien, cuando tienes un procedimiento, por decir algo, con un parámetro de tipo Integer:

Código:
procedure MiProc(I: Integer);
begin
end;
para llamar a este procedimiento no es necesario que hagas:

Código:
I := 84;
MiProc(I);
sino que basta usar:

MiProc(84);

Lo mismo sucede con RegisterClass. En lugar de usar una variable como FormaClase para pasársela cómo parámetro, puedes pasarle directamente el valor que te interesa; en este caso TMiForma (o como quiera que se llame la clase de tu formulario):

RegisterClass(TMiForma);

// Continúa ...

Última edición por roman fecha: 09-11-2003 a las 04:35:46.
Responder Con Cita
  #12  
Antiguo 09-11-2003
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
Ahora que tienes una noción de las referencias de clases, desmenucemos lo que te escribí en mi primer mensaje de este hilo. Voy a suponer que TMiForma es una de las clase de formularios que te interesa "guardar" en la base de datos".

El primer punto a notar, como lo dije en su momento, es que lo más conveniente es guardar no el nombre del formulario, sino de la clase del formulario ya que este último es el que te sirve para crear dinámicamnete formularios de dicha clase. En otras palabras, en lugar de guardar la cadena "MiForma" en la base de datos, lo que guardas es "TMiForma".

Normalmente, para crear un formulario de tipo TMiForma basta que pongas:

Código:
var
  Forma: TMiForma;

begin
  Forma := TMiForma.Create(...);
end;
Pero esto sólo lo puedes hacer cuando estás escribiendo el código y no durante la ejecución del programa, simple y sencillamente porque Delphi es un lenguaje compilado y no interpretado como VB. En VB podrías poner en un Edit la cadena

"TMiForma.Create(...)"

y pasársela a alguna función de tipo Eval o como quiera que se llame en VB para ejecutar la instrucción.

Para suplir esta limitación, Delphi implementa las referencias de clase y crea una tabla que asocia nombres de clases con las clases en sí:

Código:

'TButton'  | TButton
'TEdit'    | TEdit
'TListBox' | TListBox

etc.
La función GetClass recibe el nombre de una clase, busca este nombre en la columna izaquierda y, si lo encuentra, regresa lo que haya en la columna derecha, por ejemplo:

GetClass('TEdit') -> TEdit

Entonces, para que GetClass funcione, el nombre de la clase debe estar en dicha tabla, es decir, debe estar registrada. Delphi registra algunas clases automáticamnete pero otras debe uno mismo registrarlas. Ese es el caso de TMiForma y para ello se usa

RegisterClass(TMiForma)

Este registro puede hacerse en cualquier momento pero para poder crear formularios de tipo TMiForma en cualquier momento lo que conviene es que el registro se haga apenas comience el programa, esto es, en la sección initializatio del formulario.

Posteriormente, para crear tus formularios dinámicamente es que usas las referencias de clase. No puedes, como vimos, usar la instrucción

Forma := TMiForma.Create(...)

pero sí puedes sustituir TMiForma por una referencia de clase:

Código:
var
  FormaClase: TFormClass;

...

Forma := FormaClase.Create(...);
pero FormaClase debe inicializarse en algún momento anterior. ¿De dónde sacas el valor correcto? Pues de la tabla de registro mediante

GetClass(NombreClase)

donde NombreClase es una variable de tipo String cuyo valor es el que obtienes de la consulta SQL.

Ahora bien, como GetClass es una función genérica lo que regresa es una referencia de clase para la clase TPersistent que está muy arriba en la jerarquía de clases de Delphi. Esto es así porque GetClass no puede saber qué descendientes habrá.

Si tu usas:

Código:
var
  FormaClase: TFormClass;

...

FormaClase := GetClass(NombreClase);
el compilador protesta porque devuelve una referencia de TPersistent que está por arriba en la jerarquía que TForm.

Pero por el momento no te confundas con esta parte y sabe simplemente que debes hacer un "type casting"

FormaClase := TFormClass(GetClass(NombreClase));

Con esto ya tienes la referencia de clase que necesitas. Si por alguna razón la clase no quedó registrada entonces GetClass devuelve nil y por ello hay que verificar el valor de regreso:

Código:
if FormaClase <> nil then
Pero si el registro fue correcto el valor de FormaClase será TMiForma y podrás hacer

Forma := FormaClase.Create(...);

------------

Yo sé que esto es largo y no para entenderse a la primera pero creo que te puede dar una mejor idea de lo que está pasando y cómo usar correctamente el ejemplo que te dí al mero principio del hilo.

Lee esta información sin tratar de digerir todo de un jalón y concrétate al ejemplo del mero principio del hilo. Haz pruebas omitiendo en un principio el uso de las consultas SQL, simplemente registra la clase de un sólo formulario y entiende un código como:

Forma := FormaClase('TMiForma');

así, directa la cadena sin variables intermedias.

Siguiente paso, registra dos clases de formularios y trata de construir instancias de ellos tomando el nombre de su clase de un Edit.

Sólo hasta que estos ejemlos los tengas bien maduros es que intentas hacerlo ya tomando los nombres de la base de datos.

Es decir, "paso a pasito"

// Saludos

Última edición por roman fecha: 09-11-2003 a las 04:30:26.
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 04:55:25.


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