![]() |
Aplicacion Multiformulario
Que tal Gente!
Lo que quiero hacer es una aplicacion en la cual yo pueda tener cualquier cantidad de formularios pero que no se me salgan de la ventana principal y ademas poder ordenar los formularios en cascada horizontal o verticalmente dentro de la misma ventana principal. Espero se entienda lo que necesito!! Gracias al que me pueda colaborar. |
lo que tu necesitas es una aplicacion "MDI" para eso solo debes tener un formulario principal que sera el Frame al cual debes cambiar la propiedad "FormStyle = fsMDIForm" y a las ventanas que se crearan dentro de este marco tienes que asignarles la propiedad "FormStyle= fsMDIchild" prueba con eso hay muchas cosas mas que debes tomar en cuenta para este tipo de aplicacion,cualquier duda, no temas en preguntar.
saludos |
Aplicacion MDI
Gracias Sudamericano, voy a intentar lo que propones y cualquier cosa te estoy comentando.
|
Ya hice lo que sudamericano me aconsejo y realmente era lo que necesitaba. Pero encontre algunos inconvenientes.
Ya tengo los formularios secundarios (fsMDIForm) dentro del principal (fsMDIForm) pero quisiera saber como ocultar estos formularios y con que codigo o componente hago ordenamiento de ellos dentro del formulario principal (en cascada, horizontal o verticalmente). Muchas gracias y espero que este tema sea de utilidad para todos. |
Los formularios MdiChild no pueden ocultarse. Normalmente debes destruirlos si no quieres que aparezcan y (re-)crearlos cuando vuelvas a necesitarlos.
El formulario padre tiene los métodos Cascade y Tile para poner las ventanas en cascada o mosaico y la propiedad TileMode del formulario padre controla si el mosaico es horizontal o vertical. // Saludos |
Un pequeño apunte a lo dicho por Roman.
Los formularios hijos pueden minimizarse. También puedes cargar un formulario maximizado "encima" del formulario que quieres ocultar, sin tener que destruir el formulario. Cuando lo necesites de nuevo, utiliza show para mostrarlo. No se si es el efecto que buscas, si no lo es intenta explicar un poco más lo que quieres hacer. saludos |
ok, te debes haber percatado que al ejecutar el proyecto se crean y se muestran todos los formularios, esto no es precisamente lo que uno espera, bueno, hay viene la solucion :
* lo primero que debes hace es ir al menu project/options; se cargara una ventana anda a la pestaña "Form" en el listview de la izquierda donde dice "auto-create form" quita todos los formularios menos el Principal * segundo paso para pode rmostrar (crear) un formulario hijo debes poner el codigo siguiente :
Explicacion : if not Assigned( FrmCliente) then = verificas que el formulario no este creado "FrmCliente" = nombre del formulario "Aplication" = propietario del formulario hijo FrmCliente.ShowModal = Muestra el formulario Ahora en el evento "Close" del formulario "FrmCliente" pones lo siguiente
prueba estos pasos primero, cuando ya te funcione, avanzamos con las opciones de cascada, etc.. otras cosa que version de DELPHI USAS ?? saludos |
Una preguntilla
Hola, estaba probando con este tipo de ventanas, y resulta que si pongo un form como padre con un boton , y le digo que me cree otro form, sigo viendo el boton por debajo del form que acabo de crear, es normal esto?!
Un saludo y gracias. |
Normal, no lo sé. Vamos, supngo que sí pero el efecto es bastante feo. Realmente en las aplicaciones MDI lo único que "debería" haber en el área cliente del formulario padre son ventanas hijas y no controles propios. Nótese que digo área cliente, de manera que se pueden colocar paneles u otros controles alineados a uno de los extremos del formulario. Lo que sobra es el área cliente.
// Saludos |
Cita:
"Cannot make a visible window modal" Pero aún suponiendo que se pueda, queda medio extraño una ventana hija modal ¿qué no? // Saludos |
ok si es un error, solo se debe poner lo siguiente :
; lo hize de memoria, por eso me equivoque, sorry |
Esteee..., es que el FrmCliente.Show también sobra (no hace daño pero no es necesario). Y no pidas disculpas que no era regaño :) Si así lo pareció pido disculpas.
// Saludos |
te puedo asegurar que la linea no esta de mas, toma en cuenta que estoy creando y destruyendo los Form segun lo demanda,
|
Haz la prueba. Yo te aseguro que sí está de más. En formularios normales sí que es necesaria pero los formularios MdiChild se hacen automáticamente visibles apenas se crean.
// Saludos |
Gracias Sudamericano, creo que vamos avanzando positivamente con este tema! Tambien gracias a roman por sus aportes y si tiene razon en cuanto al aporte sobre la aparicion del formulario tipo modal
(FrmCliente.ShowModal;) pues presento el error que el menciona, pero pues si suprimimos esta linea el codigo funciona. Continuando con el tema mientras aplicaba evento "Close" del formulario "FrmCliente" tuve el problema que no podia volver a abrir el formulario. De casualidad se me ocurrio adicionar una linea en el codigo de creacion del formulario hijo de esta manera : procedure TFrmKey.ShowFrmCliente; begin FrmCliente := nil; if not Assigned( FrmCliente) then FrmCliente:=TFrmCliente.Create(Application); FrmCliente.ShowModal; end; Y con esto pude solucionar el invonveniente, pero no se que problemas pueda traer y pues quiesiera saber que significa el "nil". Sudamericano, yo estoy usando Delphi 7 y pues creo que podemos ir avanzando en lo del ordenamiento de los formularios secundarios (cascada,..) Muchas Gracias! |
Además de que en el código que pegas sigues usando el ShowModal, el problema es que al poner FrmCliente := nil, la sdiguiente condición siempre va a ser cierta así que siempre vas a crear la ventana, exista previamente o no. El nil significa simplemente que la variable FrmCliente no apunta a nada, que no tiene ninguna referencia.
// Saludos |
Como primer punto quiero aclarar porque pongo
primer caso :si no existe; se crea y se muestra segundo caso : si si hubiran varios form hijos lo que logra la linea mencionada es que el formulario "FrmCliente" se muestre por encima de todos. otro punto es que en el evento close debes destruir el formulario,
con eso te aseguraas de destruir el frmcliente saludos |
Gracias Roman, que pena lo de la ultima linea se me paso lo del ShowModal ya lo he entendido. Y pues entiendo lo que me quieres decir con respecto al "nil". Entonces como se prodria resolver el problema que despues de cerrar el formulario lo pueda volver a abrir.
Saludos |
Sólo es necesario usar Show si ya está creado para ponerlo al frente (equivale a poner BringToFront) pues el Create automáticamente hará el Show y pondrá el formulario al frente. // Saludos |
codigo roman = 4 lineas
Mi codigo = 3 lineas
ambos codigos son equivalentes |
Las líneas al compilador le son indistintas. El punto es que hay un paso de más en la otra manera (Show después de Create). Claro que- como dije al principio -no afecta y seguro que en este caso concreto nadie notará un ciclo más del procesador, pero yo prefiero como norma evitar redundancias. Desde luego es más cuestión de gustos.
// Saludos |
Muy buen debate!! Pero compañeros, he tenido el mismo problema con cualquiera de los dos codigos!!! Despues de que cierro el formulario secundario no lo puedo volver a abrir.
saludos!! |
Un saludo a todos los foreros, quiza sea un poco tarde para este mensaje, pero espero que le sirva a alguno.
codigo para mostrar form hijas: ( procedimiento) Código Delphi [-] procedure mostrarHija(aHija: TFormClass); luego ... si se decea destruir una ventana(form) hija al cerrarla y no solo minimizarla, solo adicionamos una linea de codigo en el evento OnClose de esta: Código Delphi [-] Action:= caFree; de antemano pido disculpas si existe algun error en el codigo, lo escribo de memoria, pero los que tienen el libro de Ian Marteens pueden consultarlo, pues fue en la "Cara Oculta" donde lo lei hace algun tiempo atras. |
Parece que el compañero se quedó con el error, despues de 3 semanas supongo que lo habrá solucionado; tambien puede darse el caso de que lo haya "postpuesto".
Reuniendo todo lo dicho, sin entrar en más debates, una solución completa sería:
Ventajas de este método: - En la ventana de facturas se puede usar datos de Frmclientes de forma cómoda:
- No necesitamos hacer un bucle para encontrar una ventana, porque tenemos sus referencias Frmclientes, FrmFacturas, etc. - Solo permitimos una ventana abierta de cada tipo al mismo tiempo. En algunos casos es una desventaja, en otros una ventaja, depende de la filosofía que se quiera seguir. El método de kesu si tiene un pequeño error, pero al haber sido escrito de memoria, demasiado bien está. Por otra parte, es "la otra filosofía" para trabajar con ventanas MDI, ese método si permite tener varias ventanas FrmClientes abiertas al mismo tiempo, pero tambien tiene sus inconvenientes. Si interesa ese método, pregunten. Lo que sí es muy importante es no mezclar ambos métodos, porque tendríamos Access Violation, Abstract Error y otras muchas excepciones nada obvias de localizar Saludos |
Aplicacion Multiformulario
Gracias Kesu y Lepe!!
La verdad no habia solucionado este inconveniente pero habia buscado otros caminos que solucionaban de manera diferente mi problema. Voy a probar lo que ustedes acosejan y espero dar parte positivo despues de esto. Saludos!! |
Pues lepe diste justo en el blanco...
Disculpen que habra este hilo desde hace tiempo... lo que pasa es que yo estaba buscando en los foros algo que me ayude a determinar un error.
Hace un tiempo dejé un hilo inconcluso. Pues, empecé a retomarlo... y estuve metiendo código. Veran, estoy declarando un descendiente de TForm ,lo llamé TExpertForm. Pues en dicha forma se encapsulan procedimientos y propiedades que permitan realizar visualizaciones tanto en forma modales como no modales... y que funcionen tanto para aplicaciones MDI como SDI (es asi?:p) Me leí todo y al llegar aqui: Cita:
Hasta ahora (todavia estoy viendo esto) el código que tengo es como sigue:
Me preguntaba si se podrá realizar lo que pretendo... se que tiene errores... y algunos los veo ahorita. Mi pregunta mas que nada pasa por el hecho de como controlar que se pueda operar tanto para una sola instancia como para varias. Desde ya muchas gracias, Saludos, |
Aclaro algunas cosillas...
Me pareció oportuno aclarar algo sobre el código que expuse anteriormente. Mi intención (pues.. el código está en versión 0.0beta:D:p )no es simplemente contar con un form especializado en mostrarse modal o no, con o sin instancias multiples. Si se fijan bien... tiene en su estructura interna un array del tipo variant. El mismo está pensado para llevar en el cualquier variable que usualmente uno declararía en la unidad. Lo que evitaría tener que estar declarando variables... (eso pretendo yo). Sólo bastaría con asignarles valores a las posiciones que uno desea. Por ejemplo: que Vars[1] indique CantidadActualPedidos. No se si la idea es buena... tiene su defecto... al destruir la forma todo se pierde (por tanto la solución es usar variables globales) [en lo personal... no me gusta emplear demasiada variables globales].
Comento esto ya que para alguno tal vez le sirva... y le de una idea, y para que se me entienda mejor. Entonces, la forma mantiene encapsulada funciones para manejar el vector y va a tener... (pues todavia falla) funciones para mostrarse adecuadamanete según sea necesario. Si alguien ya tiene algo parecido, o si creen que estoy inventando la rueda me avisan. Saludos, |
Sobre el Variant.... a ver si esto le ves alguna utilidad ;).
Saludos |
claro... es muy util
Cita:
Por ahora me estaba por concentrar en tratar de elaborar funciones para que la ventana se muestre modal, no modal, que permita una o mas instancias, MDI, etc... y como esto es algo más para el aspecto estetico de mis aplicaciones es algo que le dedico poco esfuerzo. Mi mayor concentración está por el momento en la lógica y diseño de unidades de bajo y medio nivel. Si bien esta unidad (TExpertForm) me viene barbaro para el aspecto visual... si no me sale.., no hay drama. Lo que importa es que la lógica ande. Si tengo novedades y problemas sobre este aspecto, estaré metiendo dudas. Saludos, |
Como bien dices, hay métodos para convertir el variant, pero al usar dichas conversiones en el programa final, se enrolla mucho el código, por eso mismo creé esa unidad, es más práctico.
Yo lo veo usando un TObjectList con cada VariantElement, así quitaríamos el array que se crea siempre. Pero bueno, si de momento no te sirve... ahí queda para cualquiera. En tu código hay algo que no entiendo muy bien: Assigned(Self) se refiere a la instancia de TEXpertForm; como siempre haremos algo así: El ExpertForm siempre estará creado, por tanto, jamás entrará en esa rama. Si el ExpertForm no está creado previamente, delphi nos lanzará un access violation al intentar acceder al método ViewModal (o cualquier otro), antes de intentar ejecutarlo, por ende, tampoco le veo sentido a "With Create(Application)" No entiendo muy bien la filosofía que sigues, ya que en principio debe existir una instancia de ese ExpertForm, quizás viendo el código del "programa de usuario" (el que usa el módulo ExpertForm), entendería la funcionalidad que quieres crear. Saludos |
Cita:
Cita:
Cita:
Pues, el objetivo es determinar si ha sido creada una instancia de la forma. Si la hay, mostrarla, si no la hay... primero crearla. Y pruebas que hice, esta parte funciona. Haz la prueba: 1. Agrega al dpr la unidad. 2. Hereda la forma y desactivala de las auto-creadas. 3. Al form1 dale un código donde te guste: ¡La forma se crea, y modal! Ha decir verdad... las pruebas que he realizado me han indicado que sólo funcionan (ViewModal y ViewNotModal) siempre y cuando no esté en auto create forms. Eso si... no recuerdo bien si hice cambios y luego verifique, mis disculpas. Ya me pongo a ver si es asì. Pero de las pruebas que hice, es como describo. Utilidad que pretendo es encapsular todo y dejar que sea la misma forma decida como debe mostrarse (según las propiedades seteadas) y ofrecer publicamente sólo algunas de las propiedades y funciones. Por ejemplo: tanto ViewModal como ViewNotModal deben ser declaradas en forma privada y sólo dejar View. El hecho de tener ese array de variables, es para permitir el flujo de datos entre unidades. |
| La franja horaria es GMT +2. Ahora son las 21:04:55. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi