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 24-02-2005
pingale pingale is offline
Registrado
 
Registrado: feb 2005
Ubicación: Argentina (Buenos Aires)
Posts: 2
Poder: 0
pingale Va por buen camino
Angry Formularios: problema con segunda instancia

Hola, tengo un problema al intentar crear una segunda instancia de un formulario en tiempo de ejecución.

El formulario debería crear una nueva instancia de si mismo, de esta forma desde un formulario del tipo TMyForm tengo que crear otro de ese tipo. El problema surge porque la ventana original queda inutilizable mientras que la ventana recien creada funciona correctamente.

El código es algo así:

Código:
  ( ... )
  
  var
    newForm : TMyForm;
  begin
    newForm := TMyForm.Create(frmMain);
    newForm.Show;
  
    ( ... )
  
  end;
Donde:

- TMyForm es el tipo del formulario.
- frmMain es el formulario original.

No sé si esto es posible, supongo que debería serlo. Desde ya muchas gracias.
Saludos.

Última edición por pingale fecha: 24-02-2005 a las 18:45:09.
Responder Con Cita
  #2  
Antiguo 25-02-2005
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

¡Buen día a todos!

Pingale,

Tengo algunas dudas:
1. ¿Es frmMain la forma principal de la aplicación?
2. ¿A qué método, rutina o manejador de evento pertenece el código que nos has mostrado?
3. ¿Tiene TMyForm código asociado a algún evento que se dispare al crear (OnCreate) o mostrar (OnShow, OnActivate) la forma, el cual pudiera estar causando algún conflicto con la forma original?
4. ¿Qué pasa al momento de cerrar la segunda forma? ¿vuelve a habilitarse la primera?

Creo que la respuesta a algunas de esas preguntas, nos hará dar con la causa del problema.

Seguimos en contacto.

Al González .
Responder Con Cita
  #3  
Antiguo 25-02-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Aparte de lo comentado por Al González,

Intenta usar

Application.CreateForm(TmyForm, newform);

es igual que lo tuyo.... pero no es lo mismo.


Saludos
Responder Con Cita
  #4  
Antiguo 25-02-2005
pingale pingale is offline
Registrado
 
Registrado: feb 2005
Ubicación: Argentina (Buenos Aires)
Posts: 2
Poder: 0
pingale Va por buen camino
Ya está solucionado

Gracias a todos, ya logré solucionar el inconveniente.

Lo que sucedía era que una de las rutinas del nuevo formulario (y también del original, por supuesto) hacía referencia a una variable global que ambos formularios compartían, esto traía unos problemas, pero ya los solucioné.

De todas formas les agradezco la velocidad de respuesta y su buena predisposición.
Responder Con Cita
  #5  
Antiguo 25-02-2005
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 pingale
hacía referencia a una variable global que ambos formularios compartían, esto traía unos problemas, pero ya los solucioné.
He aquí un ejemplo de la inconveniencia de usar variables globales

Lepe, ¿cuál es la ventaja de usar Application.CreateForm?

// Saludos
Responder Con Cita
  #6  
Antiguo 26-02-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Ya que lo preguntas, Román, te tocó solucionarme la papeleta:
Que conste que no tengo Updates de Delphi 6 Empresarial instalados.

Pones un memo, un boton en Form1:

En el boton pones:
form2 := Tform2.create(application);

Creas un segundo formulario (Form2) y lo quitas de AutocreateForms

en Form2, hacemos una traza de los siguientes eventos:
- on create pones:form1.Memo1.lines.add('OnCreate '+Booltostr(form2 <> nil));
- on Activate pones:form1.Memo1.lines.add('OnActivate '+Booltostr(form2 <> nil));
- on show pones:form1.Memo1.lines.add('OnShow '+Booltostr(form2 <> nil));
- on paint pones:form1.Memo1.lines.add('Onpaint '+Booltostr(form2 <> nil));

Ejecutas y ves el resultado.

A mi me ha dado:
Código:
Oncreate false
OnActivate true
Onshow true
OnPaint true
Para mi significa que el evento Oncreate se hace para Tform2, y es lógico que Form2 todavia sea nil.

Pero probemos en un entorno MDI:
Form1 MDIform (el padre)
Form2 MDIChild

