Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Los ejemplos que se han propuesto hasta ahora han sido tan simples que estaban compuestos
de tan sólo un formulario. En la práctica, la mayoría de los programas se sirven de múltiples
ventanas. Por regla general siempre existe una ventana principal, en la que se encuentra el
menú de opciones, y una serie de ventanas accesorias que pueden estar visibles siempre o
sólo cuando sean necesarias.
Un programa puede utilizar múltiples ventanas simplemente para solicitar una determinada
información, como puede ser el nombre del archivo que se desea abrir, o bien para facilitar la
edición de múltiples documentos. Las ventanas del primer tipo se suelen construir como
cuadros de diálogo, nombre con el que se conoce a aquellas ventanas que no pueden ser
redimensionadas, no cuentan con botones de maximizar o minimizar y que además son
modales, no permitiendo seguir trabajando con la aplicación hasta que no sean cerradas.
En el caso de que el programa sea capaz de permitir el trabajo con múltiples documentos de
forma simultánea, éstos pueden ser mostrados en ventanas totalmente independientes o bien
en una interfaz de documento múltiple, que se conoce como MDI.
Cuando una aplicación cuenta con varios formularios es normal hacer referencia a unos desde
otros. Para poder hacer referencia a un formulario desde un módulo de código que no es el
suyo, debemos añadir una directiva include facilitando el nombre del fichero de cabecera
correspondiente al módulo en el que está definido el formulario al que queremos acceder. La
forma más fácil es usar la opción Include Unit Hdr del menú File.
En un proyecto tan sólo puede existir un formulario principal, que es el que se muestra
inicialmente cuando se ejecuta el programa. Cualquiera de los formularios de nuestra
aplicación puede ser el formulario principal. Para establecerlo deberemos usar la opción
Options del menú Project, que da lugar a la siguiente ventana:
En esta ventana se define cuál es el formulario principal, cuales son formularios autocreados
y cuáles estarán disponibles. En el ejemplo, Form1 es el formulario principal, Form2 es un
formulario autocreado, es decir, que podemos usarlo en cualquier momento sin ocuparnos de
ningún trabajo de preparación, y Form3 es un formulario disponible, por lo que no se crea
inicialmente, sino que el programa sólo cuenta con una plantilla o definición de sus
características. Para poder usar este último formulario tendremos que crearlo y liberar la
memoria ocupada por él cuando deje de sernos útil.
A partir de este momento podemos referenciar el nuevo formulario mediante el nombre que
le hemos dado, por ejemplo:
Destrucción de un formulario
Cuando el formulario ha sido creado automáticamente por el código del propio proyecto no
tenemos que preocuparnos por su destrucción. Sin embargo, cuando el formulario lo hemos
creado nosotros mismos, deberemos destruirlo liberando la memoria ocupada por éste. Para
ello se utiliza la función delete().
delete(Formulario);
Visualización de un formulario
Un formulario cuenta con los métodos Show(), que lo hace visible y Hide(), que lo
oculta. También podemos acceder directamente a la propiedad Visible, asignándole el
valor true o false.
Un formulario que se muestra por estos métodos es una ventana no modal, lo que significa
que el usuario puede acceder a otras ventanas del mismo programa sin necesidad de cerrar
ésta. Este es el tipo lógico de visualización cuando la ventana va a servir para mostrar
información. Sin embargo, si la ventana modifica en algún aspecto el entorno del programa
no debería permitirse el acceso al resto de las funciones hasta en tanto el formulario no sea
cerrado. Para conseguir esto bastará mostrarlo mediante el método ShowModal().
Juana Sánchez Rey 2002/2003 2
Borland C++ Builder. MÚLTIPLES VENTANAS. Fundamentos de Programación (Ciclo superior A.S.I.)
Formularios MDI
Cada vez que se añade un nuevo formulario con la opción New Form, el formulario creado
tiene el estilo normal o por defecto, representado por la constante fsNormal. Este estilo de
formulario es el de una ventana independiente, que no actúa como contenedor de otras
ventanas ni está contenido dentro de ninguna y que, además, puede ser ocultada total o
parcialmente por otras ventanas. La propiedad FormStyle es la que determina el estilo del
formulario.
Los otros dos estilos permitidos son fsMDIForm y fsMDIChild, cuya finalidad es
permitir la creación de aplicaciones MDI (Multiple Document Interface / Interfaz de
Documento Múltiple). El término hace referencia a un tipo de aplicación compuesta por una
ventana principal, a la que denominamos padre, capaz de contener en su interior múltiples
ventanas a las que se denominan hijas. La ventana que actúa como padre tiene el estilo
fsMDIForm y cada ventana hija tendrá el estilo fsMDIChild.
Aquellos formularios que van a actuar como ventanas hija deberán ser definidos como
formularios disponibles y no como formularios autocreados.
La ventana principal cuenta con una serie de propiedades y métodos que facilitan la gestión
de las ventanas hija. La propiedad MDIChildCount contiene el número de ventanas hijas
existentes, mientras que ActiveMDIChild almacena una referencia a la ventana hija que
en ese momento tiene el foco de entrada.
Mediante los métodos Cascade() y Tile() podemos disponer las ventanas hijas
existentes en ese momento solapadas o en forma de mosaico, mientras que el método
ArrangeIcons() nos permite ordenar las ventanas que en ese momento estén
minimizadas.
EN LA PRÁCTICA
Con el fin de ver en la práctica cómo podemos utilizar múltiples formularios en un proyecto y
algunos de los cuadros de diálogo que nos aporta Windows, vamos a diseñar un programa
que nos permita editar ficheros de texto, con la posibilidad de tener abiertos varios de
ellos de forma simultánea en un entorno MDI.
El texto de cada ventana estará contenido en un control TMemo, por lo que no es posible el
uso de atributos de texto. Sin embargo, cada ventana puede tener un tipo de letra y color
diferentes al resto.
El formulario principal del proyecto actuará como ventana marco de la interfaz MDI. Este
formulario será el que existe inicialmente en el proyecto, al que vamos a darle el título
“Multi Editor”. Deberá tener el valor fsMDIForm en la propiedad FormStyle.
Se insertará un menú de opciones desde el cual será posible abrir un fichero, guardarlo, crear
nuevos ficheros, modificar el tipo de letra y el color de fondo y gestionar las múltiples
ventanas hija que puedan existir. El menú de opciones (componente TMainMenu) deberá
tener las siguientes opciones:
Para permitir las diferentes opciones que se deducen de las opciones del menú, tendremos
que insertar un componente TSaveDialog, un TOpenDialog, un TFontDialog y un
TColorDialog. El formulario quedará en tiempo de diseño tal y como se muestra a
continuación:
que asignar “Ficheros de Texto | *.txt”. También abrá que activar del
componente TSaveDialog las opciones ofOverwritePrompt y ofPathMustExist,
y en el componente TOpenDialog la propiedad ofFileMustExist.
El siguiente paso es añadir al proyecto un nuevo formulario, para lo que pulsaremos el botón
New Form. Este formulario actuará como hijo y en ejecución podrán existir múltiples copias
de él abiertas. Por ello esta ventana no deberá ser creada automáticamente, sino que habrá
que especificar que está sólo disponible.
Como este nuevo formulario va a ser una ventana hija habrá que darle el valor fsMDIChild
a su propiedad FormStyle.
Para visualizar y permitir la edición del texto insertaremos en este formulario un campo
TMemo que ocupará todo el espacio disponible en la ventana (Align=alClient), que
contará con una barra de desplazamiento vertical (ScrollBars=ssVertical) y que
permitirá la introducción del tabulador (WantTabs=true).
Mediante la opción Include Unit Hdr del menú File añadiremos al primer formulario una
referencia al segundo, lo que nos permitirá acceder a la definición de TForm2.
El título de cada ventana hija se establecerá en ejecución. En caso de que la ventana se cree
abriéndose un fichero existente el título será el nombre de éste. Si, por el contrario, la ventana
se ha creado vacía, asignaremos como título la palabra Nuevo seguida de un número que se
irá incrementando secuencialmente. Este contador se declarará en la parte private de la
definición del formulario, que se encuentra en el fichero de cabecera correspondiente:
Para crear un nuevo fichero, la opción Nuevo del menú Archivo tendrá que ser pulsada.
Por tanto habrá que seleccionar esta opción para abrir el editor de código por el método
correspondiente y escribir lo siguiente:
La opción Guardar del menú Archivo no debe estar accesible en caso de que no exista
ninguna ventana hija abierta. Para ello deberemos hacer click en el manú Archivo para
abrir el método correspondiente al evento OnClick. En este caso asignaremos a la
propiedad Enabled de la opción Guardar los valores true o false, dependiendo de que
exista o no un formulario hijo activo en ese momento:
Formulario->Memo1->Lines->LoadFromFile(OpenDialog1->FileName);
Formulario->Caption=OpenDialog1->FileName;
Formulario->Memo1->Modified=false;
Formulario->Show();
}
catch(...) {ShowMessage("Se produce error al recuperar");}
}
}
La opción Salir tendrá como finalidad cerrar la aplicación. Para ello bastará llamar al
método Close() de la forma:
La primera opción del menú Estilo es Letra, una opción que nos permitirá seleccionar
cualquier tipo, tamaño y estilo de letra para mostrar el texto de la ventana que en ese
momento esté activa. Para ello obtendremos los valores actuales de la propiedad Font del
control TMemo, asignándolos a la propiedad Font del control TFontDialog. Mostraremos
el cuadro de diálogo y si se ha pulsado el botón Aceptar, realizaremos la asignación contraria.
Por último encontramos en el menú una opción Ventana conteniendo tres opciones que nos
permiten disponer las ventanas hija en forma de cascada, en forma de mosaico o bien
organizar los iconos de aquellas ventanas que estén minimizadas. Los códigos asociados
serán los siguientes:
Mediante la opción Include Unit Hdr del menú File añadiremos al segundo formulario una
referencia al formulario principal mediante la opción Include Unit Hdr.
Como hemos podido ver en el punto anterior, los métodos que se encargan de guardar y
recuperar el texto de una ventana activa utilizan la propiedad Modified del control TMemo
para indicar que no se han realizado modificaciones. Esta propiedad tomará automáticamente
el valor true en el momento en que el usuario modifique el texto. Por lo tanto, en el
momento en que se desee cerrar una ventana habrá que comprobar esta propiedad y actuar en
consecuencia. Para poder hacer esto escribiremos el código siguiente correspondiente al
evento OnCloseQuery.
Cuando se pulsa el botón de cierre de una ventana hija MDI lo que ocurre es que ésta se
minimiza, pero no se destruye, por lo que habrá que liberar la memoria usada por la ventana
según lo siguiente:
Ya sólo bastaría probar el programa. Esto es to, esto es to, esto es todo, amigos!!