Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder Guión de Prácticas Desarrollo de Aplicaciones Interactivas 3º ITIS Guión de prácticas Programación visual con Borland C++ Builder DESCRIPCIÓN • Borland C++ Builder® es un Entorno Integrado de Desarrollo o IDE (esto es, editor + compilador + depurador) bastante completo, intuitivo, fácil de manejar y eficiente, que permite el desarrollo rápido de aplicaciones en entornos MS Windows®. Otros entornos de desarrollo utilizan una estructura muy parecida. • Características fundamentales de Borland C++ Builder: Utiliza el lenguaje de programación orientado a objetos C++ (como su nombre indica), con todas las ventajas que supone el uso de la OO. Permite realizar programación visual y programación dirigida por eventos. Características avanzadas de IDE: editor sensible a la sintaxis, complección de código, ayuda sensible al contexto, inspector de objetos, compilador y depurador integrados, etc. • Programación visual: el programador centra su atención en diseñar el aspecto gráfico de la aplicación, la distribución de los elementos visuales (botones, menús, cuadros de texto, etc.), la interacción entre los mismos, los distintos tipos de ventanas existentes, etc. • Un entorno de programación visual se asemeja a un programa de dibujo, donde la imagen es una ventana (o formulario), y los elementos del dibujo son botones, etiquetas de texto, menús, etc. El programador dispone los elementos con el mismo aspecto que tendrá la aplicación final (WYSIWYG, What You See Is What You Get). • Programación dirigida por eventos: el programador escribe el código que se ejecutará en respuesta a determinados eventos (pulsar un botón, elegir una opción del menú, abrir o cerrar una ventana, etc.). • No existe la idea de “programa principal”, sino que el programador toma el control cuando se dispara un evento. La labor del programador es asociar a cada evento el comportamiento adecuado. • Todo lo anterior es soportado gracias a la programación orientada a objetos. La POO es fundamental aquí, no sólo para conseguir programas de calidad, sino por el propio entorno: las funcionalidades básicas y los distintos elementos 1 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder Guión de Prácticas visuales (formularios, botones, cuadros de diálogo, etc.) están definidos como clases y sus instancias son objetos. • No basta con saber C++. Conocer y saber utilizar las clases existentes (tanto los componentes visuales como los no visuales) se vuelve casi tan importante como conocer el lenguaje de programación subyacente. • Usaremos Borland C++ Builder 6. EL ENTORNO DE C++ BUILDER 1. Ejecutar C++ Builder desde el menú de inicio. Se abrirán una serie de ventanas como las mostradas abajo. Menú principal Paleta de componentes Botones de acceso rápido Formulario de la aplicación creada Editor de código Inspector de objetos 2. Partes del entorno: • Menú principal. Contiene todas las operaciones típicas para manejar los ficheros de código (abrir, cerrar, guardar, etc.), opciones de edición (copiar, pegar, buscar, etc.), manejo del proyecto (añadir ficheros al proyecto, quitar, compilar, depurar, opciones de compilación, etc.), ayuda (tanto de C/C++, como de la funcionalidad propia), y otras operaciones. • Botones de acceso rápido. Contienen las operaciones más frecuentes del menú principal. • Paleta de componentes. Son los elementos que se pueden poner dentro del formulario de la aplicación: botones, cuadros de texto, menús, listas, cuadros de diálogo, etc. • Formulario de la aplicación. Es el aspecto de la ventana que estamos diseñando. Es la "zona de dibujo" sobre la que situamos los componentes. Un proyecto puede tener varios formularios. 2 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder • • Guión de Prácticas Editor de código. Es la zona donde escribimos el código de la aplicación. Es sensible a la sintaxis, y se puede acceder a la ayuda pulsando F1 sobre una palabra. A la izquierda aparece la jerarquía de clases de la aplicación (se puede ocultar). Inspector de objetos. Es fundamental. Sirve para ver y establecer valores de los elementos visuales de la aplicación. Dos tipos de valores: propiedades (nombre, color, posición en el formulario, etc.) y eventos (funciones asociadas a cada posible acción sobre el elemento). 3. Método de trabajo: usando los elementos de la paleta de componentes, diseñamos el aspecto del formulario de la aplicación. Ajustamos las propiedades de los elementos gráficos usando el inspector de objetos. Después, usamos el editor de código para escribir las operaciones asociadas a los eventos de interés. Finalmente, usando las opciones de menú o los botones de acceso rápido, compilamos, ejecutamos, depuramos y guardamos el proyecto. 4. Ficheros de un proyecto. Un proyecto o aplicación en C++ Builder está compuesto por un conjunto de ficheros. Ejecutar en el entorno File|Save Project As..., guardando todos los ficheros que indique en un directorio propio. Observar la estructura de ficheros creada. • Fichero de proyecto: Project.bpr. Contiene la definición de todos los elementos y ficheros de los que se compone el proyecto. Usa un formato propio de Borland, en XML. No nos interesa su contenido, ni lo editaremos directamente. • Fichero de recursos del proyecto: Project.res. Fichero binario (no de texto), con formato propio de Borland, que contiene los recursos usados en el proyecto, como el icono de la aplicación, o los dibujos de los botones. No nos interesa su contenido, ni lo editaremos directamente. • Fichero de inicio del proyecto: Project.cpp. Fichero C++ generado automáticamente, que inicia la aplicación, crea el formulario principal y lo ejecuta. Se puede ver pero no tocar. • Formularios de la aplicación: unit.dfm, unit.h y unit.cpp. La aplicación puede tener varios formularios, uno de ellos será el formulario principal (el que se abre automáticamente al ejecutar la aplicación). Cada formulario se define como una clase hija de la clase TForm. Los elementos del formulario (botones, menús, etc.) se definen como datos miembro de la clase, y los eventos se definen como métodos de la clase. Cada formulario tiene asociados tres ficheros: Descripción del formulario: unit.dfm. Describe las propiedades del formulario y sus componentes (posición, tamaño, color, etc.). Utiliza un formato propio de Borland. No lo editaremos directamente, sino de forma visual en el entorno. Fichero de cabecera del formulario: unit.h. Contiene la declaración de la subclase de TForm asociada al formulario (por defecto, tendrán los nombres TForm1, TForm2, etc.), y realiza los includes necesarios. Puede ser necesario editarlo, por ejemplo, para añadir propiedades a la clase. Fichero de implementación del formulario: unit.cpp. Implementación de la subclase de TForm asociada al formulario. Este fichero sí que tendremos que manejarlo, fundamentalmente 3 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder • Guión de Prácticas para escribir el código asociado a los eventos. Si la clase del formulario se llama TFormX, la instancia se llama FormX (puntero a TFormX). Módulos creados por el usuario: modulo.h, modulo.cpp. Igual que en cualquier programa C++, la funcionalidad debería estar bien repartida modularmente entre distintas partes. Para cada módulo, su fichero de cabecera (.h) y de implementación (.cpp). Cuidado, se tiende a incluir mucho código en los ficheros de implementación del formulario. Evitarlo con una buena programación modular. NUESTRO PRIMER PROGRAMA 1. Vamos a escribir nuestro primer programa con Borland C++ Builder, que consistirá en un simple contador manual y un mensaje de saludo. 2. Abrir C++ Builder. Si ya estaba abierto, seleccionar File|Close All, y luego File|New|Application o bien pulsar en el botón y luego Application. 3. Guardar el proyecto nuevo, con File|Save Project As... o pulsando el botón Guardar todos los ficheros dentro de un directorio específico del proyecto. . 4. En el inspector de objetos (Object Inspector) está seleccionado Form1 (de tipo TForm1) que es el formulario principal. Dentro de la propiedad Caption escribir "Mi primer programa con C++ Builder". Observar el resultado. 5. Ejecutar Run|Run o pulsar el botón . ¡Ya has creado tu primer programa con C++ Builder! ... Ciérralo antes de seguir... 6. En la paleta de componentes seleccionar la etiqueta (Label), pulsando en el , dentro de la solapa Standard. A continuación, pinchar en el icono formulario, en la posición donde se quiera colocar la etiqueta de texto. 7. Ir al inspector de objetos. Ahora está seleccionado Label1 (este es el nombre dado automáticamente a esta etiqueta). En la propiedad Caption escribir "Valor del contador". Observar el resultado. Editar la propiedad Font y poner un tamaño de fuente 18. 8. En la paleta de componentes seleccionar un cuadro de texto (Edit), pulsando en el icono , dentro de la solapa Standard. A continuación, pinchar en el formulario, en la posición y tamaño donde se quiera colocar. 9. Ir al inspector de objetos. Ahora está seleccionado Edit1. En la propiedad Text escribir 0. Editar la propiedad Font y poner un tamaño de fuente 24. 4 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder Guión de Prácticas 10. De forma parecida, añadir tres botones (Button) al formulario usando el icono de la paleta de componentes. En el primero (Button1), poner en Caption "Incrementar", en el segundo "Decrementar" y en el tercero "Saludar". 11. Ya tenemos diseñado el aspecto gráfico de nuestro programa. Debería ser algo más o menor parecido a esto. Label1: TLabel Form1: TForm1 Edit1: TEdit Button2, Button3: TButton Button1: TButton Probar a ejecutar ( ). Ver cómo el formulario tiene el comportamiento que se esperaría (se puede editar el cuadro de texto, los botones se hunden al pulsarlos, etc.) , aunque no tienen ningún comportamiento útil asociado. Eso es lo que vamos a hacer ahora. 12. En el formulario diseñado, hacer doble clic sobre el botón "Incrementar". Esto crea un evento que se asocia a la pulsación de este botón. Se activará el editor de código, donde aparecerá el texto: void __fastcall TForm1::Button1Click(TObject *Sender) { } Significado: se ha creado un nuevo método en la clase TForm1, que está asociado a la pulsación del botón Button1. Este método no devuelve ningún valor, y recibe un parámetro que es el objeto que ha producido el evento (en este caso el propio botón). Dentro de las llaves escribimos el código que se ejecutará cuando pulsemos el botón. 13. En el editor de código, dentro del fichero Unit1.cpp, crear una variable global de tipo entero, inicializada a 0. Escribir lo siguiente antes del evento Button1Click: int contador = 0; 14. Escribir el siguiente código dentro del evento Button1Click: void __fastcall TForm1::Button1Click(TObject *Sender) { contador++; Edit1->Text= contador; // Conversión de tipos implícita } 5 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder Guión de Prácticas 15. Hacer doble clic sobre el botón "Decrementar", creando un evento para este botón. En el editor de código escribir: void __fastcall TForm1::Button2Click(TObject *Sender) { contador--; Edit1->Text= contador; } 16. Hacer doble clic sobre el botón "Saludar", creando un evento para este botón. En el editor de código escribir: void __fastcall TForm1::Button3Click(TObject *Sender) { ShowMessage("¡Hola Mundo!"); } 17. También se pueden crear eventos desde el inspector de objetos. Seleccionar alguno de los botones y en el inspector de objetos activar la solapa Events. En la fila OnClick aparecerá el evento que hemos creado. Haciendo doble clic en otra fila podemos crear eventos asociados a otras acciones (que se seleccione el botón, que se deseleccione, que pase el ratón por encima, etc.). 18. Guardar ( ) y ejecutar ( ) el proyecto. La ejecución conlleva, de forma implícita, la compilación del proyecto (compilación + enlace). Aunque también se puede compilar explícitamente con Project|Build Project. 19. Cambiar las etiquetas de los botones por "&Incrementar", "&Decrementar" y "&Saludar" y observar el resultado. Ejecutar ( teclas Alt+I, Alt+D y Alt+S. ) y probar las combinaciones de 20. Observar los nuevos ficheros creados dentro del directorio del proyecto: Project.exe (fichero ejecutable de Windows), ficheros .obj (código objeto), .tds (tabla de símbolos) y .~xxx (copias de respaldo temporales). 21. Observar la definición de la clase TForm1 en el fichero Unit1.h. Por ejemplo, en el editor de código, pulsar con el botón derecho y seleccionar Open Source/Header File. Los componentes incluidos aparecen como atributos de la clase, y los eventos como métodos, además del constructor de la clase. ELEMENTOS DE LA PALETA DE COMPONENTES 1. Es importante conocer los elementos más frecuentes de la paleta de componentes, que darán contenido a los formularios. Los más útiles e interesantes se encuentran en las solapas: Standard, Additional, Win32, System, Dialogs y Samples. Destacamos los siguientes: • Standard 6 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder Guión de Prácticas - • MainMenu: menú principal, situado normalmente en la parte superior de la ventana. Se edita haciendo doble clic. Lo importante son los eventos asociados a cada entrada del menú. - Label: etiqueta de texto, normalmente con contenido fijo, aunque puede modificarse en el programa cambiando el atributo Caption. - Edit: cuadro de entrada de texto. Lo importante es el atributo Text, que indica el texto escrito por el usuario (o por el programa). - Memo: cuadro de texto que puede ocupar varias líneas. El contenido es el atributo Lines, de tipo TStrings (con operaciones Clear, Add, Get, etc., ver la ayuda). - Button: botón normal. Lo importante es el evento asociado a su pulsación, y el atributo Caption. El botón puede estar desactivado (atributo Enabled). - CheckBox: cuadro de chequeo, para recibir entradas de tipo booleano. Ver los atributos Checked y Caption. - RadioButton: botón circular. Indica una elección entre un conjunto de posibilidades excluyentes. Ver los atributos Checked y Caption. - ListBox: selector de una línea entre una lista de posibilidades. Las posibilidades están en el atributo Items, de tipo TStrings, que se puede rellenar en tiempo de diseño o de ejecución. La propiedad ItemIndex indica el número de la entrada seleccionada. - ComboBox: selector de lista desplegable. Parecido a la anterior, pero la lista puede estar desplegada o no. - RadioGroupBox: grupo de botones de radio. Los botones existentes se establecen en la propiedad Items, de forma parecida a un ListBox. - GroupBox: establece un marco para agrupar un conjunto de elementos y darle un nombre (propiedad Caption). Additional - • BitBtn: botón con un dibujo. Igual que un botón normal, pero muestra también un dibujo, establecido en la propiedad Glyph. SpeedButton: botón cuadrado con dibujo y sin texto, como los de acceso rápido. StringGrid: matriz de cadenas, para la visualización e introducción de datos. Ver las opciones (propiedad Options), para permitir la edición. Con la propiedad Cells se accede al contenido de las celdas. Image: imagen, cargada en tiempo de diseño o en ejecución. La propiedad Picture hace referencia al bitmap almacenado en la imagen. Shape: figura geométrica sencilla. Ver las propiedades Brush (relleno), Pen (borde) y Shape (forma). LabeledEdit: cuadro de entrada de texto, junto con una etiqueta. El texto está en la propiedad Text, y la etiqueta en EditLabel. ColorBox: selector de color. Permite al usuario seleccionar un color, que se lee en el atributo Selected. El color viene dado como un tipo TColor (long), donde el último byte es R, el segundo G y el tercero B. Win32 - PageControl: sistema de solapas. Permite tener varias páginas en un mismo espacio, cada una con una solapa asociada. Para crear nuevas 7 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder • Guión de Prácticas páginas: botón derecho del ratón, New Page. Cada hoja creada es de tipo TabSheet. - TrackBar: barra de selección de posición. Permite seleccionar visualmente un valor que está entre un mínimo y un máximo (propiedades Min y Max, respectivamente). La propiedad Position (entero) indica la posición actual. - ProgressBar: barra de indicación de progreso. Muestra el nivel de progreso de algún proceso, entre 0 y 100%, establecido en Position. - UpDown: par de botones arriba/abajo. Igual que el anterior, contiene propiedades Min, Max y Position, pero no se muestra gráficamente la posición actual del elemento. System - • Timer: reloj. Su principal misión es crear eventos que se activan cada cierto tiempo. La propiedad Interval indica el tiempo, en milisegundos, entre cada par de eventos generados. - PaintBox: zona de dibujo. La diferencia con Image es que no tiene asociado un fichero de bitmap (Picture). El atributo principal es Canvas (lienzo) de tipo TCanvas, que tiene operaciones LineTo, MoveTo, Rectangle, Ellipse, Pixels[x][y], etc. Dialogs - • OpenDialog: cuadro de diálogo de abrir fichero. El método Execute() muestra el cuadro de diálogo, que pide al usuario un nombre de fichero. No se hace ninguna acción sobre el fichero, sólo se obtiene el nombre, que se almacena en el atributo FileName. Observar las distintas opciones (Options) y la propiedad de restringir la extensión del fichero de entrada (Filter). - SaveDialog: cuadro de diálogo de guardar fichero. Igual que antes, pero para indicar un nombre para guardar. Recordar que no se guarda nada, sólo se almacena el nombre seleccionado en FileName. - ColorDialog: cuadro de diálogo de selección de un color. Al ejecutarlo, Execute(), pide al usuario que seleccione un color, que es almacenado en la propiedad Color, de tipo TColor. Ver otros componentes interesantes en la paleta Samples 2. Probar el comportamiento de estos componentes. "Jugar" con ellos incluyéndolos en un programa de prueba. Analizar sus propiedades y eventos en el inspector de objetos. Buscar más información sobre las propiedades, eventos y métodos en la ayuda. ALGUNAS INDICACIONES IMPORTANTES 1. Involuntariamente, la programación visual y dirigida por eventos pueden favorecer un mal estilo de programación, donde no se separa adecuadamente entre la parte de interface de usuario y la lógica de la aplicación. Se tiende a poner todo el código dentro de los eventos, haciéndolo confuso, ilegible y desorganizado. Es importante respetar la programación modular: crear 8 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder Guión de Prácticas módulos separados para la parte no visual, con sus ficheros de cabecera y de implementación, y desde los eventos hacer simples llamadas a las operaciones que correspondan. El código asociado a los eventos debería ser trivial. La funcionalidad debe estar fuera, estructurada en módulos de forma adecuada. 2. En la medida de lo posible, utilizar código C++ estándar, sobre todo en la parte no visual. Algunas funcionalidades están muy bien, aunque no son muy estándar, como por ejemplo el tipo AnsiString para manejar cadenas. 3. Algunos consejos prácticos sobre C++ Builder: • Los ejecutables generados por C++ Builder son muy pequeños, porque se usan paquetes en tiempo de ejecución. Pero esto requiere tener instalado C++ Builder en el ordenador donde se vaya a ejecutar el programa. Para evitarlo, hay que modificar las opciones de proyecto, en Project| Options... En la solapa Packages, en la sección Runtime packages, desactivar la opción Build with runtime packages. • Ya de paso, observar las opciones de compilación del proyecto, fundamentalmente las incluidas en Compiler. Existen dos modos básicos de compilación: Full debug (modo depuración) y Release (versión final). Normalmente, mientras estamos desarrollando el programa compilaremos con Full debug. Una vez que esté acabado, compilaremos con Release. • A veces el formulario no se ve como se ha diseñado, porque se ejecuta en un pantalla con distinta resolución. Esto es debido a la propiedad Scaled de TForm. Lo más recomendable es desactivarla, ya que por defecto está activada. 9 Desarrollo de Aplicaciones Interactivas Programación visual con Borland C++ Builder Guión de Prácticas TAREA A REALIZAR Habituarse a los distintos elementos del entorno de C++ Builder. Abrir el proyecto de contador y añadir los siguientes elementos: 1. Un menú principal con las opciones Archivo (Iniciar contador, Salir), Edición (Incrementar, Decrementar) y Acerca de. Asociar el comportamiento adecuado a cada una de estas opciones. 2. Para el comando “Acerca de” crear un formulario específico (New | Forms | About box). El formulario se abre con “AboutBox->Show();” y se cierra con “Close();”. ¿Qué falta para poder usar el formulario AboutBox desde Form1? 3. Crear una barra de botones de acceso rápido con la misma funcionalidad que el menú principal. Ojo: no hace falta repetir código. 4. Incluir un ListBox que permita seleccionar el tipo de saludo a mostrar al pulsar en el botón “Saludar”. Deben haber 4 opciones: “Estándar”, “Coleguilla”, “Corto”, “International”. Según la línea que seleccione el usuario, el saludo será: “¡Hola Mundo!”, “¿Qué pasa tío?”, “Ale” u “Bon yur!”, respectivamente. 5. Añadir en el menú principal un comando Opciones, que abra una ventana donde se pueda configurar el tamaño del incremento/decremento del contador. Crear una nueva ventana y abrirla con ShowModal(). 6. Añadir dentro del menú principal, en Archivo, un par de comandos Abrir y Guardar, que guarden el estado del contador en un fichero (un simple entero). El nombre del fichero se seleccionará abriendo un cuadro de diálogo (OpenDialog o SaveDialog). 10