ejecutas el programa y me da esto:
Código:
Oncreate false
OnActivate false
Onshow false
OnPaint true
Hecho que me deja un poco groki.
Hasta que no se pinta, no se asigna a la variable Form2 ??

Sin embargo, creando el form2 con CreateForm, me sale todo a true en entorno MDI y en entorno SDI

He visto la implementación de CreateForm, y lo hace de una forma distinta a TcustomForm.Create.

Ya me contarás que te sale a ti.
Saludos
Responder Con Cita
  #7  
Antiguo 26-02-2005
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

¡Buen día a todos!

Cita:
Empezado por roman
...¿cuál es la ventaja de usar Application.CreateForm?...
La ventaja de utilizar el método Application.CreateForm en lugar de TMyForm.Create, es que CreateForm crea la instancia de la forma y asigna ésta a la variable dada, antes de llamar al constructor:
Código Delphi [-]
// Extracto de Forms.pas de Delphi 7
procedure TApplication.CreateForm(InstanceClass: TComponentClass;
  var Reference);
var
  Instance: TComponent;
begin
  Instance := TComponent(InstanceClass.NewInstance);
  TComponent(Reference) := Instance;
  try
    Instance.Create(Self);
  ...
Esto garantiza que los eventos OnCreate, OnShow y OnActivate, disparados por la llamada al constructor, se ejecuten cuando la variable forma ya tiene asignado un valor.

En el caso de usar la sintaxis "FormaX := TFormaX.Create", los eventos OnCreate, OnShow y OnActivate, se dispararán antes de realizarse la asignación.

Con respecto al evento OnPaint, la prueba de Lepe puede ser algo engañosa, ya que este evento se dispara de forma imprecisa, dependiendo de las necesidades de despliegue de la forma y sus controles. Puede ocurrir de forma asíncrona a la construcción de la forma.

Lepe, dudo de dos de los resultados que has presentado. Específicamente el de los eventos OnActivate y OnShow de la prueba con forma SDI, que deberían ser False y False. En el caso de la forma MDI me parece que los resultados False, False, False y True son correctos.

Es decir, al no usar el método Application.CreateForm, los resultados para OnCreate, OnShow y OnActivate son False en todos los casos, y True si se utiliza Application.CreateForm.

Espero esto sea de utilidad, seguimos en contacto.

Al González. .
Responder Con Cita
  #8  
Antiguo 26-02-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Cita:
Empezado por Al González
Lepe, dudo de dos de los resultados que has presentado. Específicamente el de los eventos OnActivate y OnShow de la prueba con forma SDI, que deberían ser False y False.
Llevas toda la razón, lo puse de memoria ... y me equivoqué.

Saludos Al
Responder Con Cita
  #9  
Antiguo 27-02-2005
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
La ventaja de utilizar el método Application.CreateForm en lugar de TMyForm.Create, es que CreateForm crea la instancia de la forma y asigna ésta a la variable dada, antes de llamar al constructor:
¿Y en qué consiste la ventaja? Si la forma aun no ha sido creada no hay gran cosa que se pueda hacer con la variable. ¿Y qué pasa si ocurre una excepción en el constructor?

// Saludos
Responder Con Cita
  #10  
Antiguo 27-02-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Si dentro de un Datamodule necesitas saber si existe ese formulario, (para actualizar un control no-adaware) puedes usar Assigned(form2).

Si la variable no está asignada, entonces ese código del Datamodule no se ejecuta, y por tanto, la primera vez que se muestra la ventana, el control queda desfasado.

Por otra parte, si tienes codigo en el AfterScroll de un dataset, que depende de la existencia de un Form, tampoco se ejecuta ese código.

Quizás el error está en la forma de programar, o en el sistema que se esté usando. En mi caso particular, y usando tablas paradox, no me queda más remedio que realizar esas comprobaciones en el Datamodule. Ya que viene a cuento.... ¡¡Que hartura de paradox !! ... con lo útil que resulta los triggers oiga...

Cita:
Empezado por roman
¿Y qué pasa si ocurre una excepción en el constructor?
Te refieres a que la variable ya no es nil, y se quedará asignada.... Pues si; Si es un problema. La creación de la forma debe estar en un try ... except con Freeandnil(Form2).

Saludos

Última edición por Lepe fecha: 27-02-2005 a las 10:37:53.
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 18:13:45.


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