BorlandC BuilderApuntesss
BorlandC BuilderApuntesss
BorlandC BuilderApuntesss
El IDE consta de las herramientas necesarias para diseñar, implementar, ejecutar y depurar una aplicación,
mediante una serie de elementos que operan de forma integrada y complementaria: un Editor de Código, un
Depurador de Errores, una Barra de Herramientas, Herramientas de Bases de Datos, etc.
Ventana principal
En la parte superior de la pantalla, aparece una ventana que contiene el nombre del proyecto, los botones de
acción rápida, la Paleta de Componentes y el menú principal. A esta ventana se le denomina ventana principal.
Cerrándola estaremos saliendo de C++ Builder. La ventana principal se divide en:
- El menú principal.
o File. Permite crear, abrir, salvar, cerrar e imprimir los elementos que forman una aplicación,
además de abandonar el entorno.
o Edit. Agrupa las funciones típicas de edición como deshacer, rehacer, copiar, pegar y borrar.
Además existen funciones de ayuda en la colocación de los elementos de la interfaz, como
alinear con la cuadrícula, traer al frente, enviar al fondo, ...
o Search. Comprende todas las funciones típicas de búsqueda de texto en las ventanas del área
de trabajo.
o Project. Gestiona los elementos del proyecto o aplicación y genera su programa asociado
_____________________________________________________________________________________________
o Run. Contiene las funciones que nos permiten tanto ejecutar como depurar la aplicación.
o Component. Contiene una serie de utilidades que nos facilitan la gestión de los componentes
VCL (Visual Component Library), así como la configuración de la Paleta de componentes de
la Ventana Principal.
o Database. Contiene comandos que permiten crear, modificar y visualizar Bases de Datos.
o Tools. Para visualizar y cambiar las opciones de entorno, modificar la lista de programas,
crear y editar imágenes, etc. Permite, por tanto, añadir y configurar herramientas auxiliares.
- Los botones de acción rápida. Son iconos que realizan de forma directa, sin necesidad de acceder a
los menús desplegables, las funciones más utilizadas durante el desarrollo de una aplicación. Es
totalmente configurable (pulsando con el botón derecho y accediendo a Properties) y, por defecto,
presenta las acciones más comunes para crear y depurar un programa, como abrir, salvar, ejecutar,
detener (pausa), ejecutar línea a línea, etc.
- La Paleta de Componentes. Está compuesta por múltiples páginas a las que accederemos mediante las
pestañas que hay en la parte superior. Cada una de las páginas contiene componentes que son los
elementos básicos con los que construiremos los programas. Esta paleta la usaremos cuando
desarrollemos programas para Windows.
El área de trabajo
En el área de trabajo nos encontramos con dos tipos de ventanas: las de elaboración de interfaz en caso de
desarrollo de una aplicación Windows (Ficha o Formulario e Inspector de Objetos) y las de implementación de la
aplicación en código fuente C++ mediante un editor, para todo tipo de aplicaciones (Editor de Código). Ahora,
solamente vamos a realizar pequeñas aplicaciones en modo consola, por tanto, las dos primeras ventanas que
aparecen a continuación, no serán usadas, aunque se explica su propósito:
- La ficha o “formulario” es la ventana que aparece aproximadamente en el centro de la pantalla y que tiene
_____________________________________________________________________________________________
La ventana que sí usaremos siempre para introducir (editar) el programa fuente es la que aparece a
continuación:
- Es el Editor de Código, que permite introducir el código fuente que definirá el funcionamiento de nuestra
aplicación. Posee unas características que facilitan la labor de introducción del código fuente, como son el marcado
de sintáxis a color, la capacidad de deshacer a diferentes niveles, la integración con el depurador, etc.
_____________________________________________________________________________________________
A continuación aparecerá una ventana donde escribiremos el código de nuestro programa fuente. En este
momento es posible cerrar la ventana correspondiente al Inspector de Objetos (Object Inspector), ya que nuestro
programa no va a contar con elementos visuales (componentes).
_____________________________________________________________________________________________
El nombre de nuestro programa, por defecto, es Project1.cpp. La extensión cpp indica que es un fichero
con código fuente en Borland C++ Builder. Para cambiar el nombre de nuestro programa bastará acceder a la opción
Save del menú File, donde nos solicitan el nombre que queremos dar a nuestro programa. Lo llamaremos
Bienvenida.cpp y lo almacenaremos en la carpeta Archivos de programa\Borland\CBuilder3\Projects.
_____________________________________________________________________________________________
El resultado de esta opción es una ventana informativa que indica el resultado del proceso de compilación,
avisando de los errores y cuáles de ellos son simples avisos o consejos (Hints-señales o insinuaciones de que algo
no es del todo correcto-, Warnings – avisos-) y cuántos son verdaderamente errores fatales (Errors). Sin la
depuración de estos últimos no podremos probar la ejecución de nuestro programa, puesto que un proceso de
compilación que detecte errores no genera código objeto.
En caso de error, aparecerá señalada la línea donde se ha producido el error y, justo debajo de la ventana de
edición de código, una ventana indicando el tipo de error producido.
El error deberá ser solventado modificando el código fuente. Una vez que los errores de compilación están
solucionados y que el proceso de compilación nos indica que el proceso no ha tenido problemas (Done: Make)
podemos ejecutar nuestro programa.
_____________________________________________________________________________________________
donde el fichero que aparece con el icono de MS-DOS corresponde al programa .exe que hemos generado.
Para ejecutar el programa bastará con pulsar sobre éste fuera del entorno de desarrollo o, dentro de este
entorno, pulsar la opción de menú Run/Run, pulsar F9 o pulsar sobre el icono de los botones de acción
rápida.
La ejecución de nuestro programa dará paso a una ventana en modo MS-DOS con la siguiente apariencia:
_____________________________________________________________________________________________
Toda aplicación Windows de tipo estándar cuenta con una ventana en la que se visualiza o solicita
información. En un programa Windows desarrollado con C++ Builder las ventanas de la aplicación son las
fichas, cuyas características estableceremos mientras estamos construyendo el programa, es decir, en la
denominada fase de diseño.
El aspecto de una ficha durante el diseño no tiene por qué ser precisamente el aspecto que tendrá la ventana
cuando el programa se ejecute. Por ejemplo, durante el diseño se muestra en el interior de la ficha una
matriz o rejilla de puntos cuya finalidad es facilitar la alineación de los componentes en su interior. Esta
matriz no será visible durante la ejecución. Su aspecto es totalmente configurable desde la opción Tools
del menú principal en el apartado Environment Options-Preferences, donde
Snap to grid Si se desea que al mover un componente esta distancia sea la unidad
mínima de trabajo o no
Inicialmente, las dimensiones de la ventana serán las mismas que hayamos dado a la ficha durante el
diseño, aunque este aspecto depende del valor que asignemos a ciertas propiedades. También con el ratón
podemos modificar estas propiedades de tamaño y situación inicial.
Una parte muy importante del desarrollo de una aplicación con C++ Builder consiste en insertar en la ficha
los componentes apropiados, situándolos adecuadamente y estableciendo las propiedades que
correspondan. Todos estos pasos se completarán con la escritura de código asociado a eventos.
Para insertar un componente lo primero que hay que hacer es seleccionarlo en la paleta de componentes,
dentro de la página a la que pertenezca. La selección del componente se efectúa simplemente marcando
con el ratón el icono que lo representa, posicionando el ratón en el lugar que queramos de la ficha y
pulsando el botón izquierdo de éste.
El nuevo componente tomará unas dimensiones por defecto que, posteriormente, podremos modificar
desplazándolo o modificando su forma con el ratón o mediante sus propiedades.
3) Modificación de propiedades
Cada vez que en la ficha se selecciona un componente, automáticamente el Inspector de Objetos muestra su
nombre y sus propiedades y eventos.
_____________________________________________________________________________________________
El código de un programa Windows no se ejecuta de forma secuencial sino que lo hace según los mensajes
que recibe del propio sistema. Estos mensajes se generan, por ejemplo, al pulsar un botón, introducir un
carácter, etc. Estos mensajes son gestionados en C++ Builder automáticamente por cada componente y
traducidos en eventos. Nosotros podemos asociar un método a un evento, de tal forma que cuando dicho
evento se produzca se ejecute el código de ese método.
En la página Events del Inspector de Objetos veremos los nombres de los eventos con los que cuenta el
componente que tengamos seleccionado en ese momento en la ficha. A la derecha de cada uno de los
eventos puede existir el nombre de un método, que será el que se ejecute en el momento en el que se genere
el evento. Haciendo doble clic sobre la columna derecha de un evento abriremos automáticamente la
ventana de código situando el cursor en el método adecuado.
La mayor parte de un programa C++ Builder estará siempre asociado a algún evento, y será el mismo C++
Builder el que se encargará de establecer el nombre de los métodos, determinar los parámetros necesarios y
sus tipos, de forma que nosotros solamente deberemos introducir las sentencias que deseemos ejecutar.
El código de un programa se estructura en lo que se denominan módulos, que son ficheros de texto
conteniendo código. Cada una de las fichas de un proyecto tiene asociado un módulo, pudiendo además
existir módulos independientes que nosotros añadamos para definir funciones, procedimientos u objetos.
La edición se realiza en la ventana del Editor de Código, que aparece normalmente bajo la ficha en la que
se está trabajando. Para pasar de la ficha al editor de código o viceversa se pulsa <F12> o se pincha con el
ratón.
El editor de código es multiarchivo, lo que quiere decir que es capaz de mantener abiertos múltiples
módulos de código de forma simultánea.
5) Ejecución.
El fin último de todo el proceso que se está describiendo es conseguir un programa que sea posible
compilar y ejecutar. Para ello pulsaremos <F9> o accederemos a Run desde el menú principal o desde los
botones de acceso rápido.
_____________________________________________________________________________________________
Introducción
La Biblioteca de Componentes Visuales o VCL (Visual Component Library) está formada por objetos
prefabricados, también denominados componentes. Cualquier componente que se incluya en una aplicación pasa a
formar parte de su ejecutable. El uso de componentes visuales permite ahorrar tiempo en la codificación y en las
pruebas de una aplicación, además de ofrecer la posibilidad de darle un aspecto visual.
Un componente es, desde nuestro punto de vista, un elemento de nuestro programa que posee
características (propiedades) y acciones (métodos) asociadas y que reaccionará o no ante una situación producida en
el entorno (evento). Los distintos tipos de componentes (botón, formulario, cuadro de diálogo, menú, etiqueta,
etc…) son facilitados al programador mediante la utilización de la VCL. Cada tipo de componente ofrecerá un
conjunto de propiedades, métodos y eventos predefinidos.
Los eventos son condicionantes ante los cuales el objeto puede reaccionar.
Un componente posee siempre un nombre (Name) que lo diferencia del resto de componentes de una
aplicación. Por defecto, el C++ Builder asigna un valor que tiene relación con el tipo de componente y un número
que los diferencie del resto de componentes.
_____________________________________________________________________________________________
Por ejemplo, para modificar el título de un formulario se puede asignar el valor directamente a la propiedad
Caption desde el Inspector de Objetos o modificarla desde código cuando ocurra un evento o cuando se inicie la
aplicación. El código asociado se incluiría en el código del programa como muestra la figura:
En la tabla siguiente se muestran algunas propiedades comunes a la mayor parte de los componentes
visuales.
Aspecto del Texto Font Valores numéricos o predeterminados para las subpropiedades (color,
altura, tipo de fuente, tipo de espaciado, tamaño en puntos y estilo del
texto).
Estado visual Visible True/false (si se quiere que el componente sea visible o no)
Estado de Acceso Enabled True/false (si el control estárá accesible para el usuario del programa
o no)
_____________________________________________________________________________________________
Acceso al control TabOrder Un número entero entre 0 y el número de controles de ese tipo que
haya en el formulario menos uno.
2. Eventos.
Un evento es una situación que se produce durante la ejecución de un programa. Los eventos pueden
provenir del sistema, del ratón, desde teclado, etc....
Un componente podrá reaccionar ante un evento si el tipo de componente lo tiene así predefinido,
dependiendo del objetivo para el que está diseñado. Por ejemplo, un componente TForm (formulario o ficha)
tiene, por supuesto, un evento asociado a la acción de cerrar (Sistema), en cambio, el componente TButton
(botón) no lo tendrá.
Cuando ocurre un suceso durante la ejecución de nuestro programa, los componentes sobre los que se
produzca reaccionarán o no a este suceso si disponen de un evento que lo detecte. Cuando queramos incluir un
conjunto de sentencias que se ejecuten cuando se produzca un determinado suceso deberemos asociar un
conjunto de instrucciones al evento correspondiente del componente. Este grupo de acciones se expresará en el
código del programa.
C++Builder generará automáticamente la base principal del código que se va asociar al evento, pudiendo
escribir como bloque de instrucciones las sentencias que deseemos. Por ejemplo, si pulsamos en el Inspector de
Objetos del componente formulario (Form1) sobre el evento OnClose (que se produce cuando se cierra el
formulario) aparecerá el editor de código con las líneas:
//------------------------------------------------------------------------
ShowMessage(“Adiós”);
Que hará que al cerrar el formulario (evento OnClose) aparezca en pantalla un cuadro de mensaje con el
texto “Adiós” y el botón de OK.
OnClick.
Se produce al realizarse una pulsación, que puede venir del ratón o del teclado, es decir:
Eventos de ratón.
Cada vez que se mueve el ratón o se pulsa o libera uno de sus botones se produce un evento.
Eventos de teclado.
Algunos controles tienen la capacidad de recibir eventos desde teclado, como un formulario (TForm)
o un control de edición TEdit.
Cada vez que se pulsa una tecla que corresponde directamente con un carácter (letra, número, signo de
puntuación, <Intro>, etc.) se genera un evento OnKeyPress. La función que asociemos a este evento
recibirá un parámetro de tipo char & llamado Key, conteniendo el carácter pulsado.
Existen muchas teclas que no reciben un evento OnKeyPress puesto que no corresponden a un
carácter (por ejemplo, <Insert> o <Supr>). Estas teclas, al igual que las anteriores, siempre generan un
evento OnKeyDown al ser pulsadas y otro OnKeyUp al ser liberadas. El uso de estos eventos se hará
más adelante.
Existen muchos métodos más, como los asociados a operaciones de arrastrar y soltar, por ejemplo,
además de los específicos de cada componente. Estos métodos se irán estudiando mediante ejemplos.
Otros eventos.
Otros eventos son generados por el sistema y se producirán, por ejemplo, para informarnos del estado
de la impresora, de la hora, de una situación de error, etc.
3. Métodos.
Un método es una acción que actúa sobre un determinado componente. Básicamente un método es
una función que recibirá datos o no y devolverá resultados o no. Los más comunes, existentes en
prácticamente todos los componentes, son:
_____________________________________________________________________________________________
Formularios <Nombre_del_Proyecto>.DFM
Recursos <Nombre_del_Proyecto>.RES
Los ficheros con extensión .CPP y .H son los que normalmente podremos modificar puesto que estarán
compuestos de líneas de código en lenguaje C++. Los demás serán creados y mantenidos por el propio C++ Builder.
A continuación se muestra un ejemplo del contenido de los ficheros fuente PROYECT1.CPP, UNIT1.CPP
y UNIT1.H de un programa que solamente presenta un formulario en pantalla y presenta, al cierre del formulario un
mensaje de despedida.
_____________________________________________________________________________________________
Y accediendo en el menú View a la opción Project Source accederemos al código fuente del proyecto:
_____________________________________________________________________________________________
7. Mediante el botón de acceso rápido Toggle Form/Unit acceda a la ventana de código y escriba detrás de
Tform *Form1; la línea int ncolor; con la que
definiremos una variable de tipo entero en nuestro programa.
Esta variable tomará los valores 1, 2, 3 ó 4.
ncolor=1;
Form1->Color=clRed;
_____________________________________________________________________________________________
if (Application->MessageBox("¿Seguro?","Cerrar",MB_YESNO) == ID_NO)
CanClose=false;
El método MessageBox() presenta una ventana con una serie de botones y devuelve un valor indicando
el botón que pulsó el usuario. En nuestro caso hemos puesto una ventana con dos botones (“Sí” y “No”),
asignando al parámetro CanClose el valor false si la respuesta es “no”. Las distintas ventanas que
puede usar este método se irán conociendo mediante ejemplos.
10. Por último, haga doble clic sobre el evento OnClick para hacer que cada vez que se pulse el ratón
aparezca el fondo del formulario de uno de los colores del parchís. Para ello escriba el código:
void __fastcall TForm1::FormClick(TObject *Sender)
switch (ncolor)
break;
case 2:Color=clYellow;
break;
case 3:Color=clGreen;
break;
default:Color=clRed;
ncolor=0;
ncolor++;
Guardar el programa con el nombre PE1.BPR (Proyecto) y E1.CPP (Unidad). Ya basta depurar los
posibles errores de compilación, linkado y ejecución para ejecutar el programa. La ventana de nuestro programa
tendrá la siguiente apariencia al solicitar su cierre:
_____________________________________________________________________________________________
Ejercicios a realizar.
- Basándonos en el ejercicio anterior, añadir el código necesario para que aparezca una
ventana de despedida de la aplicación con el texto “Adiós”.
- Basándonos en el ejercicio anterior, realizar pruebas, accediendo a la ayuda <F1>, con las
propiedades:
BorderIcons HorzScrollBar Height
AutoScroll Font
_____________________________________________________________________________________________
Los componentes pueden ser visuales y no visuales. Los visuales tienen prácticamente el mismo aspecto al
diseñar la ficha que al ejecutarla (un botón, una etiqueta, etc...), mientras que los no visuales no se ven en tiempo de
ejecución. Un ejemplo de componente no visual lo encontramos en Timer de la página System, que en fase de
diseño ofrece una representación visual de la función que los temporizadores proporcionan a la función, mientras
que en tiempo de ejecución el temporizador mide los intervalos pero no es un elemento visible de la interfaz.
Label S Crear un control sin ventana que muestre texto no accesible para el usuario,
como los títulos. Suele tratarse de texto que actúa como etiqueta de control.
Edit S Presentar un área donde el usuario pueda introducir o modificar una sola línea
de texto (cuadro de edición).
Memo S Presentar un área donde el usuario pueda introducir o modificar varias líneas
de texto (cuadro memo).
Button S Crear un botón que los usuarios puedan seleccionar para realizar una operación
(por ejemplo, interrumpir, iniciar o cancelar un proceso).
CheckBox S Crear una casilla de verificación, que representan alternativas del tipo Sí/No,
Verdadero/Falso o Activado/Desactivado. Las casillas de verificación son
independientes entre sí, ya que las opciones que representan no son
mutuamente exclusivas.
ListBox S Mostrar una lista de opciones de las cuales el usuario puede seleccionar una o
varias (cuadro de lista).
_____________________________________________________________________________________________
ScrollBar S Crear una barra de desplazamiento para poder desplazar en pantalla la parte
visible de una lista o ficha, o trasladarse por un rango en incrementos.
GroupBox S Crear un cuadro de grupo para agrupar componentes relacionados en una ficha.
Panel S Agrupar en un panel otros componentes, como botones rápidos en una barra de
herramientas. También se emplea para crear barras de estado.
En la pantalla siguiente aparecen ejemplos del aspecto que en tiempo de ejecución tienen todos los
componentes de la paleta Standard que pueden incluirse en un formulario:
_____________________________________________________________________________________________
Un botón puede contar con una tecla de acceso rápido que, utilizada con la tecla <Alt>, permite pulsar el
botón sin necesidad de desplazarse a él. Esta tecla será uno de los caracteres que forman parte del título, al que se le
antepondrá el carácter &, apareciendo subrayado.
En un formulario pueden existir varios botones. De todos ellos dos pueden ser activados de una forma
especial que consiste en pulsar la tecla <Intro> o la tecla <Esc>.Si la propiedad Default tiene el valor true el
botón actuará como botón por defecto, es decir, que se activará cuando se pulse la tecla <Intro>. Si Cancel está a
true, el botón será el botón de cancelación (tecla <Esc>). Por supuesto, no puede haber más de un botón con estas
propiedades a true dentro del mismo formulario.
El evento principal de un botón es OnClick (evento de pulsación). Lo normal es que se asocie un método
al evento OnClick de un botón, ejecutando el código que proceda en el momento en que el usuario lo pulse.
Una etiqueta –Label- es un control que presenta un texto en el formulario (Caption) pero que no puede
tomar el foco de entrada ni podemos acceder a él con la tecla <Tab>. Sólo recibe eventos de ratón.
Las propiedades más comunes de una etiqueta son, además de las que definen su aspecto (Width,
Color, etc..), son:
A derecha: taRightJustify
Centrado: taCenter
FocusControl Tiene sentido cuando la etiqueta se usa como título de otro Nombre del control que
control. Sirve para que la etiqueta de texto sepa a qué control recibe el foco.
debe pasar el foco de entrada cuando se pulse la tecla de acceso
rápido (&).
Transparent Para tomar como color de fondo el del componente que lo True/false
contiene.
_____________________________________________________________________________________________
Color clAqua
2. Insertar una etiqueta y dar el valor false a la propiedad AutoSize y redimensionar su tamaño de forma
que ocupe prácticamente todo el ancho del formulario. Asignar a la etiqueta el Color clYellow. Verificar
que la propiedad Alignment tiene el valor taLeftJustify. Asignar a Caption el valor “Soy la etiqueta”.
4. Asignar true a la propiedad Default del primer botón (justificación izquierda) y true a la propiedad
Cancel del tercer botón (justificación a la derecha)
5. Hacer clic en el evento OnClick del primer botón y asignar, mediante código, el valor taLeftJustify a la
propiedad Alignment de la etiqueta.
6. Hacer lo mismo con el resto de los botones asignando los valores taCenter y taRightJustify en los eventos
de pulsación del segundo y tercer botón, respectivamente.
8. Mejorar la aplicación anterior permitiendo acceder con teclas rápidas a cada uno de los botones y establecer
el color de fondo de la etiqueta al que actualmente tenga el formulario cuando el ratón esté situado sobre la
misma.
La apariencia que deberá tener la ventana del proyecto con esta última mejora es la siguiente:
_____________________________________________________________________________________________
Cuando en ejecución el usuario modifica el contenido de un Edit, la propiedad Modified de éste toma
el valor true. Desde el código de nuestro programa podemos comprobar el valor de esta propiedad y, en caso de
que proceda, recuperar la entrada realizada por el usuario leyendo la propiedad Text.
Por defecto el control Edit no pone ningún límite a la cantidad de texto que el usuario puede introducir y,
en caso de que sea necesario, desplazará el contenido actual del control a medida que se introducen nuevos
caracteres. Si se desea, se puede limitar el número de caracteres que es posible introducir mediante la propiedad
MaxLength. El valor 0 indica que no hay un límite establecido y cualquier otro número entero fija la longitud
máxima de la propiedad Text.
Selección de texto
Mientras se edita el contenido de un control Edit, el usuario puede marcar una porción del texto, mediante
la combinación de la tecla <Mayus> y los cursores o bien con el ratón, con el fin de realizar alguna operación
que le afecte, como puede ser eliminarlo o copiarlo al portapapeles.
En cualquier momento podemos saber qué texto es el que hay seleccionado en el control, para lo que
disponemos de las propiedades SelStart, SelLength y SelText. La primera contiene el carácter a partir
del cual se ha seleccionado, sabiendo que el primero de los existentes es el carácter 0. La segunda propiedad
contiene el número de caracteres que hay marcados y la tercera contiene el texto.
El valor de estas propiedades también puede ser establecido por el código de nuestro programa,
seleccionando automáticamente el texto que nos interese. Si deseamos marcar todo el texto contenido en el
control podemos realizar una simple llamada al método SelectAll().
Las operaciones de copiar, cortar y pegar con el portapapeles, pueden ser también realizadas mediante
código gracias a la existencia de varios métodos al efecto. El método ClearSelection() elimina el texto
que hay seleccionado (cómo si el usuario hubiera pulsado la tecla <Supr>). El método CopyToClipboard()
copia el texto al portapapeles, mientras que CutToClipboard() lo copia al portapapeles y lo elimina del
campo de edición. PasteFromClipboard(), finalmente, nos permite recuperar el texto que hay en el
portapapeles insertándolo en Edit en la posición actual del cursor.
Si lo que queremos es solamente mostrar un valor en un campo de edición e impedir que el usuario pueda
modificarlo bastará asignar a la propiedad ReadOnly el valor true.
Si lo que queremos es que al solicitar cualquier tipo de dato éste no sea visible por terceras personas, por
ejemplo, cuando se solicita una clave de acceso a una aplicación, mediante la propiedad PasswordChar
podemos conseguir que el campo de edición vaya representando cada uno de los caracteres introducidos
mediante un cierto símbolo, como puede ser un asterisco. En realidad se puede asignar a esta propiedad
cualquier carácter.
Controles de entrada
La introducción de ciertos datos puede requerir que todas las letras sean facilitadas en mayúsculas o en
minúsculas con el fin de evitar posteriores fallos de comparación. Mediante la propiedad CharCase podemos
_____________________________________________________________________________________________
El componente Edit no realiza ningún tipo de comprobación previa a la admisión de los caracteres que el
usuario pueda introducir. Sin embargo, éste es un aspecto que podemos controlar nosotros mismos gracias a
que cada vez que el usuario pulsa una tecla, y justo antes de que el correspondiente carácter sea almacenado en
la propiedad Text, el Edit genera un evento OnKeyPress, en el que podemos realizar las comprobaciones
necesarias.
El evento OnKeyPress recibe un parámetro por referencia con el carácter pulsado, de forma que
podemos tanto comprobar su contenido como modificarlo o ignorarlo asignando el carácter nulo.
________________________________________
En la práctica, vamos a partir insertando en un formulario tres campos de edición (Edit), que estarán
encabezados por tres etiquetas (Label) y tres botones (Button). El aspecto del formulario será el que se
muestra a continuación:
El primer control Edit, que recibirá el foco desde la etiqueta Label1 (propiedad FocusControl de la
etiqueta) lo utilizaremos para comprobar el funcionamiento de las propiedades MaxLength, a la que
asignaremos el valor 10, y PasswordChar, a la que asignaremos el valor *.
A continuación tenemos el segundo Edit, que recibirá el foco desde Label2 y que usaremos para ver cómo
podemos controlar la entrada de caracteres, permitiendo tan sólo la introducción de dígitos numéricos. Abra la
página de eventos en el Inspector de Objetos de ese control y haga doble clic sobre el evento OnKeyPress,
escribiendo el código que se muestra a continuación:
Void__fastcall Tform1::Edit2KeyPress(Tobject *Sender,char &Key)
El último control Edit (recibe el foco de Label3) lo utilizaremos para probar los métodos de copiar, borrar y
_____________________________________________________________________________________________
Edit3->SelectAll();
Edit3->CopyToClipboard();
Edit3->SetFocus();
Edit3->ClearSelection();
Edit3->SetFocus();
Edit3->PasteFromClipboard();
Edit3->SetFocus();
Observe que tras realizar la operación se hace una llamada al método SetFocus(), con el fin de devolver el
foco de entrada al control Edit3.
Tipos de propiedades
Cada propiedad de un componente de la VCL tiene asignado un tipo de dato. Este tipo de dato determinará
los posibles valores que puede tomar. Por ejemplo, la propiedad Visible es de tipo bool y, por ello, sólo puede tomar
los valores true o false, en cambio, la propiedad Caption es de tipo cadena, pudiendo tomar como valor cualquier
texto.
Existen propiedades de tipo enumerado, que son aquellas que solamente pueden tomar valores de una lista
prefijada. Un ejemplo de ello es la propiedad BorderStyle de un formulario en cuya página de ayuda
observamos lo siguiente:
Donde
quiere decir que la propiedad BorderStyle de un formulario es del tipo TFormBorderStyle, un tipo
enumerado, y que, por tanto, sólo puede tomar los 6 valores preestablecidos.
En el caso de los tipos enumerados, es posible referirse a los valores con su propio nombre, p.ej.
_____________________________________________________________________________________________
static_cast<tipo_de_dato_enumerado>(posición_del_valor)
Así pues, la propiedad BorderStyle de un formulario podría modificada de las siguientes formas:
BorderStyle=bsSingle;
3) Transformando, mediante código, un número entero (en este caso 0,1,2,3,4 o 5) en un valor concreto.
BorderStyle= static_cast<TFormBorderStyle>(1)
El control TMemo:
El control TEdit es el de uso más habitual cuando en un programa es necesario solicitar una entrada del
usuario, pero esa entrada no puede exceder una línea. Cuando necesitemos una entrada de texto más amplia que
ocupe varias líneas podemos usar un control TMemo.
Este control cuenta con muchas propiedades que ya hemos visto trabajando con un TEdit, como
ReadOnly, MaxLength, Text, ..., así como con los métodos relacionados con las operaciones del portapapeles.
Un control TMemo puede contar con barras de desplazamiento, permitiendo trabajar con líneas más largas
que el espacio horizontal disponible y con más líneas de las que es posible mostrar de forma simultánea. La
propiedad TScrollBars permite el uso de estas barras de desplazamiento. Esta propiedad es de tipo
TScrollStyle, que es un tipo enumerado, es decir, que sólo puede tomar los valores:
0 ssNone
1 ssVertical
2 ssHorizontal
3 ssBoth
El texto almacenado en un control TMemo es accesible mediante la propiedad Text, al igual que en un
control TEdit. Sin embargo, es conveniente e incluso más útil poder acceder a ese texto línea a línea. Para ello, el
control TMemo cuenta con la propiedad Lines que es de tipo TStrings. Este tipo de objetos tiene dos métodos
muy interesantes con relación a un control TMemo que sirven para guardar o recuperar las líneas de texto en un
archivo en disco. Estos métodos son SaveToFile() y LoadFromFile(), que solamente toman como único
parámetro el nombre del fichero donde se va a guardar o del que se va a recuperar.
También podemos saber en cada momento con cuántas líneas cuenta un control TMemo mediante la
propiedad Count del objeto TStrings, de la forma:
Memo1->Lines->Count
_____________________________________________________________________________________________
Un control TMemo, mientras está activo, puede permitir el uso de las teclas <Intro> y <Tab> como parte de
la edición de texto, pero estas teclas tienen un funcionamiento especial dentro de un formulario. Para que al pulsarse
la tecla <Intro> el control TMemo la reconozca como salto de línea y no como activación del botón por defecto, por
ejemplo, es necesario asignar el valor true a la propiedad WantReturns. Lo mismo ocurre con la propiedad
WantTabs, que si está activada permitirá insertar tabulaciones en el texto en lugar de pasar el foco de entrada al
siguiente componente del formulario.
El control TCheckBox
El control TCheckBox es adecuado para mostrar y permitir la entrada de cualquier información de tipo
bool que es posible representar con tan sólo dos estados (sí o no, verdadero o falso, activado o desactivado). Los
dos estados posibles se muestran visualmente mediante una casilla, que puede contener o no en su interior una
marca.
La propiedad Checked es la más importante de este control, ya que nos permite tanto saber el estado
actual del control como modificarlo. Estará a true cuando el control esté marcado y a false en caso contrario.
Podemos tener tantos controles TCheckBox en un formulario como queramos. El hecho de que alguno de
ellos esté activo no afecta a los demás, es decir, las opciones que representan no son exclusivas entre sí. Para que
varias opciones sean excluyentes se necesitan controles TRadioButton.
Normalmente, los controles TCheckBox se suelen agrupar en un contenedor TGroupBox con el fin de
asignar un título común a los componentes TCheckBox que afecten a un mismo tema.
Como se dijo anteriormente, a veces nos puede interesar representar opciones de tipo bool que son
exclusivas entre sí, de forma que sólo sea posible seleccionar una de ellas, al tiempo que, obligatoriamente, una debe
estar activa. En este caso utilizaríamos controles TRadioButton, que son muy similares a los controles
TCheckBox tanto en aspecto como en funcionamiento. Así pues, este control también cuenta con una propiedad
Checked en la que se almacena el estado del control.
Si tenemos varios controles TRadioButton en un formulario, ¿qué ocurre si queremos solicitar varios
datos diferentes que tengan, a su vez, opciones exclusivas entre sí?. Pues que deberemos agrupar los controles
TRadioButton que representen una misma finalidad dentro de un TRadioGroup, que, además, permite asignar
un título (Caption) al grupo de botones.
Un control TRadioGroup es capaz de almacenar múltiples elementos, cada uno de los cuales se muestra
como un TRdioButton independiente. Para establecer las opciones existentes en un control TRadioGroup
tendremos que editar el contenido de la propiedad Items. Esta propiedad (al igual que la propiedad Lines de un
campo TMemo) es del tipo TStrings.
En modo de diseño basta con hacer doble clic sobre la propiedad Items para abrir el editor específico con
el que cuenta, añadiendo los títulos de las opciones que deseemos mostrar. En ejecución podremos usar los métodos
Add(), Append(), Insert() y Clear() para añadir o eliminar elementos.
Los elementos existentes en un control TRadioGroup se numeran con un índice cuyo punto de partida es
el 0. Este índice nos servirá para saber qué opción es la que está activa o bien para establecerla, mediante la
propiedad ItemIndex. De esta forma no es necesario comprobar la propiedad Checked de cada uno de los
_____________________________________________________________________________________________
En la práctica
- Comenzar una nueva aplicación e incluir, en fase de diseño, los siguientes componentes:
o Un TLabel
o Un TMemo
o Un TGroupBox
o Dos TCheckBox dentro del TGroupBox
o Un TRadioGroup
o Dos TButton
- Salvar el proyecto (Save All) con los nombres: E4.CPP (para la unidad) y PE4 (para el proyecto).
- Continuar los pasos necesarios para conseguir como código fuente de la unidad lo siguiente:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "E4.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
_____________________________________________________________________________________________
Label1->Caption="&Texto";
Label1->FocusControl=Memo1;
Memo1->Lines->Clear();
Memo1->WantReturns=true; //Por defecto
Memo1->WantTabs=false; //Por defecto
Memo1->ScrollBars=ssNone; //Por defecto
GroupBox1->Caption="Permitir ...";
CheckBox1->Caption="Tabulación";
CheckBox1->Checked=false;
CheckBox2->Caption="Retorno de carro";
CheckBox2->Checked=true;
RadioGroup1->Caption="Barras de Desplazamiento";
RadioGroup1->Items->Add("Ninguna");
RadioGroup1->Items->Add("Horizontal");
RadioGroup1->Items->Add("Vertical");
RadioGroup1->Items->Add("Ambas");
RadioGroup1->ItemIndex=0;
Button1->Caption="&Guardar texto";
Button2->Caption="&Recuperar texto";
Button2->Enabled=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
Memo1->WantTabs=CheckBox1->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CheckBox2Click(TObject *Sender)
{
Memo1->WantReturns=CheckBox2->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RadioGroup1Click(TObject *Sender)
{
Memo1->ScrollBars=static_cast<TScrollStyle>(RadioGroup1->ItemIndex);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Memo1->Lines->SaveToFile("memo.txt");
Button2->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Memo1->Lines->LoadFromFile("memo.txt");
}
//---------------------------------------------------------------------------
Otro de los controles que nos permite mostrar listas de elementos de las cuales es posible seleccionar uno o
varios es TListBox. Este control se conoce como lista, un recuadro en el cual aparecen una serie de líneas de texto
siendo posible la selección de una o varias de ellas. El funcionamiento de este control es parecido al del
TRadioGroup, aunque visualmente su aspecto es bastante diferente.
Los elementos con los que cuenta una lista están contenidos en la propiedad Items, que, como sabemos,
es un objeto de tipo TStrings. En modo de diseño podemos usar el editor de código asociado para incluir los
elementos que queramos en la lista simplemente haciendo doble clic sobre la propiedad Items. En cambio, en
modo de ejecución, podemos usar los métodos siguientes:
Método Explicación
Add() Toma como parámetro una cadena de texto, añadiéndola como nuevo elemento al final de la
lista, salvo si la propiedad Sorted de la lista está a true, en cuyo caso se insertará en la
posición que le corresponda.
Insert() Toma dos parámetros, indicando el primero la posición en la que se desea insertar el elemento
y el segundo el texto a añadir.
Delete() Este método nos permite eliminar un elemento de la lista, para lo cual deberemos facilitar su
índice.
Clear() No necesita parámetros. Elimina todas las cadenas existentes en la lista.
IndexOf() Toma como parámetro una cadena, devolviendo el índice que ésta ocupa en la lista o –1 en
caso de no encontrarse.
Move() Facilita el desplazamiento de un elemento de una posición a otra, para lo cual deberemos
facilitar el índice en que se encuentra actualmente y el índice correspondiente al punto al que
se desea mover.
Exchange() Este método es similar al anterior, tomando como parámetros dos índices con el fin de
intercambiar las posiciones de los elementos correspondientes.
SaveToFile() Guarda el contenido de la lista a un archivo en disco, cuyo nombre deberemos facilitar.
LoadFromFile() Recupera la lista de elementos de un archivo cuyo nombre se facilita como parámetro.
La propiedad ItemIndex de este control permite saber en cada momento qué elemento hay seleccionado
(igual que en un TRadioGroup). El valor –1 indica que en ese momento no hay ninguno.
Cuando una lista contiene más elementos de los que le es posible mostrar de forma simultánea,
automáticamente aparece una barra de desplazamiento vertical que nos permite acceder al contenido completo de la
propiedad Items. Podemos determinar, entonces, cuál es el primer elemento que está visible en un determinado
momento, en la parte superior de la ventana, mediante la propiedad TopIndex, que almacena el índice de dicho
elemento.
Al desplazar los elementos que contiene la lista podemos observar, posiblemente que el elemento que está
en la parte superior o el situado en la parte inferior aparecen cortados, viéndose sólo un trozo de texto. Esto se debe
a que el alto de la lista no es un múltiplo de la altura de cada elemento. Esto se soluciona asignando el valor true a
la propiedad IntegralHeight.
El programa ejemplo que vamos a realizar nos permitirá añadir elementos a una lista en ejecución con el
texto que se facilite en un campo de edición. También se podrá eliminar el elemento seleccionado o vaciar
totalmente la lista. Los elementos podrán aparecer ordenados o no, según el valor de un campo CheckBox.
- Insertar en el formulario los controles necesarios para que la ventana tenga la siguiente apariencia:
_____________________________________________________________________________________________
- Dar el valor true a la propiedad Default del primer botón, haciendo así que la pulsación de la tecla
<Intro> tenga como resultado la inserción en la lista del elemento cuyo texto se ha introducido en el
TEdit.
- Asignar el valor false a la propiedad Enabled del segundo botón, ya que sólo debe estar activo cuando
haya un elemento seleccionado.
_____________________________________________________________________________________________
Básicamente, un TComboBox incorpora las funciones de ambos controles y, por tanto, cuenta con
propiedades que ya conocemos como Text, MaxLenggth, Items, ItemIndex, etc. Tanto el aspecto como
el funcionamiento de una lista combinada dependerá del estilo que tenga, el cual dependerá del valor que se
asigne a la propiedad Style. Esta propiedad, de tipo TComboBoxStyle, puede tomar 5 valores de los cuales
solamente vamos a estudiar los siguientes:
En la práctica vamos a diseñar un programa que presentará una ventana con la siguiente apariencia:
_____________________________________________________________________________________________
Deberemos controlar cada pulsación de tecla sobre el TComboBox, mediante el evento OnKeyPress,
para que en el momento en que se detecte la pulsación de la tecla <Intro> se proceda a la inserción del texto en
la lista, ignorando la pulsación. El código que deberemos escribir es el siguiente:
Por último, asignaremos el valor 0 a la propiedad ItemIndex del TRadioGroup y deberemos controlar
su evento OnClick con el fin de establecer el estilo adecuado para la lista combinada según la opción que se
seleccione. Esta asignación se realizará de forma directa llevando a cabo una conversión de tipo de la forma
siguiente:
Lista de Ejercicios
1. Realizar mejoras sobre el ejercicio anterior de forma que...
2. Diseñar un programa que presente un formulario para la introducción de los siguientes datos acerca de una
persona:
_____________________________________________________________________________________________
Los errores de compilación son detectados por C++ Builder en el momento en que se compila el
programa. En estos casos no se permite la ejecución y en la parte inferior del Editor de Código se abre una lista con
la descripción de los errores encontrados, permitiéndonos el desplazamiento a la línea apropiada. Estos errores se
producen cuando se teclea mal el nombre de un identificador, hemos olvidado cerrar un paréntesis, etc.
Por su parte, los errores de ejecución no son detectables durante la compilación y surgen de forma
esporádica mientras el programa se ejecuta. Si no está adecuadamente controlado, un error de ejecución puede
terminar interrumpiendo la ejecución de la aplicación. Estos errores se producen, por ejemplo, cuando se intenta usar
un archivo inexistente, se pretende dividir por 0, etc. Es decir, no son detectados por el compilador porque más que
errores del programa son errores que vienen provocados por alguna causa externa.
Cuando estas excepciones se producen, automáticamente aparece un cuadro de diálogo en el que se informa
al usuario del error producido, pero aparece en inglés y de forma que no siempre el usuario puede entender, además
de que se produce una parada en el módulo donde se ha producido el error y las siguientes instrucciones no llegan a
ejecutarse. Una de las formas, por tanto, más eficientes de controlar los errores de ejecución consiste en interceptar
las excepciones que producen, actuando en consecuencia.
En el código de un programa sólo algunas sentencias son susceptibles de generar errores de ejecución. Una
simple asignación a una variable, por ejemplo, no suele generar una excepción, en cambio, el acceso a un dispositivo
externo o una división, sí puede generar tal excepción, puesto que el archivo puede no existir o el dividendo puede
ser 0.
Lo primero que hay que hacer, por tanto, para controlar los errores de ejecución es identificar los bloques de
código en que pueden tener lugar las excepciones, ya que serán estos bloques los que hay que proteger mediante la
construcción try/catch.
La sintaxis de try/catch es la que se muestra en el fragmento siguiente, en el que podemos distinguir unas
sentencias a proteger, que son las dispuestas detrás de la palabra try, y unas sentencias que se ejecutarán sólo en
caso de que se produzca una excepción, que son las escritas a continuación de la palabra catch. La construcción se
finaliza con el cierre de llaves, de tal forma que la ejecución siempre continuará con la sentencia siguiente, tanto si
se ha generado la excepción como si no.
try
{
SentenciaAProteger;
}
catch (...)
{
SentenciaDeControl;
}
Tanto tras la palabra try como tras la palabra catch podemos disponer múltiples sentencias.
Clases de excepciones
Normalmente, después de la palabra catch basta escribir tres puntos entre paréntesis para detectar cualquier
excepción, de la forma: catch (...)
_____________________________________________________________________________________________
Las excepciones, al igual que otros muchos elementos de C++Builder, son objetos que tienen cierta jerarquía,
existiendo una clase de excepción base o genérica de la cual se van derivando clases más específicas. Existe, por
ejemplo, una clase de excepción llamada EIntError de la que están derivadas todas las clases de excepciones
relacionadas con números enteros, como ERangeError o EDivByZero.
Para controlar la clase de excepción, detrás de la palabra catch, y entre paréntesis, podemos disponer el nombre
de la clase de excepción a gestionar, por ejemplo, catch (EDivByZero &). El código dispuesto en el bloque
siguiente se ejecutará tan sólo en caso de que la excepción que se ha producido sea de la clase indicada. Podemos
usar varios apartados catch para interceptar excepciones de diferentes clases.
En la práctica, para comprobar el funcionamiento de las excepciones y ver cómo podemos controlarlas, vamos a
diseñar un pequeño programa que nos permita presentar en pantalla una imagen que será tomada de un archivo con
extensión .bmp.
Para ello debemos insertar un TImage (de la paleta Additional) con las propiedades AutoSize y
Center a true y un control TEdit (de la paleta Standard). Al evento OnKeyPress del control TEdit
asociaremos el código apropiado en caso de que el usuario pulse <Intro>; es decir, asignaremos como imagen el
nombre del fichero que se ha escrito en el campo TEdit, controlando que no exista o no sea un archivo reconocible
por un TImage. El código sería el siguiente:
La apariencia de la aplicación en ejecución, en caso de que exista el archivo y sea reconocible como
archivo imagen, sería la siguiente:
_____________________________________________________________________________________________
Ejercicio Propuesto.-
Realizar una aplicación que permita realizar divisiones de números enteros, para lo que tendremos que
facilitar el dividendo y el divisor. La apariencia de la ventana en ejecución será la siguiente:
Habrá que asignar el valor true a la propiedad ReadOnly del campo de edición correspondiente al
cociente, ya que éste será solo para mostrar el resultado de la operación y no para que el usuario introduzca
un valor.
Habrá que seleccionar conjuntamente los dos primeros controles Tedit (de Dividendo y Divisor) para
asignarles el mismo código asociado a su evento OnKeyPress, con el fin de controlar la entrada de
caracteres.
Cuando se pulse clic sobre el botón Calcular habrá que proteger las excepciones posibles en los siguientes
casos:
_____________________________________________________________________________________________
_____________________________________________________________________________________________
Una de las formas más tradicionales y eficientes de mostrar las distintas opciones de que dispone un
programa consiste en construir un menú. Existen básicamente dos tipos de menús: principal y emergente.
Un menú principal es aquel que se muestra en la parte superior del formulario, justo debajo de la barra de
título, y que cuenta con una serie de opciones principales que son las visibles en cada momento, en base a las cuales
es posible acceder a la lista de subopciones.
El menú emergente, por el contrario, no está visible normalmente, apareciendo tan sólo cuando el código
de programa lo solicita. C++ Builder es capaz de establecer una asociación entre un componente y un menú
emergente, mostrando este último en el momento en que se pulsa el botón derecho del ratón sobre dicho
componente.
El siguiente paso consistirá en diseñar el menú, para lo cual tendremos que hacer doble clic sobre el propio
componente TMainMenu o bien sobre el valor de su propiedad Items, en el Inspector de Objetos. En ambos casos
aparecerá el Editor de Menús, una ventana en la que podremos ir introduciendo opciones y desplazándonos entre
ellas construyendo nuestro menú.
Inicialmente el Editor de Menús aparecerá vacío, mostrando tan sólo un recuadro en el que podremos
iniciar la introducción del título de la opción que deseemos definir. Observe que en el Inspector de Objetos existen
una serie de propiedades que hacen referencia a la opción que se está definiendo.
Introduzca el título de la primera opción principal, que se llamará por ejemplo &Archivo, y pulse la tecla
<Intro>, lo que le desplazará a la línea siguiente, en la que podrá iniciar la introducción de las subopciones. Vamos a
añadir tres opciones, a las que vamos a llamar &Guardar, &Recuperar y &Salir.
En cualquier momento podemos eliminar opciones del menú e insertar otras nuevas entre algunas
existentes. La primera operación la realizaremos simplemente pulsando la tecla <Supr>, mientras que la segunda la
efectuaremos con una pulsación de la tecla <Insert>.
Sitúese encima de la última opción que hemos insertado, &Salir, y pulse la tecla <Insert>, lo que provocará
la apertura de un espacio en blanco. Inserte en ese espacio un guión y pulse <Intro>, verá cómo automáticamente en
el menú aparece una línea de separación entre las dos primeras opciones y la última.
Además de las letras que precedemos con un signo & en los títulos de las opciones y que pueden ser
utilizadas conjuntamente con la tecla <Alt> para acceder de una forma rápida, cada opción puede contar además con
una tecla "caliente" o de acceso rápido.
_____________________________________________________________________________________________
Ciertas opciones de un menú pueden dar acceso a otras listas de opciones, lo cual se indica mediante una
flecha apuntando hacia la derecha. El ejemplo más cercano lo podemos encontrar en la opción Reopen del menú
File de C++ Builder.
Para añadir una lista de opciones a una opción del menú deberemos pulsar la combinación <Control-Flecha
derecha>, o bien desplegar el menú emergente y seleccionar la opción Create Submenu. En cualquiera de los
casos se abrirá una nueva lista a la derecha de la que ya teníamos, en la que podemos introducir las opciones que
deseemos.
Al igual que un botón o una lista, un menú genera el evento OnClick cuando se selecciona una cierta
opción. Para acceder al código del método asociado a una de las opciones existentes lo único que tenemos que hacer
es seleccionarla en modo de diseño en el mismo formulario, tras haber cerrado el editor de menús. También
podemos hacer doble clic sobre la opción deseada en el propio Editor de menús, continuando posteriormente con la
tarea de diseño.
Observe que cada una de las opciones de un menú es un objeto diferente, concretamente de tipo
TMenuItem, y por lo tanto genera su propio evento.
Como se comentaba anteriormente, un menú emergente puede ser desplegado automáticamente, al pulsar el
botón derecho del ratón sobre el componente al que esté asociado, o bien ser abierto desde código, con una llamada
al método Popup() del propio TPopupMenu. Al llamar a dicho método pasaremos como parámetros dos enteros,
indicando la posición en la que deseemos hacer aparecer la ventana. El método más habitual es el primero y también
el más cómodo y simple.
Para conseguir que un menú emergente se despliegue de forma automática lo primero que tenemos que
hacer es dar el valor true a la propiedad AutoPopup, valor que tiene por defecto. El segundo paso consistirá en
crear un enlace entre un componente y el menú, para lo cual asignaremos a la propiedad PopupMenu del
componente el nombre del TPopupMenu. Es posible asociar un TPopupMenu al formulario, a un botón o a,
prácticamente, cualquier otro control. Algunos componentes suelen tener ya asociado un PopupMenu por defecto,
que, a no ser que se indique lo contrario o se asigne otro menú emergente, aparecerá de forma automática al pulsar el
botón derecho del ratón. Esto último puede comprobarse en un campo TMemo, que, por defecto, tiene asociado un
menú emergente con las típicas opciones de edición, como Deshacer, Copiar, Pegar, Eliminar, ...
En la práctica
Para practicar con el diseño y uso de menús vamos a realizar un proyecto que permita al usuario introducir
información en el archivo “memo.txt” . Para ello insertaremos un menú principal con dos opciones: Archivo y
Herramientas. La opción Archivo contará con las opciones Recuperar (accesible sólo si ya se ha guardado la
_____________________________________________________________________________________________
En fase de diseño ésta será la apariencia de la primera opción del menú principal:
_____________________________________________________________________________________________
La marca delante de la subopción “Retorno de Carro” se consigue asignando el valor true a la propiedad
Checked, propiedad que modificaremos según se pulse o no la opción (actuaría como un CheckBox).
Por último, después del diseño del menú principal, habrá que insertar un control TMemo sobre el formulario
donde se pueda editar el texto que desee el usuario. Este control aparecerá ocupando todo el espacio disponible del
formulario o ficha. Para ello asignaremos a su propiedad Align el valor alClient.
A continuación se muestra el código fuente que tiene que asociarse al proyecto. El alumno debe interpretar cada
una de las funciones y acceder a ellas según el evento correspondiente:
//------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Menu.h"
//------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Recuperar1->Enabled=false;
}
//------------------------------------------------------------------------
void __fastcall TForm1::Recuperar1Click(TObject *Sender)
{
Memo1->Lines->LoadFromFile("memo.txt");
}
//------------------------------------------------------------------------
void __fastcall TForm1::Guardar1Click(TObject *Sender)
{
Memo1->Lines->SaveToFile("memo.txt");
_____________________________________________________________________________________________
_____________________________________________________________________________________________
Una vez vistos todos los componentes de la paleta Standard, vamos a estudiar algunos otros que van a
facilitar al usuario el uso de nuestras aplicaciones.
En algunos ejercicios realizados hasta el momento ha sido necesario facilitar el nombre de un archivo en disco,
con el fin de recuperar o guardar información en él. En estos ejemplos el nombre del archivo era fijo o se solicitaba
mediante un campo de edición. Para que el usuario del programa pueda elegir el archivo deseado, los controles que
vamos a estudiar permitirán la selección de una unidad disponible en el sistema, el desplazamiento por los
directorios de ésta y la selección de un archivo determinado, todo ello de forma visual, sin necesidad de tener que
escribir código alguno. Estos componentes están en la página Win 3.1 de la paleta de componentes.
Por último, estudiaremos el uso del reloj. Para ello veremos las propiedades y eventos del componente TTimer
de la paleta System.
Los tres controles que vamos a conocer aparecen en la paleta Win 3.1 y son derivados de TComboBox o
TListBox, contando con muchas propiedades que ya conocemos, como Items, ItemIndex, Text, etc.
El control TDriveComboBox es una lista combinada en la que se muestran las unidades de disco disponibles
en el sistema, pudiendo seleccionar cualquiera de ellas. Este control toma los elementos automáticamente en el
momento de la creación inspeccionando el sistema.
Como cualquier otra lista, podemos obtener el texto de cada uno de los componentes accediendo a ellos
mediante la propiedad Items y saber qué elemento es el que está seleccionado a través de ItemIndex. Sin
embargo, la propiedad que más nos interesará será Drive, de tipo char, que contiene la letra correspondiente a la
unidad seleccionada en cada momento. Esta letra podrá ser mayúscula o minúscula, dependiendo del valor que
asignemos a la propiedad TextCase, que puede ser tcLowerCase o tcUpperCase.
Se usa para mostrar una lista de directorios y como su nombre indica es un derivado de TListBox. Este
control muestra la jerarquía de directorios correspondiente a la unidad facilitada en la propiedad Drive,
permitiendo el cambio de un directorio a otro.
La propiedad más interesante es Directory, ya que mediante ella podemos recuperar el camino
completo que está actualmente seleccionado, sin necesidad de tener que acceder a los elementos de la lista
individualmente. Este directorio puede ser mostrado automáticamente en un control TLabel simplemente
asignando a la propiedad DirLabel el nombre de la etiqueta.
_____________________________________________________________________________________________
El último de los tres controles, TFileListBox, nos permite ver los archivos existentes en un cierto
camino que habremos de facilitar en la propiedad Directory. Este valor se toma automáticamente si este control
está asociado a un TDirectoryListBox.
Aunque por defecto se muestran todos los archivos que hay en el directorio, podemos limitar esta selección
modificando el contenido de la propiedad Mask, a la que asignaremos una cadena conteniendo una o más
referencias de selección. En caso de que sean varias deberemos separarlas mediante un punto y coma (por ejemplo
*.bmp;*.ico).
También podemos limitar los archivos mostrados en el TFileListBox según sus atributos, mediante la
propiedad FileType. Esta propiedad es un conjunto que puede contener true/false en los conceptos que se
muestran a continuación, según los cuales se seleccionarán unos archivos u otros.
ftHidden Ocultos
ftSystem De sistema
ftDirectory Directorio
ftArchive Archivo
En la práctica
Vamos a realizar un ejercicio que permita visualizar archivos de tipo .ico (iconos) y que también permita,
mediante un botón, asignar un elemento elegido como icono del formulario. La apariencia de la aplicación en
funcionamiento será la que se muestra en la página siguiente.
Con el fin de mostrar en la lista de archivos sólo aquellos que sean de tipo icono, habrá que asignar a la
propiedad Mask el valor *.ico. Por último, dé el valor “Aplicar como icono del formulario” a la propiedad
Caption del botón.
Cada vez que se seleccione uno de los archivos mostrados en el TFileListBox éste generará un evento
OnClick, que aprovecharemos para recuperar el archivo y mostrar su contenido. Para ello tendremos que escribir
el código siguiente:
_____________________________________________________________________________________________
Y cuando se pulse sobre el botón habrá que asociar el código que se presenta a continuación.
_____________________________________________________________________________________________
Hasta ahora todos los componentes que hemos conocido han sido controles, es decir, componentes visuales
con los que es posible interactuar durante la ejecución. No todos los componentes de C++ Builder son de este tipo,
existen también algunos que sin ser visibles desempeñan funciones muy importantes como se tendrá ocasión de ver
en el manejo de Bases de Datos.
Uno de los componentes no visuales es TTimer, un componente cuya única finalidad es generar un evento
a intervalos regulares con la frecuencia que nosotros mismos establezcamos. Este componente es el primero de la
página System.
La frecuencia con la que el componente TTimer generará el evento OnTimer dependerá del valor que
asignemos a la propiedad Interval, que por defecto es 1000. Esta medida está expresada en milisegundos, lo que
quiere decir que por defecto el evento se producirá una vez cada segundo.
En la práctica
Vamos a realizar una aplicación que simplemente presente un reloj digital, mostrando la hora ocupando
todo el espacio disponible del formulario.
A continuación inserte un control TTimer y haga doble clic sobre su evento OnTimer, en el que
escribiremos la sentencia que se muestra a continuación. La función Time() devuelve la hora actual, que
asignaremos a la propiedad Caption del control TLabel.
Label1->Caption=Time();
_____________________________________________________________________________________________
Los controles por parte de la aplicación del buen funcionamiento del juego se escapan, ahora mismo, del
objetivo del ejercicio, por lo que será el usuario el que se encargue de este aspecto. Más adelante se intentarán hacer
mejoras.
Así pues, la apariencia que ofrecerá el juego en un momento determinado podría ser la siguiente:
Donde, como se observa, existen parejas de imágenes cuyas posiciones se establecerán al azar desde la
propia aplicación.
1. Cualquier grupo de componentes que tengamos en un formulario pueden compartir un mismo código. Si se
marcan (pulsando <Mayusc> y seleccionando los componentes) podemos acceder, en el Inspector de
Objetos, a todos aquellos eventos que compartan los elementos seleccionados.
Cuando se accede al código asociado a un evento, el Borland C++ Builder genera la cabecera de la función
donde aparece un parámetro denominado Sender, que es un puntero al componente asociado a ese código.
El puntero Sender es del tipo genérico Tobject, del que están derivados todos los componentes.
Si quisiéramos acceder a una propiedad o un método, por ejemplo, del componente asociado, deberemos
hacer una conversión del tipo Tobject al tipo que deseemos de la forma siguiente:
static_cast<tipo_de_componente_al_que_se_quiere_convertir *>(Sender)->propiedad|método
_____________________________________________________________________________________________
Controls[].- Vector de elementos contenidos en el panel según el orden en el que se insertaron. Por
ejemplo, si un botón está incluido en el panel, podremos acceder a su propiedad Caption de la
forma siguiente: Panel1->Controls[0]->Caption=”Salir”
3. Una TImage (de la paleta Additional) es un control que permite mostrar una imagen en el formulario
obtenida desde un archivo en disco que puede estar en formato BMP, ICO o WMF.
Las propiedades que vamos a usar de una imagen son las siguientes:
Align.- Indica la alineación de la imagen con respecto al componente que la contiene. Si toma el
valor alClient utilizará todo el espacio disponible del contenedor.
Stretch.- Tomará el valor verdadero cuando queramos que la imagen se adapte al tamaño del
control.
Picture.- Es la propiedad más interesante de un Timage, puesto que su contenido hace referencia al
archivo imagen asociado a este componente. A esta propiedad se le puede asignar un valor en fase de
diseño simplemente haciendo doble clic sobre la propiedad en el Inspector de Objetos o bien,
podremos asignarle un valor desde código usando el método LoadFromFile(). Por ejemplo, de la forma
siguiente:
Image1->Picture->LoadFromFile(“foto1.bmp”);
4. Una vez insertado un componente en un formulario es posible marcarlo y copiarlo en el formulario tantas
veces como deseemos. Imaginemos que ya hemos insertado un componente y que le hemos asignado unas
propiedades concretas y también asociado unos eventos. Para que este componente pueda ser usado con
esas características en ocasiones posteriores podemos usar la opción del menú principal Component,
Create Component Template. Esta opción permite dar un nombre al control que queremos incluir como
plantilla y, generalmente, se insertará en una nueva pestaña de la Paleta de Componentes denominada
Templates. Este componente podrá ser usado cuando se quiera con sus propias características.
1. Crear un directorio de trabajo donde almacenaremos nuestro proyecto. Incluir en ese directorio al menos 8
imágenes .bmp.
3. Insertar un componente TPanel al que asignaremos el título ‘1’ y asociaremos a su evento OnClick el
siguiente código:
static_cast<TPanel *>(Sender)->Controls[0]->Visible=true;
4. Insertar un componente imagen Timage dentro del panel con la propiedad Visible a false. Asignar alClient
a la propiedad Align, y true a la propiedad Stretch. Asociar a su evento OnClick el siguiente código:
static_cast<TImage *>(Sender)->Visible=false;
_____________________________________________________________________________________________
6. Acceder a la pestaña Template e insertar 15 componentes más en el formulario de la forma que se vio en la
figura de la página 21. Asignar a los paneles como título los números del 1 al 16.
7. Ya sólo queda, antes de ejecutar el programa, asignar los ficheros imagen a cada uno de los Timage que
tenemos. Para ello pulsaremos sobre el evento OnActivate del formulario y escribiremos el siguiente
código, que, partiendo de un conjunto de 8 imágenes que insertamos en un vector de tipo cadena
(AnsiString en C++) crearemos otro vector del mismo tipo de 16 elementos con los ficheros que se van a
asociar con cada imagen. La asignación posterior a cada imagen, por ahora, la realizaremos una por una.
void __fastcall TForm1::FormActivate(TObject *Sender)
{
AnsiString tablaimagenes[8]={nombres de los 8 ficheros bmp que queremos utilizar};
int esta[8]={0,0,0,0,0,0,0,0};//Para comprobar las veces que se ha cargado una imagen
AnsiString asociacion[16];
int i,j;
randomize();
for (j=0;j<16;j++)
{
do
i=random(8);
while (esta[i]==2);
esta[i]++;
asociacion[j]=tablaimagenes[i];
}
Image1->Picture->LoadFromFile(asociacion[0]);
Image2->Picture->LoadFromFile(asociacion[1]);
Image3->Picture->LoadFromFile(asociacion[2]);
Image4->Picture->LoadFromFile(asociacion[3]);
Image5->Picture->LoadFromFile(asociacion[4]);
Image6->Picture->LoadFromFile(asociacion[5]);
Image7->Picture->LoadFromFile(asociacion[6]);
Image8->Picture->LoadFromFile(asociacion[7]);
Image9->Picture->LoadFromFile(asociacion[8]);
Image10->Picture->LoadFromFile(asociacion[9]);
Image11->Picture->LoadFromFile(asociacion[10]);
Image12->Picture->LoadFromFile(asociacion[11]);
Image13->Picture->LoadFromFile(asociacion[12]);
Image14->Picture->LoadFromFile(asociacion[13]);
Image15->Picture->LoadFromFile(asociacion[14]);
Image16->Picture->LoadFromFile(asociacion[15]);
Por último, recordar que para usar las funciones relacionadas con los números pseudoaleatorios hay que
incluir <stdlib.h>.
_____________________________________________________________________________________________