1. Visual Basic - Guía del Estudiante Cap. 10
INTERFACE DE DOCUMENTOS MULTIPLES. (Multiple Document Interface MDI )
Lo que se va a explicar en este capítulo le será bastante familiar aunque nunca haya reparado
en ello. Posiblemente haya utilizado un procesador de texto en el que está escribiendo una
carta, y antes de terminar de escribir esa carta, comienza a escribir otro documento, y
posiblemente otro, y tenga los tres documentos en la pantalla al mismo tiempo, bien en
ventanas escalonadas, (cascada), bien en ventanas en forma de mosaico, o simplemente
tapando unas a otras completamente. Los tres documentos están en su procesador de textos,
y puede actuar sobre uno u otro simplemente eligiendo el deseado mediante el mecanismo
que le proporciona su procesador de textos. Este sistema no es ni mas ni menos que una
interface de documentos múltiples. En programación, a este tipo de aplicaciones las
denominamos MDI
Para crear una aplicación MDI debe hacerse mediante un Formulario Padre al que se le
añaden tantos Formularios Hijo como documentos tengamos. Al formulario padre le
denominamos Formulario MDI, y a los formularios hijo en Visual Basic se les denomina
formularios MDIChild. En esta Guía del Estudiante se usarán indistintamente una u otra
denominación.
La única diferencia entre un formulario normal y un formulario Hijo es que éste tiene la
propiedad MDIChild a true.
Para realizar una aplicación MDI, lo primero que hay que hacer es introducir en ella un
formulario MDI. Para introducirlo, basta con hacer click en Insertar | Formulario MDI de la
barra de menú. Solamente se puede tener un formulario MDI en una aplicación. Puede
observar que una vez que ha introducido uno, la palabra Formulario MDI del submenú Insertar
queda deshabilitada.
Una vez que tiene un formulario MDI puede introducir tantos formularios hijo como desee. Para
que un formulario sea formulario hijo basta con poner a True su propiedad MDIChild.
En una aplicación MDI pueden coexistir formularios hijo y formularios normales.
Propiedades de los formularios MDI
Aparte de las propiedades de un formulario normal, un formulario MDI tiene las siguiente
propiedades :
AutoShowChildren. Muestra los formularios hijo nada mas cargarlos.
Esta propiedad puede verse si se carga un formulario hijo mediante la sentencia :
Load NombreFormularioHijo
Si la propiedad AutoShowChildren está a True, el formulario cargado se verá inmediatamente.
Si está a False, será necesario ejecutar la sentencia NombreFormularioHijo.Show para
presentarlo.
ActiveForm Mediante esta propiedad podemos conocer el formulario activo dentro de una
aplicación de documentos múltiples. (El formulario activo es aquel que tiene el foco)
MiVariable = ActiveForm.caption
MiVariable contendrá el Caption (Barra de Titulo) del formulario activo.
ActiveForm.Backcolor = RGB (255,0,0)
pondrá el fondo del formulario activo de color rojo.
2. ScrollBars Hace que el Formulario MDI (padre) muestre barras de Scroll para presentar
en toda su extensión a un formulario hijo, cuando las dimensiones de áste superan las de
aquel.
Aparte de estas propiedades que diferencian un Formulario MDI de un Formulario normal, los
Formularios MDI presentan otras particularidades.
Inserción de Controles Solamente podrán introducirse en un formulario MDI aquellos
controles que tengan la propiedad Align. (Picture, Data, DBGrid) y solo permiten que se
presenten con alineación a uno de los lados del Formulario (Top, Bottom, Left o Right)
El control Picture puede trabajar como contenedor de otros controles. Por lo tanto, para poder
introducir cualquier control (TextBox, Label, CommandButton ...) será necesario introducir un
control Picture, y sobre el, poner los controles que se necesiten.
Línea de Menú. Cuando existe la línea de Menú en un Formulario MDI y en el Formulario
Hijo que introduzcamos en él, la línea de menú del Formulario MDI se sustituye por la línea de
menú del Formulario Hijo introducido.
Barra de Título. La Barra de Título del Formulario MDI se conserva siempre. Pero si el
Formulario Hijo insertado dentro de él está maximizado (ocupa toda la extensión del Formulario
MDI), a la barra de título se le añadirá la barra de Título del Formulario Hijo entre paréntesis.
Para hacer que un Formulario sea un formulario hijo basta con ponerle su propiedad MDIChild
a True.
Puede preparar los formularios hijo uno a uno e introducirlos dentro del formulario MDI según
las necesidades de la aplicación. Este sería el caso de una aplicación con varias pantallas,
todas ellas colocadas sobre una pantalla fija (Formulario MDI) del que se aprovecha quizás
alguna parte como parte común de toda la aplicación (Menú, Título, Barra de herramientas
montada sobre un Picture, etc.)
Puede también darse el caso de introducir un número indeterminado de ventanas iguales para
realizar varias veces la misma función, pero sobre ventanas diferentes. (Caso del procesador
de texto que tiene varias ventanas de texto, cada una con un documento. Lo que
desconocemos a priori es el número de documentos que vamos a editar)
Para el primer caso, será necesario crear cada una de las ventanas, e introducirlas y quitarlas
según pida la aplicación.
En segundo caso, bastará con crear un formulario hijo con todas las partes necesarias para su
correcto funcionamiento, y luego, realizar tantas “fotocopias” de ese formulario como ventanas
necesitemos. Lo que introducimos en la aplicación son precisamente esas “fotocopias”, pero no
el original, que lo seguimos manteniendo intacto para volver a copiarlo si fuese necesario.
A esas “fotocopias” de un formulario las llamamos Instancias. Al original le llamaremos Clase.
En realidad una Clase es la definición de un objeto Visual Basic. Un objeto Visual Basic puede
ser un Formulario, un control, un objeto de acceso a datos.
La Instancia es la réplica de una clase. Puede ser la réplica de un Formulario, de un control o
de otro objeto. La Instancia lleva las mismas Propiedades que la clase. Se dice que hereda
las propiedades. (Excepto la propiedad Visible, que siempre, por defecto, aparece a False).
Cuando se varía una propiedad de una Instancia, no se altera el valor de esa propiedad en la
Clase ni en ninguna de las restantes Instancias.
Después de toda esta teoría, ¿podemos saber como se crea una Clase de un formulario ? O
dicho de manera mas coloquial, ¿Cómo se crea un Formulario para poder hacer varias
“fotocopias” de él ?
3. La respuesta es obligatoriamente mas sencilla que la teoría. Con el formulario vacío que
tengamos en el proyecto (Insertemos un Formulario si fuese necesario) pongámosle todos los
controles que deseemos. Le podemos poner un Menú y cambiar a nuestro antojo todas sus
propiedades. Entre ellas, la propiedad MDIChild. Si vamos a introducir las Instancias de ese
Formulario en un Formulario MDI esa propiedad debe estar a True, y por lo tanto sus
Instancias saldrán igualmente con esa propiedad a True. Pongámosle un nombre y ya está
creada la clase. Supongamos que ese nombre es FormularioHijo
Para crear ahora Instancias de ese Formulario podemos hacerlo de dos formas :
Declarar una variable tipo Objeto. No se asuste. Para declarar que una variable es un
Formulario basta con declararla de la siguiente forma :
Dim MiVentana As Form
Esta variable debe declararla en sitio adecuado para su aplicación, y el ámbito de esa variable
objeto será el mismo que para cualquier tipo de variable. (Vea Ambito de las Variables) La
sentencia a utilizar para la declaración será Dim, Private, Public o Global tal como se explicó
para las variables.
Una vez declarada como variable puede hacerla igual a un objeto existente que servirá de
modelo (Una Clase) que estará definida por un nombre: (P.e. FormularioHijo)
Set MiVentana = New FormularioHjo
Podemos hacer las dos operaciones a un tiempo : declarar y crear la copia :
Dim MiVentana As New FormularioHijo
Una vez creado la instancia del formulario debemos cargarlo en el Formulario Padre. Para
cargarlo debemos emplear la sentencia Load MiVentana, con lo que quedará cargado en la
memoria, pero, dependiendo de como está la propiedad AutoShowChildren del Formulario
Padre se mostrará o no se mostrará. Para que se muestre, independientemente de como esté
esa propiedad, basta con ejecutar MiVentana.Show. En realidad mediante el método Show un
formulario no solamente se muestra, sino que también se carga en la memoria si no estuviese
previamente cargado. Por lo tanto podíamos habernos ahorrado la instrucción anterior para
cargarlo Load MiVentana
Es muy práctico poner un Caption distinto a cada formulario que se introduzca, caso de
introducirse varios formularios hijo iguales. El Caption es una propiedad y por lo tanto todas las
instancias heredan el Caption de la Clase. Sería prudente distinguir un formulario de otro
mediante su Caption, es decir mediante su barra de título.
Para ello podemos crear un contador en el mismo procedimiento en el que creamos una nueva
instancia, y poner el Caption de cada nuevo Formulario siguiendo un orden numeral.
Documento 1, Documento 2, Documento 3, etc.
Ese procedimiento quedará de la siguiente forma :
Static contador As Integer
Dim MiVentana As New FormularioHijo
MiVentana.Caption = “Documento “ & Str (contador)
MiVentana.Show
4. Referencias a los Formularios. ActiveForm y Me
Si queremos nombrar un Formulario Hijo dentro de una aplicación MDI el primer problema con
el que nos encontramos es que todos los formularios hijo (Instancias de la misma Clase) tienen
el mismo nombre. Por lo tanto no podemos nombrarlas con ese nombre, ya que la aplicación
no sabría a cual de ellas nos referimos.
Si el código donde vamos a nombrar ese formulario está fuera de él (P.e. en el Formulario
Padre) deberemos referirnos al formulario hijo mediante ActiveForm. ActiveForm nos va a
indicar cual es el formulario que está actualmente activo. Un formulario está activo cuando
estamos trabajando sobre él. En ese momento tiene el foco. Permanece activo desde que
hacemos click con el ratón sobre cualquiera de sus partes, hasta que activamos otro
formulario. Es sencillo reconocer cual es el formulario activo pues tiene su barra de título con
el color vivo.
Cada vez que hacemos una operación sobre una parte de un formulario éste se pondrá activo.
Por ejemplo, si el formulario es un documento de texto, y contiene el texto en un RichTextBox
de nombre RTB1, si queremos hacer una operación con el texto desde un botón colocado en el
formulario padre (poner en negrita el texto seleccionado), haríamos lo siguiente :
ActiveForm.RTB1.SelBold = True
ya que siempre estaremos seguro de que el Formulario Activo es aquel en el que acabamos de
seleccionar el texto.
Si el botón donde hemos puesto el botón no es el formulario padre, sino el hijo, tenemos un
problema similar. Su nombre será (con los ejemplos anteriores) MiVentana, y pueden existir
varios formularios con ese nombre, tantos como documentos hayamos introducido. No
podemos por tanto nombrarlo con su nombre, pues hay (o puede haber) varios. Tampoco lo
podemos nombrar con ActiveForm, ya que esta propiedad corresponde al Formulario Padre. La
solución es nombrarle mediante Me. Me siempre se refiere al formulario que contiene al
procedimiento donde está esa palabra. Por lo tanto, si tenemos un botón en el formulario hijo
con la instrucción :
Me.RTB1.SelBold = True
Me se refiere concretamente a ese formulario.
Colocación de los Formularios Hijo - Método ARRANGE
Mediante el método Arrange podemos distribuir los formularios hijo dentro del formulario
padre. Pueden colocarse en cascada, mosaico horizontal, mosaico vertical o como iconos.
SintaxisNFMDI.Arrange distribución
donde
NFMDI = Nombre del Formulario MDI
distribución puede tomar los siguientes valores o constantes :
Constante Valor Descripción
vbCascade 0 Dispone todos los formularios MDI secundarios no minimizados
en cascada.
vbTileHorizontal 1 Dispone todos los formularios MDI secundarios no minimizados
en mosaico horizontal.
vbTileVertical 2 Dispone todos los formularios MDI secundarios no minimizados
en mosaico vertical.
VbArrangeIcons 3 Dispone los iconos de los formularios MDI minimizados.
5. Las ventanas o los iconos se pueden distribuir incluso si el objeto MDIForm está minimizado.
Los resultados son visibles cuando el objeto MDIForm se maximiza.
Posición de los Formularios en el Eje Z - Método ZOrder
Cuando tenemos varios formularios hijo, unos ocultan a los otros. Mucho mas si los formularios
están maximizados. Podemos colocar un formulario hijo en la parte frontal del montón de
formularios (para que se vea completamente) o llevarle a la posición mas atrás mediante el
Método ZOrder.
Sintaxis NFH.ZOrder posición
Donde NFH = Nombre del Formulario Hijo
posición puede se 0 ó 1. Si es 0 (o si se omite) el formulario se coloca en primer plano. Si es
1 el formulario se coloca en el fondo del eje Z.
ZOrder es un método que no solamente se puede emplear con formulario hijo, sino con
cualquier instancia. Puede emplearlo también con cualquier control. Pero lea detenidamente la
Ayuda de este método, ya que no todos los controles la admiten.
Mostrar los Formularios existentes mediante el Menú -- Propiedad
WindowList
Al explicar el Editor de menús casi se pasó por alto una propiedad del menú : WindowList.
Cuando se activa esta propiedad (Puede activarse para una sola palabra del menú. Si se
pretende activar para mas de una dará un error), esa palabra que tiene activada la propiedad
WindowList mostrará al hacer click sobre ella, en un menú desplegable, el Caption (Barra de
Título) de todos los formularios hijo cargados en ese instante en la aplicación. Pueden estar
incluso minimizados.
FIN del décimo capítulo de VISUAL BASIC - Guía del Estudiante.
Copyright Luis Suárez Bernaldo 1998. Este texto es de libre difusión para fines educativos.
Prohibida la copia total o parcial para usos comerciales. San Sebastián de los Reyes (Madrid,
España) , Junio de 1998