FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Crear Forms en forma DINAMICA
Hola a todos.
Hace un par de días lance un hilo referido como "multiples instancias", que por cierto agradesco a ROMAN por su ayuda. Pues bien trate con lo sugerido y muy bien, pero sucede que el numero de ventanas a emplear no se conoce o no es fijo, la duda es como crearlas dinamicamente y que en su CAPTION aparesca el nombre dado, trate y consegui crearlas con nombres para cada ventana obtenidos de un TEDIT aunque no he podido hacer referencia a ellas, pero (que nunca falta), se presentan los formularios sin CAPTION, ignoro si lo que hice sea correcto, alguien me podrias hechar una mano con eso, esto fue lo que hice para generar las ventanas: Begin Name:=Edit1.Text; TFOrm.Create(Application).Name:=(Name); TFOrm.Create(Application).Caption:=Name; TForm.Create(Application).Show; Application.CreateHandle; End; |
#2
|
||||
|
||||
hola...
no soy muy diestro en esto pero creo que en tu codigo estas en lugar de crear una sola ventana lo que estas haciendo es crear tres ventanas y a cada una le estas "haciendo" algo distinto creo que al menos esta parte del codigo debiera aparecer como saludos... |
#3
|
||||
|
||||
Cita:
referencian a nada (van a nil), que son separadas y por lo tanto no hacen lo que quieres y ademas, para que Application.CreateHandle? No lo necesitas para nada.... Es asi de simple: Código:
var oForm:TForm; begin oForm:=TForm.Create(Application); oForm.Name:='Hola'; oForm.Caption:='Hola'; end; modal... Código:
var oForm:TForm; begin oForm:=TForm.Create(Application); try oForm.Name:='Hola'; oForm.Caption:='Hola'; oForm.ShowModal; finally oForm.Release; //se usa release y no free con forms end; end; maneras: Usando la referencia Application (observa que application CONTIENE a oForm) en las colecciones Forms o Components (usando FindControl('UnNombre') y haciendo cast tambien sirve). Sin embargo, alli hay otros objetos que no son los que estas haciendo. Realmente, lo que se hace es crear un administrador en una lista de objetos: Código:
var oFormas:TObjectList; = Mira en ayudas cual unit se necesita... ObjectList automaticamente libera objetos (llama al free) tonces no necesitas preocuparte por objetos perdidos en memoria.... begin oForm:=TForm.Create(Application); oFormas.Add(oForm,'Bodega') = Chequee en ayudas, no recuerdo orden oForm.Name:='Hola'; oForm.Caption:='Hola'; oForm.Show; end; Si haces un helper (una clase de ayuda) puedes poner algo como: Código:
function Forma(Nombre:String):TForm;overload; function Forma(Indice:Integer);TForm;overload; articulo Framework Simple Aplicaciones(ingles): Es lo que hago tambien y realmente es una forma EXCELENTE de trabajar, se lo recomiendo a todos. No depende de los controles de DevExpress asi que no te asustes (y el codigo es funcional: lo puedes usar de base). Deberias empezar a estudiar sobre Desing Patterns (Patrones de diseño) ya que aumenta considerablemente la calidad del codigo.....
__________________
El malabarista. Última edición por mamcx fecha: 11-09-2004 a las 00:23:08. |
#4
|
||||
|
||||
Un comentario:
Creo que manejar una lista propia de ventanas podría ser útil en determinados contextos pero en un caso general estamos repitiendo una lista que ya existe: Screen.Forms Y en el caso de aplicaciones MDI, el formulario principal tiene el arreglo MDIChildren que lista todas las ventanas hijas. Por otra parte no veo cómo tener dicha lista de ventanas nos ayuda a liberar correctamente los formularios creados. Para liberar el objeto formulario basta con poner Action := caFree; en su evento OnClose. El único problema que puede presentarse aquí es cuando necesitamos poder abrir nuevamente el formulario ya que debemos poder determinar si está ya creado o no. Con formularios MDIChildren esto normalmente no es asunto de preocupación ya cada vez que se abre un documento se utiliza otra ventana y no se reusa una anterior de manera que, en efecto, creamos uno nuevo. Tampoco hay problema, como ya se vió, en el caso de ventanas modales ya que el formulario se libera inmediatamente después de cerrarse- y por cierto, también en este caso se puede hacer Action := caFree para no tener que llamar a Release (o Free, que me parece que Release sólo es necesario cuando se desea liberar el formulario desde un evento del mismo). Queda el caso de formularios que nos son modales y de los cuales sólo queremos que haya una instancia. La manera más común es es usar la variable que se declara automáticamente cuando se añade el formulario durante el diseño: se pone a nil en el evento OnClose para así poder verificar con certeza si existe o no al momento de intentar abrilo:
Pero esto tiene el defecto de que se está haciendo referencia a un objeto global y no sólo eso, sino que la clase en sí del formulario hace referencia (en su evento OnClose) a una instancia particular; ambas prácticas no aconsejables. Otra opción mejor es olvidarse de la variable global (de hecho casi siempre debería uno olvidarse de ellas) y usar una variable privada en el formulario principal y siguiendo la misma técnica del OnClose. Con esto se evita el uso de una variable global aunque persiste el hecho de que la clase hace referencia a una de sus instancias en particular. El método que prefiero es el de la notificación:
El método Notification será llamado cada vez que se agregue o remueva un componente, así que aquí checamos si es el formulario secundario y si está destruyéndose para en tal caso poner la refererencia a nil. Pero debemos asegurarnos de que la notificación llegue al formulario principal. Para ello basta pedirlo al momento de construirlo:
// Saludos Última edición por roman fecha: 11-09-2004 a las 00:33:19. |
#5
|
||||
|
||||
Si, Screens.Forms es la via rapida.
Sin embargo, el punto que se ve es que una aplicacion GUI tiene un form principal, entonces crea forms secundarios que: 1- Pueden ser MDIChildren, o pueden ser hijas dentro de una aplicacion SDI, o puden ser independientes (Owner y parent =nil) 2- Pueden ser modales. A la vez, o son dialogos, o son formas de edicion 3- Pueden ser embeidos (algunos les gusta meter forms dentro de forms, en vez de usar Frames) 4- Tienen logica de muestra y cerrado muy variable 5- Pueden ser formas de multiple instancia (como los documentos en Word) o DEBERIAN ser de unica instancia. A la vez, las de unica instancia TAL VEZ son parte de un esquema MDI... o SDI? 6- Pueden ser ensambladas (ej: Un form contiene los frames de Edicion de Frame Contacto + Frame campos de cliente + ...) Las tecnicas tradicionales son ineficientes en el sentido que cada vez que se hace una forma hija, estamos implementando una de estas ideas, o muchas mas! Luego, no olvidar que ademas se necesitan sincronizar el menu, las barra(s) de navegacion... Luego el problema de la reutilizacion. Es dificil EXTRAER un Form bien hecho, que se necesita en otro proyecto porque hay muchas dependencias o se olvida como es la logica y las reglas de creado/destruccion. Adicionalmente, las interfaces MDI se consideran "obsoletas" por algunos. De hecho, una forma mas efectiva es usar una interface por tabs, como lo hace Mozilla Firefox, VS.NET o el mismo Delphi. Es por eso que es importante el link al framework simple de aplicaciones. La idea es que uno crea un "modulo" (en mi caso, uso Frames pero igual da con forms) y un Administrador de modulos se encarga de cubrir TODOS los casos enumerados anteriormente. Luego, siguiendo el patron de Factory/Builder, se hace algo como: Código:
initialization AdministradorModulos.Registrar('Editar Cliente', TfrmEditarCliente, TCategoria.Create('Editar Cliente','Archivo/Clientes','BarraClientes',IndiceIcono), tipInstanciaUnica); Código:
AdministradorModulos.Mostrar('Editar Cliente'); resultado:=AdministradorModulos.MostrarModal('Editar Cliente'); AdministradorModulos.Clonar('Editar Cliente'); Lo cual se encarga de administrar los menus y barras, la logica de creacion y destruccion declarativamente. Es MUY facil extraer los "modulos" y reusar en otros proyectos. Actualmente, tengo una version personalizada basada en esta idea, y puedo decir que reuso sin problemas modulos con proyectos tan diferentes como: - Un ERP (mezcla todo) - Un IDE de programacion para scripts (mas tipo MDI) - Un formulario de administracion de los servidores (SDI, 2-3 formas y ya) - Otros proyectos mas pequeños Extraigo, reubico y reuso modulos de personalizacion, de claves, de edicion, etc... sin lios... La productividad se siente, y no me preocupo en si estoy haciendo bien la creacion o destruccion, o como se hace todo... adicionalmente, el administrador de modulos es portable entre D7 y D8 (ASP.NET) y he podido hacer "transplantes" de componentes (probando con los de Delphi, los de TMS y DevExpress, actualizando versiones, etc...) con un traumatizmo minimo.... En fin, es meter TODO el conocimiento que expone Roman (muy bien explicado) y dejarlo en un framework!
__________________
El malabarista. Última edición por mamcx fecha: 11-09-2004 a las 00:25:16. |
|
|
|