You are on page 1of 378

Programacin visual de aplicaciones con C++ Builder

Curso de C++ Builder

Introduccin El IDE Componentes La VCL Programacin orientada a objetos en C++ Tratamiento de excepciones Programacin con hebras Acceso a bases de datos Enlaces interesantes Todo en un ZIP

file:///D|/Manuales/index.html (1 of 2) [27/02/2003 16:23:49]

Programacin visual de aplicaciones con C++ Builder

ndice

Ejercicios

Apndices

Francisco Jos Cortijo Bon & Fernando Berzal Galiano


Todos los derechos reservados por los autores sobre el contenido de este documento electrnico. Queda prohibido su uso comercial sin el consentimiento escrito de los autores. Cualquier uso de este material debe ser comunicado a los autores.

IDE | Componentes | VCL | OOP | Excepciones | Hebras | Bases de datos | Enlaces

file:///D|/Manuales/index.html (2 of 2) [27/02/2003 16:23:49]

Introduccin

Curso de C++ Builder Introduccin

Para ser un buen programador en C++ Builder existen distintos aspectos que se deben conocer:
q

El Entorno de desarrollo integrado de C++ Builder (el IDE). En la seccin 2 se estudia el IDE de C++ Builder. Los componentes disponibles para crear aplicaciones Windows, y sobre stos, sus propiedades ms importantes, los mtodos asociados y los eventos a los que pueden responder (seccin 3). Un conocimiento genrico acerca de la biblioteca de clases visuales de Borland (la VCL), en definitiva, conocer a grandes rasgos la jerarqua de clases de la que forman parte los componentes (seccin 4). Los conceptos fundamentales de la metodologa de programacin orientada a objetos (POO), el lenguaje C++ y cmo se debe usar bajo el estilo de C++ Builder (seccin 5). Ciertas tcnicas avanzadas de programacin, como pueden ser el tratamiento de excepciones, la programacin con hebras, la construccin de componentes personalizados, la interaccin con bases de datos, la programacin de aplicaciones para Internet...

En el transcurso del curso se pretende introducir al alumno en la programacin de aplicaciones para Windows utilizando C++ Builder. Aunque se supone que ste ya posee cierta experiencia en la programacin de C, y conocimientos muy bsicos de programacin orientada a objetos.

Pgina principal

file:///D|/Manuales/intro/1.html (1 of 2) [27/02/2003 16:23:49]

Introduccin

Francisco Cortijo Bon

file:///D|/Manuales/intro/1.html (2 of 2) [27/02/2003 16:23:49]

IDE

Curso de C++ Builder El IDE (Entorno de Desarrollo Integrado)

q q q q q q

2.1. Una visin general del IDE de C++ Builder.. 2.2. Un estudio detallado del IDE de C++ Builder.. 2.3. El sistema de ayuda. 2.4. Compilacin, ejecucin y depuracin de programas. 2.5. El almacn de objetos. 2.6. Ejercicios: Ejemplos de aplicaciones simples y de consola .

IDE es el acrnimo de Integrated Development Environment o entorno de desarrollo integrado. C++ Builder es una aplicacin Windows que proporciona un entorno de trabajo visual para construir aplicaciones Windows que integra distintos aspectos de la programacin en un entorno unificado o integrado. La integracin y facilidad de manejo hace que sea una herramienta indispensable para el desarrollo rpido de aplicaciones o RAD (Rapid Application Development). Guarda una gran similitud con el IDE de Visual Basic, aunque existen ciertas diferencias que veremos. El IDE de C++ Builder es una aplicacin Windows 95 y como tal cumple con los estndares de aspecto, diseo y comportamiento que aconseja Microsoft a los desarrolladores de aplicaciones. En consecuencia, cualquiera que est familiarizado con el manejo a nivel de usuario de Windows 95 no le supondr ningn esfuerzo manejarlo con soltura.

2.1. Una visin general del IDE de C++ Builder.


El entorno de desarrollo se divide, bsicamente, en tres partes. Una serie de ventanas, que pueden estar visibles u ocultas, constituyen la base de C++ Builder. El aspecto de la aplicacin al inicio de una sesin de trabajo es el mostrado en la figura 2.1. Figura 2.1. Aspecto del C++ Builder al inicio de una sesin.

file:///D|/Manuales/intro/2.html (1 of 26) [27/02/2003 16:23:53]

IDE

En la parte superior se coloca la ventana principal, que contiene el men principal, la barra de herramientas (a la izquierda) y la paleta de componentes (a la derecha). Debajo de la ventana principal, y a la izquierda se coloca el inspector de objetos. A la dercha del inspector de objetos est el rea de trabajo de C++ Builder, que inicialmente muestra el diseador de formularios, y escondido u oculto parcialmente tras ste
file:///D|/Manuales/intro/2.html (2 of 26) [27/02/2003 16:23:53]

IDE

aparece el editor de cdigo. Veamos a grandes rasgos la misin de cada uno de ellos.

1. Ventana principal. En la ventana principal se ubican el menu principal, la barra de herramientas y la paleta de componentes (figura 2.2). Figura 2.2. Ventana principal de C++ Builder.

Men principal. Permite el acceso a todas las operaciones y posibilita la configuracin del programa. Barra de herramientas. Permite un acceso rpido a las operaciones que se realizan ms frecuentemente. Paleta de componentes. Agrupa a los componentes que pueden incluirse en las aplicaciones.

file:///D|/Manuales/intro/2.html (3 of 26) [27/02/2003 16:23:53]

IDE

2. Inspector de objetos. Para cambiar las propiedades de los objetos que forman la aplicacin y seleccionar los eventos a los que debe responder la aplicacin. Figura 2.3. El inspector de objetos.

3. Diseador de formularios. Es una ventana cuadriculada sobre el que se disponen los componentes para disear las ventanas que formarn la aplicacin. Figura 2.4. El diseador de formularios.

file:///D|/Manuales/intro/2.html (4 of 26) [27/02/2003 16:23:53]

IDE

4. Editor de cdigo. Un tpico editor de texto multiventana para ver y editar el cdigo de la aplicacin. Est perfectamente integrado con el inspector de objetos y el diseador de formularios. Figura 2.5. El editor de cdigo.

file:///D|/Manuales/intro/2.html (5 of 26) [27/02/2003 16:23:53]

IDE

Existen otras partes del entorno, que ya iremos comentando conforme vayamos profundizando en el curso. A continuacin trataremos con ms detalle las partes que hemos enumerado anteriormente.

2.2. Un estudio detallado del IDE de C++ Builder.

1.

Men Principal

file:///D|/Manuales/intro/2.html (6 of 26) [27/02/2003 16:23:53]

IDE

Se puede decir que es la ventana principal del IDE de C++ Builder y siempre est visible. En l podemos encontrar todas las operaciones disponibles.

Figura 2.6. El men principal.

Tiene los mens comunes a cualquier aplicacin Windows: File, Edit, Search, Help..., adems de otros que ya iremos estudiando a lo largo del curso. En el ttulo del men principal aparece el nombre de la aplicacin (C++ Builder) y el nombre del proyecto/grupo de proyectos con el que actualmente se est trabajando. Por defecto, asigan el nombre Project1 al proyecto con el que se va a trabajar, aunque ste deber cambiarse, lgicamente. Como veremos, el concepto de proyecto es fundamental en C++ Builder ya que es el mecanismo de organizar sensatamente todos los ficheros (formularios, cdigo fuente, recursos, etc.) asociados a una aplicacin.

Para ms detalles acerca de los mens, consultar la lista completa de mens.

2.

Barra de Herramientas
La barra de herramientas tiene como objeto acelerar las operaciones ms comunes del men principal. Si nos acostumbramos a utilizarla agilizaremos el uso del entorno significativamente. Su aspecto habitual es el que mostramos en la figura 2.7. Figura 2.7. La barra de herramientas.

Si pasamos el ratn sobre los iconos nos aparecern unos globos o cuadros de ayuda, informndonos de cual es la funcionalidad de cada uno de ellos. La barra de herramientas se puede personalizar (al igual que casi todas las partes del entorno) pulsando con el botn derecho y seleccionando Properties.

file:///D|/Manuales/intro/2.html (7 of 26) [27/02/2003 16:23:53]

IDE

3.

Paleta de Componentes
Los componentes constituyen los bloques bsicos sobre la que se construyen aplicaciones Windows con C++ Builder basadas en la VCL (Visual Component Library) y son la base de la VCL. Todos los componentes (visuales y no visuales) estn accesible rpida y cmodamente gracias a la paleta de componentes. Podemos decir que es un gran almacn de componentes listos para ser incorporados a una aplicacin, seleccionndolo y colocndolo en un formulario. Por conveniencia, todos los componentes disponibles se encuentran organizados en distintas pginas o carpetas segn su funcionalidad. Cada pestaa de la paleta de componentes da acceso a un conjunto de iconos que representan a componentes que pueden usarse para disear la aplicacin. Su aspecto es el que mostramos en la figura 2.8. Figura 2.8. La paleta de componentes.

A diferencia con Visual Basic, todos los componentes de C++ Builder se encuentran cargados por defecto, aunque se le pueden aadir ms mediante las opciones del men de componentes (opcin Component del men principal). Cada componente tiene asignada una pgina, por lo que el usuario no puede elegir la ubicacin de los componentes disponibles por defecto en la paleta de componentes, aunque puede modificar la disposicin de las pginas y aadir nuevas pginas o componentes ( Tools | Environment Options) Para colocar un componente en un formulario se debe seleccionar en la paleta de componentes el botn que representa al componente y a continuacin, pinchar sobre el formulario donde se desea colocalo. Una estrategia alternativa (y menos utilizada) es seleccionar el componente en la ventana Components, que se abre seleccionando View | Component List. Conocer los componentes y su filosofa de trabajo (propiedades, mtodos y eventos) es fundamental para un programador. En la seccin 3 discutimos con ms profundidad sobre los componentes disponibles en C++ Builder y en la seccin 4 discutimos acerca de la estructura de la VCL. Enlaces adicionales:

file:///D|/Manuales/intro/2.html (8 of 26) [27/02/2003 16:23:53]

IDE

Para ms detalles acerca de los componentes disponibles, consultar la lista completa de componentes, agrupados por pginas.

Para ms detalles acerca de cmo configurar y manipular los componentes, consultar la relacin de propiedades, mtodos y eventos de componentes.

4.

Diseador de Formularios
Como hemos indicado anteriormente, es una ventana cuadriculada quer sirve para disear las ventanas (o formularios) que formarn la aplicacin (ver figura 2.4). Es una herramienta visual destinada a disear y presentar la interfaz de usuario (la apariencia externa) de una aplicacin. Un formulario puede ser la ventana principal de un programa, un cuadro de dilogo o cualquier otra ventana. Mediante el uso del ratn podemos colocar componentes de la paleta de componentes en el rea de diseo. Lo nico que tenemos que hacer es: 1. 2. 3. 4. Buscar el componente en la paleta de componentes. Pinchar sobre el componente para seleccionarlo. Pichar en el formulario: el componente ha quedado asociado al formulario. Arrastrarlo hasta su posicin final.

La posicin de un componente siempre se ajusta al punto ms prximo de la rejilla para facilitar su ajuste (su alineacin). La opciones relacionadas con la rejilla pueden modificarse en Tools | Environment Options. Siempre hay un componente (o en su defecto, el propio formulario) activo. Visualmente se sabe cul es porque aparece enmarcado con trazos discontnuos en el diseador de formularios. Se puede activar cualquier componente pinchando (un slo click) sobre l. Si se pincha dos veces en lugar de una, se activa el editor de cdigo para escribir el gestor del evento OnClick asociado a ese componente. Si sto no es lo que queremos basta con volver a activar el diseador de formularios y continuar con la fase de diseo. Cuando se guarde el proyecto, el cdigo que C++ Builder ha insertado automticamente desaparecer porque no hemos introducido ningn cdigo para ese gestor. En ningn caso se borrar manualmente lo que C++ Builder ha insertado automticamente: podra provocar una inconsistencia interna y hacer inaprovechable el trabajo realizado.

file:///D|/Manuales/intro/2.html (9 of 26) [27/02/2003 16:23:53]

IDE

EJERCICIO 1: Diseo de un formulario.

5.

Inspector de Objetos
Se trata, sin duda, de una de las herramientas ms potentes y atractivas de C++ Builder. Su aspecto es el que mostramos anteriormente en la figura 2.3. Se trata de una ventana que contiene dos pginas: Properties y Events. En la figura 2.9 mostramos el aspecto de las dos pginas en cuestin para el formulario que aparece por defecto al iniciar C++ Builder. Figura 2.9. Las dos pginas (Properties y Events) del inspector de objetos.

file:///D|/Manuales/intro/2.html (10 of 26) [27/02/2003 16:23:53]

IDE

Cada componente tiene asociado un conjunto de propiedades y mtodos y un conjunto de eventos a los que puede responder. Con el inspector de objetos podremos moldear los componentes de una aplicacin segn nuestras necesidades, en cuanto a su apariencia (propiedades) y funcionalidad (eventos a los que puede responder). En definitiva, podemos modificar las propiedades de los componentes y construir los gestores de eventos a los que stos pueden responder. En la parte superior se especifica el objeto activo (en la figura 2.9, el formulario, llamado Form1). Las propiedades del objeto activo aparecen en la pgina con la pestaa Properties y los eventos a los que puede responder en la pgina con la pestaa Events. Para seleccionar un objeto desde el inspector de objetos se despliega la lista de objetos y se selecciona el objeto en la lista. Tambin se puede seleccionar desde el diseador de formularios pinchando (un solo click) sobre el objeto.
file:///D|/Manuales/intro/2.html (11 of 26) [27/02/2003 16:23:53]

IDE

Si lo que se desea es modificar sus propiedades, se abre la carpeta de propiedades pinchando sobre la pestaa Properties. Si lo que se desea es asociarle un gestor de eventos, se abre la carpeta de gestores de eventos seleccionando la pestaa Events. Por ejemplo, podramos poner el texto Escuchar saludo en un botn colocado sobre un formulario (modificando la propiedad Caption) y escribir un cdigo para reprodicir un fichero .WAV que contiene una grabacin (escribiendo un gestor para el evento OnClick)

EJERCICIO 2: Uso del inspector de objetos para modificar propiedades.

6.

Editor de Cdigo
Permite editar el cdigo de una aplicacin de una forma cmoda. Admite coloreo simple de la sintaxis y distintos archivos abiertos simultneamente. En la ventana del editor pueden "pegarse" el gestor de proyectos y el inspector de clases (vase en la figura 2.10) aunque estas dos herramientas pueden aparecer tambin como ventanas separadas.
r

Inspector de clases: Es un navegador que muestra las clases, objetos y mtodos asociados a la aplicacin. Aparece por defecto asociada al editor (en la figura 2.10, en la parte inferior izquierda). Para abrir esta ventana: View | ClassExplorer. Administrador de proyectos: Es bsicamente un navegador entre los diferentes ficheros que forman la aplicacin. No aparece por defecto, y cuando se abre (View | Project Manager) se muestra como una ventana independiente. En la figura 2.10 se muestra asociada al editor, en la parte superior izquierda. Ms informacin en este enlace. Figura 2.10. El editor de cdigo.

file:///D|/Manuales/intro/2.html (12 of 26) [27/02/2003 16:23:53]

IDE

Pulsando con el botn derecho aparece un men contextual (figura 2.11) con algunas opciones bastante tiles. Figura 2.11. El men contextual del editor de cdigo.

file:///D|/Manuales/intro/2.html (13 of 26) [27/02/2003 16:23:53]

IDE

A diferencia con Visual Basic, C++ Builder nos permite el acceso a la totalidad del cdigo fuente de la aplicacin. Por esto es importante saber qu partes de ese cdigo est mantenido automticamente, y sobre todo evitar modificarlo!!!. El editor de cdigo est relacionado muy estrechamente con el inspector de objetos. Al hacer doble click en un evento, el IDE genera automticamente el cdigo para la funcin manejadora para tal evento. No tenemos que preocuparnos de cul es exactamente el prototipo que debemos de usar para la funcin que maneje el evento, ya que este se generar correctamente en la unidad de cdigo asociada al Form actual. Cuando queramos eliminar un manejador de evento que ha sido generado automticamente es conveniente no borrar "a mano" la funcin. Lo mejor es borrar "el cuerpo" de dicha funcin (lo que el programador escribe) y dejar que el resto lo elimine C++ Builder (lo que ocurrir cuando se guarde el archivo).

EJERCICIO 3: Uso del inspector de objetos para escribir gestores de eventos con el editor de cdigo.

7.

Administrador de Proyectos

file:///D|/Manuales/intro/2.html (14 of 26) [27/02/2003 16:23:53]

IDE

Un proyecto es un conjunto de archivos que trabajan en equipo para crear un archivo ejecutable independiente o una DLL. Un grupo de proyectos es un conjunto de proyectos. Figura 2.12. El administrador de proyectos.

Los proyectos que componen un grupo de proyectos, y los archivos que componen cada uno de esos proyectos, es lo que presenta, en forma de rbol, el administrador de proyectos. Puede emplearse como navegador para seleccionar el mdulo con el que se va a trabajar. Para visualizar el gestor de proyectos, seleccionar View | Project Manager. El gestor de proyectos puede "pegarse" al editor de cdigo, arrastrndolo hasta colocarlo sobre ste ltimo (ver figura 2.10). En todo momento existe un nico proyecto activo (en la figura 2.12, Project1), y ser este el que se ejecute si elegimos la opcin Run|Run.

file:///D|/Manuales/intro/2.html (15 of 26) [27/02/2003 16:23:53]

IDE

Los ficheros de proyecto especifican todos los recursos necesarios (ficheros .cpp, .h, ficheros de descripcin de formularios, etc.) que se necesitan para la construccin del ejecutable. Los ficheros de proyecto tienen extensin .bpr y el ejecutable que se genera tiene el mismo nombre que el proyecto y la extensin .exe, lgicamente. Todo proyecto en C++ Builder se compone, al menos, de un archivo de cdigo que contiene la funcin principal (WinMain()). Su nombre es el nombre del proyecto, con la extensin .cpp (en la figura 2.12, Project1.cpp). Este fichero no est, habitualmente, visible, ya que no es necesario modificarlo. Puede abrirse en el editor de cdigo con la opcin Project|View Source. Cualquier aplicacin tpica tendr al menos una ventana. Para cada ventana (en la figura 2.12, Form1) habr un mdulo, formado por una pareja de ficheros: un .cpp (en la figura 2.12, Unit1.cpp) y su correspondiente .h: en el fichero .cpp estarn los gestores de los eventos asociados a los componentes de esa ventana y en el .h (que no se modificar, normalmente) estar la declaracin de los componentes de esa ventana. Adems del fichero que contiene la funcin principal, un proyecto puede tener asociados una serie de mdulos adicionales en los cuales pueden incluirse funciones y clases de objetos, como en cualquier aplicacin C++. Cada uno de estos mdulos estar formado por una pareja de ficheros: un .cpp y su correspondiente .h.

Ms informacin sobre proyectos en C++ Builder y configuracin de aplicaciones.

A un grupo de proyectos se le pueden aadir proyectos, archivos, formularios, mdulos... nuevos o que ya existan. Hemos dicho que, en definitiva, el administrador de proyectos es nicamente un organizador de archivos. Veamos brevemente qu tipos de archivos pueden formar parte de un proyecto/grupo de proyectos, y que cul es su cometido: EXT BPR CPP H OBJ EXE Descripcin Es el archivo makefile del proyecto. Define qu y cmo se debe compilar. Archivos fuente de C++. Archivos de cabecera de C++. Archivos objeto resultado de la compilacin. Es el programa ejecutable resultante.

file:///D|/Manuales/intro/2.html (16 of 26) [27/02/2003 16:23:53]

IDE

TDS DFM

Archivos temporales para la compilacin incremental. Archivos de descripcin de formulario. Contiene los valores de las propiedades de cada componente. Aunque est en formato binario, puede verse como texto seleccionando View as text en el men contextual que aparece al pulsar con el botn derecho del ratn cuando se est situado sobre el formulario.

RES DSK BPG HPP

Un archivo de recursos. Es el archivo que contiene la configuracin del escritorio para un proyecto. Es un archivo de grupo de proyectos. Describe qu proyectos conforman el grupo de proyectos. Archivos de cabecera creados automticamente por C++ Builder.

2.3. El sistema de ayuda


El sistema de ayuda ser una de las herramientas que ms tiles nos resultar en nuestro trabajo con C++ Builder. Especialmente la documentacin de los componentes y clases predefinidas. Saber programar con C++ Builder no significa dominar todos y cada uno de los aspectos del entorno, sino que ms bien es conocer los principios en los que ste se basa, y los detalles concretos ya los buscaremos en la Ayuda cuando nos sean necesarios. La ayuda es una ayuda estndar de Windows por lo que no entraremos en ms detalles, slo comentar que pulsando F1 obtendremos una ayuda contextual. As, por ejemplo, en el caso de hacerlo en el editor de cdigo, se nos ofrecer la ayuda correspondiente a la palabra que se encuentre bajo el cursor (figuras 2.13, 2.14 y 2.15). Figura 2.13. Ventana de ayuda que se despliega al pulsar F1 sobre la palabra clave Application

file:///D|/Manuales/intro/2.html (17 of 26) [27/02/2003 16:23:53]

IDE

Figura 2.14. Ayuda detallada sobre Application variable (for standard applications).

file:///D|/Manuales/intro/2.html (18 of 26) [27/02/2003 16:23:53]

IDE

Figura 2.15. Ejemplo proporcionado en la ayuda sobre Application variable (VCL Reference).

file:///D|/Manuales/intro/2.html (19 of 26) [27/02/2003 16:23:53]

IDE

Pulsando F1 sobre cualquier opcin de un men se mostrar la ayuda asociada a esa opcin (figura 2.16). Figura 2.16. Ventana de ayuda mostrada al pulsar F1 estando seleccionada la opcin View | Project Manager

file:///D|/Manuales/intro/2.html (20 of 26) [27/02/2003 16:23:53]

IDE

C++ Builder proporciona algunas facilidades muy tiles a la hora de escribir cdigo. Las ms importantes son:
q

Completar cdigo. Al escribir el nombre de una clase seguido del operador de acceso punto (.) o el nombre de un puntero que referencia a un objeto seguido del operador de acceso flecha (->) se muestra la lista de propiedades, mtodos y eventos asociados a esa clase (figura 2.17).

Figura 2.17. Ayuda para completar cdigo: Propiedades, mtodos y eventos asociados a la clase TApplication.

file:///D|/Manuales/intro/2.html (21 of 26) [27/02/2003 16:23:53]

IDE

Patrones de cdigo. Al pulsar Ctrl+J se muestran los patrones de cdigo (tambin llamados "esqueletos") que pueden insertarse en el cdigo de nuestro programa. Pueden crearse y guardarse nuevos patrones.

Es posible configurar estas utilidades seleccionando Tools | Environment Options | Code Insight.

2.4. Compilacin, ejecucin y depuracin de programas.


El objetivo final es la creacin de un programa ejecutable correcto que funcione bajo Windows. El ejecutable se construye tomando como referencia los ficheros que forman el proyecto activo. Para esta tarea se utilizan los mens Project y Run (figura 2.18). Figura 2.18. Submens Project y Run del men principal.

file:///D|/Manuales/intro/2.html (22 of 26) [27/02/2003 16:23:53]

IDE

Project

Run

En la compilacin se trata de la obtencin del programa ejecutable (extensin .EXE). Las operaciones asociadas a este objetivo se encuentran en el men que se despliega al seleccionar la opcin Project del men principal (figura 2.18), y las ms importantes son:
q q

Compile Unit. Compila el modulo fuente activo (extensin .CPP) generando un fichero objeto (extensin .OBJ). Make. Genera el fichero ejecutable a partir de los ficheros objeto asociados al proyecto recompilando nicamente los mdulos fuente que se

hayan modificado desde la ltima vez que se compilaron. Build. Genera el fichero ejecutable a partir de los ficheros objeto asociados al proyecto recompilando todos los mdulos fuente, aunque no se hayan modificado desde la ltima vez que se compilaron.

Si durante la compilacin se detectaran errores, se mostraran en el editor de cdigo y se puede acceder directamente a las lneas de cdigo en las que se han detectado para facilitar su correccin. Para ejecutar el programa basta con pinchar sobre el botn correspondiente de la barra de herramientas o seleccionar la opcin Run | Run. C++ Builder proporciona facilidades para la depuracin de programas, seleccionables al desplegar el men Run (figura 2.18). Las ms importantes son:
q

Step Over F8. Ejecuta instruccin a instruccin el programa, pero ejecuta las llamadas a funciones como una instruccin ms, sin mostrar la

ejecucin de las instrucciones de las funciones.

file:///D|/Manuales/intro/2.html (23 of 26) [27/02/2003 16:23:53]

IDE

q q

Trace Into F7. Ejecuta instruccin a instruccin el programa, incluidas las instrucciones de las funciones llamadas. Run to Cursor F4. Ejecuta desde el principio del programa hasta la lnea en la que est situada el cursor.

Para que la depuracin sea ms completa y verstil se incorporan las siguientes opciones en el mismo men:
q q q

Evaluate/Modify Ctrl+F7. Evaluar expresiones que involucren a las variables y modificar los valores de las variables. Add Watch Ctrl+F5. Visualizar el contenido de una variable permanentemente. Add Breakpoint. Aade un punto de ruptura en la lnea en la que est situado el cursor. de modo que cuando se ejecute el programa se

detendr su ejecucin al llegar al siguiente punto de ruptura.

2.5. El almacn de objetos


Se accede al almacn seleccionando File | New. Contiene formularios, cuadros de dilogo, mdulos de datos, asistentes, DLLs, etc. que podemos utilizar para simplificar el desarrollo de aplicaciones. Todos ellos estn prediseados y pueden servirnos como punto de partida para nuestros propios diseos. Adems se pueden incorporar nuevos elementos que nosotros desarrollemos, consiguiendo de esta forma reutilizar nuestros diseos. Figura 2.19. El almacn de objetos.

file:///D|/Manuales/intro/2.html (24 of 26) [27/02/2003 16:23:53]

IDE

En este curso utilizaremos con frecuencia el almacn para crear nuevos proyectos (File | New | Application), para crear aplicaciones de consola (File | New | Console Wizard), para aadir nuevos formularios (File | New | Form) o ficheros de cdigo (File | New | Unit), para crear mdulos de datos (File | New | Data Module), etc.

2.6. Ejercicios

Ejemplos de aplicaciones simples y de consola.

file:///D|/Manuales/intro/2.html (25 of 26) [27/02/2003 16:23:53]

IDE

Pgina principal Francisco Cortijo Bon

file:///D|/Manuales/intro/2.html (26 of 26) [27/02/2003 16:23:53]

Mens

Curso de C++ Builder Lista completa de mens


Sobre el men principal y sus submens...

File

file:///D|/Manuales/appendix/menu/index.html (1 of 4) [27/02/2003 16:23:53]

Mens

Edit

Search

View

file:///D|/Manuales/appendix/menu/index.html (2 of 4) [27/02/2003 16:23:53]

Mens

Project

Run

Component

file:///D|/Manuales/appendix/menu/index.html (3 of 4) [27/02/2003 16:23:53]

Mens

Database

Tools

Workgroups

Help

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/menu/index.html (4 of 4) [27/02/2003 16:23:53]

Componentes

Curso de C++ Builder Componentes

q q q

3.1. Pginas de componentes. 3.2. Propiedades, mtodos y gestores de eventos. 3.3. Componentes visuales y no visuales.

Los componentes son unos elementos genricos con una funcionalidad muy concreta, cuya nica finalidad es la reutilizacin. Cada uno de ellos est destinado a realizar una tarea tpica en una aplicacin. Un componente de la VCL es una clase que caracteriza a un control de Windows agregando propiedades, mtodos y gestores de eventos a cada control. La filosofa de los componentes en C++ Builder es exactamente la misma que en Visual Basic. Esto es tanto as que algunos componentes pueden utilizarse en ambos entornos (los componentes ActiveX).

3.1. Pginas de componentes


Como ya hemos comentado anteriormente los componentes se agrupan en la paleta de componentes en distintas pginas, a saber:
q

q q

q q

Standard: Incluye los componentes comunes y ms habituales de los programas Windows. Additional: Los componentes de esta pgina son controles especializados. propios de C++ Builder. Win32: Componentes de cuadros de dilogo propios de Windows 95/NT. System: Esta pgina incluye controles muy especializados para interaccin con el sistema. Internet: Componentes para distintos protocolos de acceso a Internet. Data Access y Data Controls: Componentes especializados para acceso a bases

file:///D|/Manuales/intro/3.html (1 of 5) [27/02/2003 16:23:54]

Componentes

q q

de datos. Midas: Esta pgina incluye componentes que permiten el desarrollo de aplicaciones multicapa con MIDAS. Decision Cube: Incluye componentes para realizar anlisis multidimensionales de datos con objeto de tomar decisiones. QReport: Componentes para disear rpidamente informes y resmenes. Dialogs: Contiene cuadros de dilogo comunes en aplicaciones Windows listos para usar. Win 3.1: Componentes propios de Windows 3.1, la mayora de ellos se mantienen en C++ Builder slo por compatibilidad con versiones anteriores. Samples: Componentes de demostracin (cmo hacer componentes personalizados). Active X: Los componentes de esta pgina son objetos Active X, creados por otros desarrolladores puede que utilizando otros lenguajes de programacin.

Para ms detalles, consultar la lista completa de componentes, agrupados por pginas.

3.2. Propiedades, mtodos y gestores de eventos


De un componente podemos destacar tres aspectos: sus propiedades, los mtodos que puede ejecutar y los eventos a los que puede responder.

Propiedades.
Las propiedades son los elementos del componente que configuran su aspecto y controlan su comportamiento. Muchos componentes tienen propiedades en comn. Por ejemplo, todos los componentes visuales tienen las propiedades Top y Left que controlan la posicin del componente en el formulario, tanto en tiempo de diseo como en tiempo de ejecucin. Hemos visto como pueden establecerse y modificarse las propiedades de los componentes en tiempo de diseo utilizando el inspector de objetos. Las propiedades tienen, normalmente, un mtodo de acceso asociado que se ejecuta al modificar la propiedad en tiempo de ejecucin. Para modificar una propiedad
file:///D|/Manuales/intro/3.html (2 of 5) [27/02/2003 16:23:54]

Componentes

basta (generalmente) con asignarle el nuevo valor. Al realizar un cambio, la VCL invoca el mtodo de acceso a la propiedad. En el caso concreto de la propiedad Left, la VCL dibuja de nuevo todo el formulario en la nueva ubicacin. A modo de resumen, las propiedades tienen dos especificadores de acceso que se emplean al consultar o modificar el valor de una propiedad en tiempo de ejecucin. En definitiva, hay un especificador de lectura y un especificador de escritura. Los especificadores de acceso asocian mtodos de lectura o de escritura (funciones, en definitiva) con las propiedades. Al consultar o modificar el valor de una propiedad se invocan, automticamente, las funciones respectivas asociadas:

Al asignar un nuevo valor a una propiedad se est accediendo al especificador de escritura. La VCL comprueba si existe un mtodo de acceso asociado al especificador de escritura y si es as, lo ejecuta. Si no existe, simplemente asigna el nuevo valor a la propiedad. Al consultar el valor de una propiedad se est accediendo al especificador de lectura. En la mayora de los casos el especificador de lectura no hace ms que devolver el valor de la propiedad.

EJERCICIO 4: Modificacin y consulta de propiedades en tiempo de ejecucin.

Mtodos.
Los mtodos son funciones asociadas al componente que pueden invocarse para que el componente realice distintas acciones. Por ejemplo, todos los componentes visuales tienen un mtodo llamado Show() para mostralos y otro llamado Hide() para ocultarlos. En el ejemplo 3 invocamos al mtodo Terminate() asociado a la aplicacin que se estaba
file:///D|/Manuales/intro/3.html (3 of 5) [27/02/2003 16:23:54]

Componentes

ejecutando (Objeto Application) para terminar su ejecucin como respuesta a la pulsacin del botn. En C++ los mtodos son miembros de una clase, al igual que las propiedades.

EJERCICIO 5: Mtodos asociados a componentes.

Eventos.
Un evento es cualquier suceso que puede ocurrirle a un componente (movimiento del ratn, pulsacin de algn botn del ratn, pulsacin de una tecla del teclado, desplazamiento o redimensionamiento de una ventana, etc.) que pueden condicionar el comportamiento y apariencia del programa. Cada componente poseer una serie de eventos que puede recibir o generar. Se pueden tratar los eventos de un componente que necesitemos, y dejar que los dems sean tratados por defecto. Cuando se responde a un evento se dice que se est manipulando el evento. Los eventos se manejan mediante los gestores o manipuladores de eventos. La forma de tratar un evento asociado a un componente en C++ Builder es sencilla: se activa el componente que va a responder al evento y utilizando el Inspector de Objetos (pestaa Events) se selecciona el evento al que debe responder y, cuando se active el editor de cdigo, se escribe el cdigo asociado al gestor del evento. Se dice que Windows est orientado a eventos. Esto significa que cualquier programa est condicionado por lo eventos que ocurren en el entorno Windows. Un programa Windows est continuamente sondeando al sistema ante la ocurrencia de cualquier evento y de ocurrir, Windows avisa al programa envindole un mensaje. Un programa Windows est ocioso la mayor parte del tiempo esperando a que ocurra algn evento.

file:///D|/Manuales/intro/3.html (4 of 5) [27/02/2003 16:23:54]

Componentes

EJERCICIO 6: Gestores de eventos.

3.3. Componentes visuales y no visuales


Se pueden establecer muchas clasificaciones para los componentes. Una de ellas es la de visuales o controles, frente a no visuales. Un componente es visual cuando tiene una representacin grfica en tiempo de diseo y ejecucin (botones, barras de scroll, cuadros de edicin, etc.), y se dice no visual en caso contrario (temporizadores, cuadros de dilogo -no visibles en la fase de dieo-, etc). Por lo dems no existen ms diferencias entre ellos, excepto, claro est, las derivadas de la visualizacin del componente. Los componentes no visuales se pueden colocar en los formularios de la misma manera que los controles, aunque en este caso su posicin es irrelevante.

Pgina principal Francisco Cortijo Bon

file:///D|/Manuales/intro/3.html (5 of 5) [27/02/2003 16:23:54]

Paleta de componentes - Standard

Curso de C++ Builder La paleta de componentes

Pgina Standard
Iconos de los componentes agrupados en la pgina Standard

Esta pgina incluye los componentes comunes y ms habituales de los programas Windows:

Crea una barra de men (que acta como men principal). Para aadir opciones al men y a los submens, aadir el componente MainMenu al formulario y hacer doble click sobre l para acceder al diseador de mens. Crea mens desplegables (tambin llamados mens contextuales) que aparecen cuando se pincha con el botn PopupMenu derecho del ratn. Para configurar el men desplegable, proceder como con el componente MainMenu. Muestra texto que el usuario no puede seleccionar ni manipular. Se usa para mostrar textos de ttulo, Label encabezamientos, o incluso para mostrar resultados, ya que puede establecerse su valor (propiedad Caption) en tiempo de ejecucin. MainMenu Edit Memo Muestra un rea de edicin de texto en la que el usuario puede introducir y modificar una nica lnea de texto. Muestra un rea de edicin de texto en la que el usuario puede introducir y modificar mltiples lneas de texto.

file:///D|/Manuales/appendix/components/Standard.html (1 of 2) [27/02/2003 16:23:55]

Paleta de componentes - Standard

Button

Crea un botn que el usuario puede pulsar para efectuar acciones.

Presenta una opcin binaria (Si/No - Verdad/Falso) de manera que cuando se selecciona este control, se permuta entre ambos valores. Este control puede emplearse para crear un grupo de estos controles que representen elecciones que no CheckBox sean mutuamente exclusivas (al contrario que los RadioButton, por lo que el usuario puede seleccionar ms de una opcin en un grupo. Presenta una opcin binaria (Si/No - Verdad/Falso) de manera que cuando se selecciona este control, se permuta entre RadioButton ambos valores. Este control puede emplearse para crear un grupo de estos controles que representen elecciones mutuamente exclusivas (al contrario que los CheckBox, por lo que el usuario puede seleccionar slo una en un grupo. ListBox ComboBox ScrollBar GroupBox Muestra una lista de eleciones que est acompaada de una barra de scroll. Muestra una lista de eleciones. Es un control que combina aspectos de un componente ListBox y de un componente Edit: el usuario puede introducir datos en el rea de edicin o seleccionar en el rea de lista. Prociona una forma cmoda de modificar el rea visible de un formulario o de una lista. Tambin puede usarse para "desplazarse" en un rango -amplio- de valores por incrementos prefijados. Contenedor para agrupar opciones relacionadas en un formulario.

RadioGroup Contenedor que crea un grupo de componentes RadioButton en un formulario. Panel ActionList Contenedor que puede contener otros componentes en un formulario. Se usa para crear barras de herramientas y lneas de estado. Los componentes que contiene estn asociados al panel. Crea grupos de acciones que centralizan las respuestas de la plicacin ante las acciones del usuario.

file:///D|/Manuales/appendix/components/Standard.html (2 of 2) [27/02/2003 16:23:55]

Paleta de componentes - Additional

Curso de C++ Builder La paleta de componentes

Pgina Additional
Iconos de los componentes agrupados en la pgina Additional

Los componentes de esta pgina son controles especializados:

BitBtn SpeedButton MaskEdit StringGrid DrawGrid

Crea un botn que puede contener un grfico (tipo "bitmap"). Crea un botn que puede contener un grfico pero no contiene texto. Estos botones se agrupan, normalmente, dentro de un panel para crear una barra de herramientas. Permite la introduccin y edicin de datos, como lo hace el componente Edit, salvo que proporciona la posibilidad de especificar formatos particulares, como cdigos postales o nmeros de telfono. Crea una rejilla que puede usarse para mostrar cadenas en filas y columnas. Crea una rejilla que puede usarse para mostrar datos en filas y columnas.

file:///D|/Manuales/appendix/components/Additional.html (1 of 2) [27/02/2003 16:23:55]

Paleta de componentes - Additional

Image Shape Bevel ScrollBox CheckListBox Splitter StaticText ControlBar Chart

Muestra un "bitmap" o un icono. Dibuja figuras geomtricas, como elipses, crculos, rectngulos, cuadrados o rectngulos y cuadrados con bordes redondeados. Crea lneas o cuadros con apariencia tridimensional y como si estuviera esculpida (alto o bajorrelieve). Crea un contenedor redimensionable que muestra barras de scroll cuando sea necesario. Muestra una lista de eleciones que est acompaada de una barra de scroll. Es muy parecido al componente ListBox salvo que cada elemento de la lista tiene asociado un CheckBox. Aade un divisor a un formulario entre dos componentes alineados que permite al usuario redimensionar los controles en tiempo de ejecucin pinchando y arrastrando la lnea de divisin. Es un componente de texto no editable, como el componente Label, slo que StaticText tiene su propio gestor de ventana. Un gestor para acompaar a barras de herramientas que se usa para poder mover este tipo de barras. Un visualizador equivalene a TTable.

file:///D|/Manuales/appendix/components/Additional.html (2 of 2) [27/02/2003 16:23:55]

Paleta de componentes - Win32

Curso de C++ Builder La paleta de componentes

Pgina Win32
Iconos de los componentes agrupados en la pgina Win32

Esta pgina incluye componentes comunes de aplicaciones para 32 bits.

TabControl PageControl ImageList

Divisor de pginas mutuamente exclusivas accesibles por pestaas. Se emplea para construir cuadros de dilodo con mltiples pginas dentro de la misma ventana. Una lista de imgenes es una coleccin de imgenes del mismo tamao accesibles mediante un ndice. Se emplea para gestionar eficientemente grandes conjuntos de imgenes o "bitmaps". Paracrear una lista de imgenes, aadir un componente ImageList al formulario y hacer doble click sobre l para acceder al editor de listas de imgenes. Es una especializacin del componente Memo: proporciona la posibilidad de 1) modificar propiedades acrerca de la fuente de letra (familia, tamao, color, negrita o itlica), 2) modificar propiedades de formato (alineamiento, tabulaciones, indentacin o numeracin), y 3) marcacin de texto y arrastre del mismo. Es una barra que muestra un rango y un indicador que muestra el valor actual y que permite modificarlo.

RichEdit TrackBar

file:///D|/Manuales/appendix/components/Win32.html (1 of 2) [27/02/2003 16:23:56]

Paleta de componentes - Win32

ProgressBar UpDown HotKey Animate

Es una barra rectangular que se va "llenando" de izquierda a derecha. Se emplea para mostrar cmo progresa una operacin. Son botones para incrementar y decrementar valores. Asigna una combinacin de teclas a cualquier componente.

Una ventana que se emplea para mostrar ficheros AVI (Audio Video Interleaved) o series de "bitmaps" dispuestos en secuencia, como una pelcula. Muestra una lista de elecciones que est acompaada de una barra de scroll para seleccionar fechas. La fecha DateTimePicker puede seleccionarse desde el calendario o empleando la barra de scroll o las flechas. MonthCalendar Muestra un calendario que representa un solo mes. TreeView ListView HeaderControl StatusBar ToolBar CoolBar PageScroller Muestra un conjunto de objetos estructurados jerrquicamente. Permite ver una lista en columnas. Muestra un encabezamiento sobre columnas de texto o nmeros. Este control puede dividirse en varias partes para proporcionar cabeceras para mltiples columnas. rea para indicar el estado de acciones o textos de pista amplios ("Hints") en la parte baja de la ventana. Gestiona botones rpidos y otros controles, colocndolos adecuadamente ajustando su posicin y tamao. Muestra una coleccin de controles "CoolBand" dentro de bandas que pueden moverse y redimensionarse. Contiene objetos dentro del rea de cliente que pueden desplazarse horizontal o verticalmente sin usar una barra de scroll sino empleando las flechas.

file:///D|/Manuales/appendix/components/Win32.html (2 of 2) [27/02/2003 16:23:56]

Paleta de componentes - System

Curso de C++ Builder La paleta de componentes

Pgina System
Iconos de los componentes agrupados en la pgina System

Esta pgina incluye controles muy especializados:

Timer PaintBox MediaPlayer OleContainer

Es un componente no visual que acta como temporizador. Se emplea para ejecutar una serie de instrucciones (mediante el gestor del evento OnTimer) que deben ejecutarse cuando se alcanza el valor especificado como intervalo (propiedad Interval). Especifica un rea rectangular sobre un formulario que delimita la zona en la que puede dibujarse desde una aplicacin. Muestra una ventana con botones (similares a los de cualquier reproductor de audio o video) para reproducir video o sonido. Crea un rea de cliente OLE (Object Linking and Embedding) en un formulario.

DdeClientConv Establece una conexin cliente a una aplicacin servidora DDE (Dynamic Data Exchange).

file:///D|/Manuales/appendix/components/System.html (1 of 2) [27/02/2003 16:23:56]

Paleta de componentes - System

DdeClientItem Especifica los datos del cliente DDE (Dynamic Data Exchange) que se transfieren en una conversacin DDE. DdeServerConv Establece una conexin servidora a una aplicacin cliente DDE (Dynamic Data Exchange). DdeServerItem Especifica los datos del servidor DDE (Dynamic Data Exchange) que se transfieren en una conversacin DDE.

file:///D|/Manuales/appendix/components/System.html (2 of 2) [27/02/2003 16:23:56]

Paleta de componentes - Internet

Curso de C++ Builder La paleta de componentes

Pgina Internet
Iconos de los componentes agrupados en la pgina Internet

Los componentes de esta pgina ofrecen diferentes protocolos de acceso a Internet:

Add to a form or data module to turn an application into a TCP/IP client. ClientSocket specifies a desired connection to a TCP/IP server, manages the open connection, and terminates the completed connection. Add to a form or data module to turn an application into a TCP/IP server. ServerSocket listens for requests for TCP/IP ServerSocket connections from other machines and establishes connections when requests are received. Converts an ordinary data module to a Web module and enables the Web server application to respond to HTTP request WebDispatcher messages. Converts an HTML template into a string of HTML commands that can be interpreted by a client application such as a PageProducer Web browser. The commands and HTML-transparent tags are replaced with customized content by the OnHTMLTag event. Assembles a sequence of HTML commands to generate a tabular display of the records from a TQuery object, which QueryTableProducer obtains its parameters from an HTTP request message. Assembles a sequence of HTML commands to generate a tabular display of the records from a TDataSet object. This DataSetTableProducer allows an application to create images of a dataset for an HTTP response message. ClientSocket
file:///D|/Manuales/appendix/components/Internet.html (1 of 2) [27/02/2003 16:23:57]

Paleta de componentes - Internet

DataSetPageProducer NMDayTime NMEcho NMFinger NMFTP NMHTTP NMMsg NMMsgServ NMNNTP NMPOP3 NMUUProcessor NMSMTP NMStrm NMStrmServ NMTime NMUDP PowerSock NMGeneralServer HTML NMURL

Converts an HTML template that contains field references into a string of HTML commands that can be interpreted by a client application such as a Web browser. Special HTML-transparent tags are replaced with field values. Gets the date and time from an internet/intranet daytime server. Sends text to an internet echo server, and echoes it back to you. Gets information about a user from an internet finger server, using the Finger protocol described in RFC 1288. Implements file transfer protocol. Invisible ActiveX control provides easy access for Internet File Transfer Protocol (FTP) services for transferring files and data between a remote and local machine. Invisible ActiveX control implements the HTTP Protocol Client, allowing users to directly retrieve HTTP documents if no browsing or image processing is necessary. Sends simple ASCII text messages across the internet or intranet using TCP/IP protocol. Receives messages sent with the TNMMsg component. Invisible ActiveX Client Control allows applications to access Networking News Transfer Protocol (NNTP) news servers. It provides news reading and posting capabilities. Invisible ActiveX control that retrieves mail from UNIX or other servers supporting POP3 protocol. MIME encodes or UUEncodes files and decodes MIME-encoded or UUEncoded files. ActiveX control that gives applications access to SMTP mail servers and mail posting capabilities. Sends streams to a stream server across the internet or an intranet. Receives streams sent with the TNMStrm component. Gets the date and time from Internet time servers, as described in RFC 868. Invisible WinSock ActiveX Control provides easy access to User Datagram Protocol (UDP) network services. It implements WinSock for both client and server and represents a communication point utilizing UDP network services. It can also be used to send and retrieve UDP data. Serves as a base for creating controls for dealing with other protocols, or for creating custom protocols. Serves as a base class for developing multi-threaded internet servers, such as custom servers or servers that support RFC standards. Invisible ActiveX control implements an HTML viewer, with or without automatic network retrieval of HTML documents, and provides parsing and layout of HTML data, as well as a scrollable view of the selected HTML page. The HTML component can also be used as a nonvisual HTML parser to analyze or process HTML documents. Decodes URL data into a readable string, and encodes standard strings into URL data format.

file:///D|/Manuales/appendix/components/Internet.html (2 of 2) [27/02/2003 16:23:57]

Paleta de componentes - Data Access

Curso de C++ Builder La paleta de componentes

Pgina Data Access


Iconos de los componentes agrupados en la pgina Data Access

Esta pgina incluye componentes especialzados para acceso a bases de datos:

DataSource Acts as a conduit between a dataset component such as TTable and data-aware components such as TDBGrid. Retrieves data from a physical database table via the BDE and supplies it to one or more data-aware components through a Table DataSource component. Conversely, it also sends data received from a component to a physical database via the BDE. Uses SQL statements to retrieve data from a physical database table via the BDE and supplies it to one or more data-aware Query components through a TDataSource component. Conversely, uses SQL statements to send data from a component to a physical database via the BDE. Enables an application to access server stored procedures. Sends data received from a component to a physical database via StoredProc the BDE. Database Sets up a persistent connection to a database, especially a remote database requiring a user login and password.

file:///D|/Manuales/appendix/components/Data_Access.html (1 of 2) [27/02/2003 16:23:58]

Paleta de componentes - Data Access

Provides global control over a group of Database components. A default TSession component is automatically created for each C++Builder database application. You must use the TSession component only if you are creating a multithreaded database application. Each database thread requires its own session component. BatchMove Copies a table structure or its data. Can be used to move entire tables from one database format to another. Lets you use cached updates support with read-only datasets. For example, you could use a TUpdateSQL component with a "canned" query to provide a way to update the underlying datasets, essentially giving you the ability to post updates to a UpdateSQL read-only dataset. You associate a TUpdateSQL component with a dataset by setting the dataset's UpdateObject property. The dataset automatically uses the TUpdateSQL component when cached updates are applied. NestedTable Retrieves the data in a nested dataset field and supplies it to data-aware controls through a datasource component. Session

file:///D|/Manuales/appendix/components/Data_Access.html (2 of 2) [27/02/2003 16:23:58]

Paleta de componentes - Data Controls

Curso de C++ Builder La paleta de componentes

Pgina Data Controls


Iconos de los componentes agrupados en la pgina Data Controls

Esta pgina incluye componentes especialzados para gestin de bases de datos:

DBGrid

DBNavigator DBText DBEdit DBMemo DBImage DBListBox DBComboBox

Data-aware custom grid that enables viewing and editing data in a tabular form similar to a spreadsheet. Makes extensive use of TField properties (set in the Fields editor) to determine a column's visibility, display format, ordering, and so on. Data-aware navigation buttons that move a table's current record pointer forward or backward. The navigator can also place a table in Insert, Edit, or Browse state, post new or modified records, and retrieve updated data to refresh the display. Data-aware label that displays a field value in the current record. Data-aware edit box that displays or edits a field in the current record. Data-aware memo box that displays or edits BLOB text in the current record. Data-aware image box that displays, cuts, or pastes bitmapped BLOB images to and from the current record. Data-aware list box that displays a scrolling list of values from a column in a table. Data-aware combo box that displays or edits a scrolling list of values from a column in a table.

file:///D|/Manuales/appendix/components/Data_Controls.html (1 of 2) [27/02/2003 16:23:58]

Paleta de componentes - Data Controls

DBCheckBox DBRadioGroup

Data-aware check box that displays or edits a Boolean data field from the current record. Data-aware group of radio buttons that display or set column values. DBLookupListBox is a data-aware list box that derives its list of display items from either a Lookup field defined for a dataset or a secondary data source, data field, and key. In either case, a user is presented with a restricted list of choices DBLookupListBox from which to set a valid field value. When a user selects a list item, the corresponding field value is changed in the underlying dataset. To specify list box items using a lookup field, the dataset to which you link the control must already define a lookup field. DBLookupComboBox is a data-aware combo box that derives its drop-down list of display items from either a lookup field defined for a dataset or a secondary data source, data field, and key. In either case, a user is presented with a DBLookupComboBox restricted list of choices from which to set a valid field value. When a user selects a list item, the corresponding field value is changed in the underlying dataset. To specify combo box list items using a lookup field, the dataset to which you link the control must already define a lookup field. DBRichEdit A multiline edit control that can display and edit a rich text memo field in a dataset. A DBCtrlGrid control displays multiple fields in multiple records in a tabular grid format. Each cell in the grid displays DBCtrlGrid multiple fields from a single record. DBChart Place the component on a form and right-click it to display the third-party developer's Help topics.

file:///D|/Manuales/appendix/components/Data_Controls.html (2 of 2) [27/02/2003 16:23:58]

Paleta de componentes - MIDAS

Curso de C++ Builder La paleta de componentes

Pgina MIDAS
Iconos de los componentes agrupados en la pgina MIDAS

Esta pgina incluye componentes que permiten el desarrollo de aplicaciones multicapa con MIDAS:

Implements a database-independent dataset that can be used independently in a single-tiered application, or to represent data received from a server in a multi-tiered database application. See Creating and using a client dataset Establishes a DCOM connection to a remote server in a multi-tiered database application. See Connecting to the DCOMConnection application server Establishes a TCP/IP connection to a remote server in a multi-tiered database application. See Connecting to the SocketConnection application server Establishes an OLEnterprise connection to a remote server in a multi-tiered database application. See Connecting to OLEnterpriseConnection the application server Encodes data from a dataset into packets than can be sent to client applications and applies updates that are received DataSetProvider from client applications to that dataset. See Creating a data provider for the application server and Providing from and resolving to a dataset Encodes data from a dataset into packets than can be sent to client applications and applies updates that are received Provider from client applications to a dataset or database server. See Creating a data provider for the application server. ClientDataSet
file:///D|/Manuales/appendix/components/MIDAS.html (1 of 2) [27/02/2003 16:23:59]

Paleta de componentes - MIDAS

SimpleObjectBroker RemoteServer MIDASConnection

Locates a server for a connection component from a list of available application servers. See Brokering connections. (For backward compatibility only) Establishes a DCOM connection to a remote server in a multi-tiered application. (For backward compatibility only) Establishes a DCOM, TCP/IP, or OLEnterprise connection to a remote server in a multi-tiered application.

file:///D|/Manuales/appendix/components/MIDAS.html (2 of 2) [27/02/2003 16:23:59]

Paleta de componentes - Decision Cube

Curso de C++ Builder La paleta de componentes

Pgina Decision Cube


Iconos de los componentes agrupados en la pgina Decision Cube

Esta pgina incluye componentes para realizar anlisis multidimensionales de datos con objeto de tomar decisiones:

DecisionCube A multidimensional data store. See Using decision cubes. Specialized form of TQuery used to define the data in a decision cube. See Creating decision datasets with the Decision Query DecisionQuery editor. DecisionSource Defines the current pivot state of a decision grid or a decision graph. See Using decision sources. DecisionPivot Use to open or close decision cube dimensions or fields by pressing buttons. See Using decision pivots. DecisionGrid Displays single and multidimensional data in table form. See Creating and Using decision grids. Displays fields from a decision grid as a dynamic graph that changes when dimensions are modified. See Using decision DecisionGraph graphs.

file:///D|/Manuales/appendix/components/Decision_Cube.html [27/02/2003 16:23:59]

Paleta de componentes - QReport

Curso de C++ Builder La paleta de componentes

Pgina QReport
Iconos de los componentes agrupados en la pgina QReport

Esta pgina incluye componentes para disear rpidamente informes y resmenes. Se pueden incorporar cabeceras y pies de pginas, resmenes, agrupaciones con cabeceras y pies, etc. Estos informes pueden realizarse a partir de cualquier fuente de datos: TTable, TQuery, listas, matrices, etc. arrays. Puede usarse un visalizador previo para comprobar los resultados. Automticamente se realizan clculos similares a como se hacen en una hoja de clculo.

QuickRep QRSubDetail QRStringsBand QRBand QRChildBand

The basic report form on which you build all your reports. It is a visual component that takes the shape of the currently selected paper size. Create reports by dropping bands and printable components on the TQuickRep component and connecting it to a dataset. Links additional datasets into a report. Typically you would set up a master/detail relationship between table or query components and create a similar relationship with TQRSubDetail components. Drops bands containing strings onto a report. Drop bands on a TQuickRep component and set the BandType property to tell how the band will behave during report generation. If you have bands with expanding components and want other components to be moved down accordingly you can create a child band and put the moving components on it. It's also useful if you have very long bands that span multiple pages.

file:///D|/Manuales/appendix/components/QReport.html (1 of 2) [27/02/2003 16:24:00]

Paleta de componentes - QReport

QRGroup

Allows you to group bands together and provides control for headers, footers, and page breaks. Prints static or other non-database text. Enter the text to be displayed in the Caption property. You can split text on QRLabel multiple lines and even multiple pages. A data-aware version of the TQRLabel that prints the value of a database field. Calculated fields and text field types can be printed, including String fields, various numeric fields, date fields and memo fields. Text can span multiple lines and QRDBText pages. You connect the component to the data field by setting the DataSource and DataField properties. Unlike regular data-aware components, TQRDBText works even with dataset controls disabled to improve speed. QRExpr Prints database fields, calculations, and static text. Input a valid QuickReport expression in the Expression property. Prints system information such as report title, current page number, and so on. Select the data to print in the Data QRSysData property. Set any preceding text in the Text property. Prints a large amount of text that does not come from a database field. It can be static text or you can change it during QRMemo report generation. You can set the field to expand vertically as needed and then span multiple pages if necessary. QRExprMemo Allows you to programmatically generate contents using Quick Report expressions. QRRichText Allows you to embed rich text into your report. QRDBRichText Provides a Quick Report wrapper for accessing DBRichText fields in your reports. QRShape Draws simple shapes like rectangles, circles, and lines on a report. QRImage Displays a picture on a report. Supports all image formats supported by the TPicture class. QRDBImage Prints images stored in binary (BLOB) fields. Prints all graphics formats supported by C++Builder. QRCompositeReport Allows you to combine more than one report together. QRPreview Brings up a form that allows you to preview a report on the screen and print it. QRTextFilter Lets you export the contents of your report into text format. QRCSVFilter Lets you export the contents of your report into a comma-delimited database source file. QRHTMLFilter Lets you export the contents of your report into HTML. QRChart Allows you to take a TChart component and drop it onto your Quick Report form.

file:///D|/Manuales/appendix/components/QReport.html (2 of 2) [27/02/2003 16:24:00]

Paleta de componentes - Dialogs

Curso de C++ Builder La paleta de componentes

Pgina Dialogs
Iconos de los componentes agrupados en la pgina Dialogs

Esta pgina incluye las diferentes ventanas de dilogo comunes en aplicaciones Windows. Estas ventanas de dilogo proporcionan un interface consistente para realizar operaciones sobre ficheros como abrir, guardar e imprimir. Una ventana de dilogo se abre al llamar al mtodo Execute(). Este mtodo devuelve un valor lgico: true si el usuario elige OK en la ventana de dilogo, false si el usuario elige Cancel o sale de la ventana de dilogo sin salvar los cambios. Cada ventana de dilogo (excepto la asociada al componente PrinterSetup) tiene la propiedad Options que afecta a su apariencia y comportamiento. Una ventana de dilogo puede cerrarse desde un programa mediante el mtodo CloseDialog(). Para modificar en tiempo de ejecucin su posicin, usar las propiedades Handle, Left, Top y Position.

file:///D|/Manuales/appendix/components/Dialogs.html (1 of 2) [27/02/2003 16:24:00]

Paleta de componentes - Dialogs

OpenDialog SaveDialog OpenPictureDialog

Muestra una ventana de dilogo comn de Windows para seleccionar y abrir ficheros. Muestra una ventana de dilogo comn de Windows para seleccionar y guardar ficheros.

Muestra una ventana de dilogo modal comn de Windows para seleccionar y abrir ficheros grphicos. Es idntica a la ventana asociada a OpenDialog salvo que contiene una regin para previsualizacin de imgenes. Muestra una ventana de dilogo modal comn de Windows para seleccionar y guardar ficheros grphicos. Es idntica SavePictureDialog a la ventana asociada a SaveDialog salvo que contiene una regin para previsualizacin de imgenes. FontDialog ColorDialog PrintDialog Muestra una ventana de dilogo comn de Windows para especificar la familia, tamao y estilo de letra. Muestra una ventana de dilogo comn de Windows para especificar color. Muestra una ventana de dilogo comn de Windows para especificar informacin de impresin.

PrinterSetupDialog Muestra una ventana de dilogo comn de Windows para configurar impresoras. FindDialog ReplaceDialog Muestra una ventana de dilogo comn de Windows para especificar la cadena a buscar. Muestra una ventana de dilogo comn de Windows para especificar la cadena a buscar y la cadena por la que se va a reemplazar.

file:///D|/Manuales/appendix/components/Dialogs.html (2 of 2) [27/02/2003 16:24:00]

Paleta de componentes - Win 3.1

Curso de C++ Builder La paleta de componentes

Pgina Win 3.1


Iconos de los componentes agrupados en la pgina Win 3.1

Esta pgina incluye controles propios de Windows 3.1 para permitir compatibilidad con aplicaciones antiguas. Muchos de estos controles tienen su versin actualizada en componentes incluidos en la pgina Win32. Estos controles no deberan usarse al desarrollar nuevas aplicaciones. En la siguiente tabla se indica qu control debera usarse en su lugar: Control Win 3.1 Sustituir por TabSet Outline NoteBook Header TabControl TreeView PageControl HeaderControl Pgina Win32 Win32 Win32 Win32 Win32

DBLookupCombo DBLookupComboBox Data Controls

TabbedNoteBook PageControl

file:///D|/Manuales/appendix/components/Win_3.1.html (1 of 2) [27/02/2003 16:24:01]

Paleta de componentes - Win 3.1

DBLookupList Data-aware list box that displays values looked up from columns in another table at runtime. DBLookupCombo Data-aware combo box that displays values looked up from columns in another table at runtime. Creates notebook-like tabs. You can use the TabSet component with the Notebook component to enable users to change TabSet pages. Outline Displays information in a variety of outline formats. Creates a component that contains multiple pages, each with its own set of controls. Users select a page by clicking the tab TabbedNotebook at the top of the page Notebook Creates a component that can contain multiple pages. Used with the Notebook component, it enables users to change pages. Creates a sectioned region for displaying data. Users can resize each section of the region to display different amounts of Header data. FileListBox Displays a scrolling list of files in the current directory. DirectoryListBox Displays the directory structure of the current drive. Users can change directories in a directory list box. DriveComboBox Displays a scrolling list of available drives. FilterComboBox Specifies a filter or mask to display a restricted set of files.

file:///D|/Manuales/appendix/components/Win_3.1.html (2 of 2) [27/02/2003 16:24:01]

Paleta de componentes - Samples

Curso de C++ Builder La paleta de componentes

Pgina Samples
Iconos de los componentes agrupados en la pgina Samples

Esta pgina incluye ejemplos de componentes personalizados que pueden construirse e incorporarse a la paleta de componentes. El cdigo fuente est disponible en el directorio \EXAMPLES\CONTROLS\SOURCE de la instalacin.

Pie Performance Graph CSpinButton CSpinEdit CGauge CDirectoryOutline CColorGrid CCalendar IBEVentAlerter

file:///D|/Manuales/appendix/components/Samples.html [27/02/2003 16:24:01]

Paleta de componentes - ActiveX

Curso de C++ Builder La paleta de componentes

Pgina Active X
Iconos de los componentes agrupados en la pgina Active X

Los componentes de esta pgina son objetos ActiveX. Son aplicaciones completas y portables creadas por otros desarrolladores.

Lets you create highly customized charts. Choose Properties to display a tabbed control panel that lets you define the values, appearance, and end-user functionality of the chart component. VSSpell Visual Speller, lets you customize a spelling checker. F1Book Formula One, lets you design a spreadsheet with its full-featured Designer. VtChart Lets you create true 3D charts. Graph Pinnacle Graph, lets you create 2D graphs. Chartfx

file:///D|/Manuales/appendix/components/ActiveX.html [27/02/2003 16:24:02]

Paleta de componentes

Curso de C++ Builder La paleta de componentes

La paleta de componentes se estructura, por defecto, en 14 pginas. En la siguiente tabla agrupamos las pginas segn nuestra conveniencia, siguiendo el criterio de utilidad en este curso. Las pginas cuyo ttulo est precedido por el smbolo espaol. estn traducidas al

Standard Additional Win32 System Dialogs Data Access Data Controls QReport Decision Cube Internet MIDAS ActiveX Samples Win 3.1

file:///D|/Manuales/appendix/components/index.html [27/02/2003 16:24:02]

Ejercicio 4. Modificacin y consulta de propiedades en tiempo de ejecucin

Curso de C++ Builder Ejercicio 4. Modificacin y consulta de propiedades en tiempo de ejecucin

Sobre el formulario que estamos empleando, observar que su ttulo qued fijado a Form de Prueba despus de modificar la propiedad Caption del formulario. Para modificar su valor en tiempo de ejecucin haremos que, por ejemplo, el ttulo se establezca en el momento de la creacin de la ventana. Para ello escribiremos un gestor para el evento OnCreate asociado al componente MainForm. Recordar que basta con hacer doble click en OnCreate (pestaa Events del inspector de objetos) del componente MainForm. Escribiremos el siguiente fragmento de cdigo:
//-----------------------------------------------------------void __fastcall TMainForm::FormCreate(TObject *Sender) { MainForm->Caption = "Primer programa con C++ Builder"; } //------------------------------------------------------------

A continuacin, modificaremos el color del formulario (propiedad Color) siempre que el valor de esta propiedad est establecido al valor por defecto (clBtnFace):
//-----------------------------------------------------------void __fastcall TMainForm::FormCreate(TObject *Sender) { MainForm->Caption = "Primer programa con C++ Builder"; if (MainForm->Color == clBtnFace) MainForm->Color = clWhite; } // Lectura // Escritura

file:///D|/Manuales/intro/ejemplos/ej4.html (1 of 3) [27/02/2003 16:24:02]

Ejercicio 4. Modificacin y consulta de propiedades en tiempo de ejecucin

//------------------------------------------------------------

Finalmente, estableceremos que cuando empiece la ejecucin del programa se encuentre desactivado el CheckBox:
//-----------------------------------------------------------void __fastcall TMainForm::FormCreate(TObject *Sender) { MainForm->Caption = "Primer programa con C++ Builder"; if (MainForm->Color == clBtnFace) MainForm->Color = clWhite; CheckBox->Checked = false; } //-----------------------------------------------------------// Lectura // Escritura

// Escritura

Si generamos el ejecutable y ejcutamos el programa, el resultado es el mostrado en la figura E4.1. Figura E4.1. El programa al iniciar su ejecucin despus de modificar propiedades en tiempo de ejecucin.

file:///D|/Manuales/intro/ejemplos/ej4.html (2 of 3) [27/02/2003 16:24:02]

Ejercicio 4. Modificacin y consulta de propiedades en tiempo de ejecucin

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/ej4.html (3 of 3) [27/02/2003 16:24:02]

Ejercicio 5. Mtodos asociados a componentes

Curso de C++ Builder Ejercicio 5. Mtodos asociados a componentes

Modificaremos el gestor del evento OnCreate del componente MainForm para que no se muestren los dos botones de radio.
//--------------------------------------------------------------void __fastcall TMainForm::FormCreate(TObject *Sender) { MainForm->Caption = "Primer programa con C++ Builder"; if (MainForm->Color == clBtnFace) MainForm->Color = clWhite; CheckBox->Checked = false; RadioButton1->Hide(); RadioButton2->Hide(); // Lectura // Escritura

// Escritura

// Hide() es el metodo que oculta el // componente sobre el que se aplica.

} //---------------------------------------------------------------

Si generamos el ejecutable y ejcutamos el programa, el resultado es el mostrado en la figura E5.1. Figura E5.1. El programa al iniciar su ejecucin despus de modificar propiedades en tiempo de ejecucin y de llamar al mtodo Hide() asociado a los componentes RadioButton

file:///D|/Manuales/intro/ejemplos/ej5.html (1 of 2) [27/02/2003 16:24:03]

Ejercicio 5. Mtodos asociados a componentes

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/ej5.html (2 of 2) [27/02/2003 16:24:03]

Ejercicio 6. Gestores de eventos

Curso de C++ Builder Ejercicio 6. Gestores de eventos

Construiremos el gestor del evento asociado a modificar el componente CheckBox de forma que cuando se active (inicialmente est desactivado) se muestren los dos botones de radio y se active el botn de OK. Cuando se desactive, los botones de radio se volvern a ocultar y el botn de Ok se desactivar. Para ello, escribiremos el gestor asociado al evento OnClick del componente CheckBox:
//-----------------------------------------------------------void __fastcall TMainForm::CheckBoxClick(TObject *Sender) { if (CheckBox->Checked == true) { RadioButton1->Show(); RadioButton2->Show(); RadioButton1->Checked = true; OKButton->Enabled = true; } else { RadioButton1->Hide(); RadioButton2->Hide(); OKButton->Enabled = false; LabelOutput->Caption = ""; } } //------------------------------------------------------------

Al ejecutar el programa, cuando se activa el CheckBox produce el siguiente resultado: Figura E6.1. El programa al activar el CheckBox

file:///D|/Manuales/intro/ejemplos/ej6.html (1 of 3) [27/02/2003 16:24:03]

Ejercicio 6. Gestores de eventos

Finalmente, escribiremos el gestor del evento asociado a hacer click sobre el botn OK, que est operativo (propiedad Enabled) nicamente cuando el CheckBox est activado, y en consecuencia, cuando pueden emplearse los botones de radio. Observar el siguiente cdigo y dos resultados de la ejecucin (figuras E6.2 y E6.3):
//-----------------------------------------------------------void __fastcall TMainForm::OKButtonClick(TObject *Sender) { if (RadioButton1->Checked) { if (Edit->Text == "") LabelOutput->Caption = "Escogi Opcin 1, Sr/Sra. desconocido/a"; else LabelOutput->Caption = "Escogi Opcin 1, Sr/Sra. " + Edit>Text; } else { if (Edit->Text == "") LabelOutput->Caption = "Escogi Opcin 2, Sr/Sra. desconocido/a"; else LabelOutput->Caption = "Escogi Opcin 2, Sr/Sra. " + Edit>Text; } } //------------------------------------------------------------

Figura E6.2. Resultado al seleccionar la opcin 1 estando el cuadro de edicin vaco.


file:///D|/Manuales/intro/ejemplos/ej6.html (2 of 3) [27/02/2003 16:24:03]

Ejercicio 6. Gestores de eventos

Figura E6.3. Resultado al seleccionar la opcin 2 habiendo escrito algo en el cuadro de edicin.

Atrs Francisco Cortijo Bon


file:///D|/Manuales/intro/ejemplos/ej6.html (3 of 3) [27/02/2003 16:24:03]

C++ Builder

Curso de C++ Builder

Introduccin El IDE Componentes La VCL Programacin orientada a objetos en C++ Tratamiento de excepciones Programacin con hebras Acceso a bases de datos Enlaces interesantes Todo en un ZIP

ndice

Ejercicios

Apndices

file:///D|/Manuales/contents.html (1 of 2) [27/02/2003 16:24:03]

C++ Builder

Francisco Jos Cortijo Bon & Fernando Berzal Galiano


Todos los derechos reservados por los autores sobre el contenido de este documento electrnico. Queda prohibido su uso comercial sin el consentimiento escrito de los autores. Cualquier uso de este material debe ser comunicado a los autores.

file:///D|/Manuales/contents.html (2 of 2) [27/02/2003 16:24:03]

VCL

Curso de C++ Builder La VCL (Biblioteca de Componentes Visuales)

q q q q q

4.1. Un paseo por la VCL. 4.2. Clases de formularios y aplicaciones. 4.3. Clases de componentes. 4.4. Restricciones al uso de la VCL en C++ Builder. 4.5. Ejercicios: Pizarra, Controles de edicin y Editor.

En Windows, no son las aplicaciones quienes manejan los recursos del sistema como pueden ser la memoria, los ficheros, las ventanas y hasta los controles grficos. Es el sistema operativo quin realiza todas estas tareas. Y la aplicacin se limita a realizar peticiones de lo que necesita. Estas peticiones se realizan mediante lo que se denomina la API de Windows, que es un conjunto de funciones que proporciona el sistema operativo para poder habilitar la comunicacin. Pero este conjunto de funciones es muy grande, poco estructurado y difcil de manejar. Por todo esto es que los entornos de programacin visuales, en su afn de aportar simplicidad y estructuracin a la programacin en Windows, han desarrollado diversos Marcos de Trabajo. Un marco de trabajo es una fase intermedia que se coloca por encima de la API para aportar mayor sencillez a las aplicaciones. Normalmente estos marcos de trabajo son orientados a objetos y se implementan como bibliotecas del lenguaje base, por ello tambin se suelen denominar bibliotecas de clases. La VCL es un marco de trabajo visual y orientado a objetos.

Figura 4.1. La VCL como interface.


file:///D|/Manuales/intro/4.html (1 of 7) [27/02/2003 16:24:04]

VCL

Tan importantes son los marcos de trabajo, que dominar un entorno de programacin visual, suele traducirse en conocer el leguaje base del entorno, y su marco de trabajo. Los marcos de trabajo se pueden clasificar en dos categoras: 1. Los marcos de trabajo C++ (OWL y MFC) 2. La VCL. OWL (Object Windows Library o Biblioteca de Objetos para Windows) fue un marco de trabajo desarrollado por Borland e incorporado a los compiladores Borland C++ (versiones 3 y sucesivas) y supuso un importante hito en la programacin para Windows por su potencia y facilidad de uso. Microsoft desarroll su propio marco de trabajo, el MFC (Microsoft Foundation Class o Biblioteca Fundamental de Clases de Microsoft) y lo incorpor a los compiladores Microsoft Visual C++ (actualmente incluso en Borland C++ 5). MFC es una biblioteca de clases menos abstracta que el OWL y ms cercana a la API. Tambin resulta ms sencillo que OWL para los programadores que conocen la API. Aunque MFC se usa ms que OWL (Microsoft...) la arquitectura de OWL es, tcnicamente, mejor que MFC. En 1995, Borland lanz al mercado Delphi, que supuso la revolucin en la programacin para Windows e inici el desarrollo rpido y sencillo de aplicaciones visuales. Delphi ofreca el desarrollo rpido de aplicaciones (RAD) empleando componentes (objetos que pueden ubicarse en formularios y manipulados por medio de propiedades, mtodos y eventos). Esta forma de trabajo se hizo ms popular con Visual Basic. Delphi empleaba como base al lenguaje Object Pascal (una ampliacin
file:///D|/Manuales/intro/4.html (2 of 7) [27/02/2003 16:24:04]

VCL

de Pascal que incorpora programacin orienta a objetos) y permita la creacin de programas ejecutables independientes que no requeran intrprete, por lo que se ejecutaban mucho ms rpido que los de Visual Basic. Lo ms relevante desde el punto de vista tcnico es que Borland cre la VCL (Visual Class Library o Biblioteca de Componentes Visuales) que es un marco de trabajo para crear aplicaciones Windows diseada en torno al concepto de componente (propiedades, mtodos y eventos). La VCL desarrollada para Delphi es la misma que se emplea como ncleo de C++ Builder, de hecho, est escrita en Object Pascal... La VCL hace un uso extensivo del concepto de herencia. El objetivo final de la VCL es crear clases que representan a componentes, aunque algunas clases no hagan referencia componentes concretos: realizan tareas de gestin interna y se emplean como clases bases para derivar mediante herencia otras clases. En la figura 4.2 mostramos una pequea parte de la jerarqua de clases que forman la VCL. En las secciones 4.1, 4.2 y 4.3 describimos con ms detalle las clases ms importantes de la VCL. Figura 4.2. Jerarqua de clases de la VCL.

4.1. Un paseo por la VCL


Conocer en profundidad la VCL se nos antoja imposible, adems de innecesario. Es

file:///D|/Manuales/intro/4.html (3 of 7) [27/02/2003 16:24:04]

VCL

posible construir aplicaciones Windows de gran calidad con C++ Builder sin un conocimiento exhaustivo de la VCL, aunque consideramos conveniente relizar una somera descripcin de la jerarqua de clases que conforman la VCL. Las clases que conforman la parte superior de la jerarqua de la VCL (TObject, TPersistent y TComponent) se denominan clases "abstractas" porque sirven para estructurar, y agrupar comportamientos comunes de las clases de la VCL. No se suelen crear objetos directamente a partir de ellas. Rigurosamente hablando, no son clases abstractas, porque no tienen mtodos virtuales puros (ver seccin 5.5.2), pero las podemos considerar como tales en la prctica. TObject Es el ancestro de todas las clases de la VCL. Encapsula el comportamiento comn de los objetos en C++ Builder, como puede ser informacin de la clase, instanciacin... Suele ser una buena idea derivar nuestras propias clases de TObject, porque aunque no sea normal que el programador haga uso de los mtodos proporcionados por TObject, si lo es que lo haga C++ Builder en tiempo de ejecucin. Directamente de TObject heredan aquellas clases que no son componentes, y no necesitan ser almacenadas en disco. TPersistent Esta clase tiene que ver con la habilidad de un objeto de almacenarse en disco o en memoria, asignarse a otros objetos, as como otros detalles internos de C++ Builder que no es preciso conocer. TComponent sta es una de las clases ms importantes de la VCL, ya que la mayora de los objetos que se manejan en una aplicacin son componentes. Esta clase proporciona toda la funcionalidad que requiere un componente bsico. La funcionalidad de TComponent permite que los objetos aparezcan en la paleta de componentes y que sean manipulados por el diseador de formularios, adems de otras capacidades comunes a los componentes. Los componentes no visuales derivan directamente de TComponent mientras

file:///D|/Manuales/intro/4.html (4 of 7) [27/02/2003 16:24:04]

VCL

que los componentes visuales derivan de TControl, que a su vez deriva de TComponent. Por esta razn se suelen denominar controles a los componentes visuales. TControl Proporciona la funcionalidad de los componentes visuales (controles). Esta funcionalidad es principalmente el aspecto visual que deben ofrecer los componentes en tiempo de ejecucin. TControl proporciona mayor funcionalidad que la que requieren los componentes visuales: los componentes individuales derivan de TGraphicControl o de TWinControl, clases derivadas de TControl. TGraphicControl Generaliza a los controles que tienen una representacin visual, pero no pueden recibir el foco: el usuario podr verlos pero no interactuar con ellos. Suelen ser controles para visualizar texto (no editable en tiempo de ejecucin), grficos o dibujos. Poseen una propiedad Canvas que permite acceder a su rea de dibujo. TWinControl Son los controles tpicos de Windows, que pueden recibir el foco, contener otros controles, y adems poseen un manejador de ventana. Un manejador de ventana es un identificador que proporciona Windows para el control, por lo que podemos decir que Windows tiene un conocimiento directo de la existencia del mismo.

4.2. Clases de Formularios y Aplicaciones


Son controles en si mismas, pero no se presentan en la paleta de componentes. TApplication La clase TApplication encapsula una aplicacin Windows por lo que caracteriza las operaciones fundamentales de un programa en Windows. TApplication simplifica el interface entre el programador y el sistema operativo, ocupndose de tareas como gestionar el paso de mensajes, proporcionar la ayuda contextual, establecer los textos de sugerencia de los botones y barras de estado,
file:///D|/Manuales/intro/4.html (5 of 7) [27/02/2003 16:24:04]

VCL

procesamiento de "teclas rpidas", gestin de excepciones, ejecutar cuadros de mensajes, etc. Todas las aplicaciones de C++ Builder tienen un puntero a un objeto TApplication denominado Application, que se crea automticamente.

Como Application se crea automticamente no aparece en la paleta de componentes ni est disponible en el inspector de objetos para manipular "visualmente" sus propiedades. En cualquier caso, algunas propiedades pueden establecerse en tiempo de diseo seleccionando las pginas Forms o Applicaction despus de seleccionar Project | Options.

Propiedades, mtodos y eventos de aplicaciones.

TForm La clase TForm caracteriza a los formularios en la VCL. Los formularios se emplean como ventanas principales, cuadros de dilogo, ventanas secundarias o cualquier otro tipo de ventana que se pueda imaginar.

Propiedades, mtodos y eventos de formularios.

4.3. Clases de componentes


Este grupo abarca un amplio espectro de clases. Bsicamente, incorpora a todos los componentes que aparecen en la paleta de componentes del IDE de C++ Builder (ver seccin 3.1) lo que implica que se pueden colocar sobre un formulario.

file:///D|/Manuales/intro/4.html (6 of 7) [27/02/2003 16:24:04]

VCL

Lista completa de componentes, agrupados por pginas.

Propiedades, mtodos y eventos de componentes.

4.4. Restricciones al uso de la VCL en C++ Builder


La VCL se desarroll originariamente en y para Delphi, por lo que est construida en Object Pascal. Aunque esto no supone normalmente consideraciones especiales, existen algunos aspectos que deben ser tenidos en cuenta:
q

Los objetos de la VCL deben crearse siempre dinmicamente (con new). Esto es as porque deben de localizarse en el heap, y no en la pila. La VCL no asigna valores por defecto a las funciones. No se puede usar herencia mltiple con clases VCL.

4.5. Ejercicios: Pizarra, Controles de edicin y Editor.


q q q

Pizarra . Controles de edicin . Editor.

Pgina principal Francisco Cortijo Bon

file:///D|/Manuales/intro/4.html (7 of 7) [27/02/2003 16:24:04]

La variable Application

Curso de C++ Builder Sobre la variable Application

Cuando un programa empieza a ejecutarse, C++ Builder instancia la variable Application, llama a sus mtodos Initialize(), CreateForm() y Run(). A modo de ejemplo, si retomamos el ejemplo inicial de este curso (proyecto Inicial), observar el contenido del fichero que C++ Builder crea como fichero principal de la aplicacin, Inicial.cpp. Recordar que el formulario principal se llam, finalmente, MainForm. En Inicial.cpp:
//-------------------------------------------------------------------------#include <vcl.h> #pragma hdrstop USERES("Inicial.res"); USEFORM("main.cpp", MainForm); //-------------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TMainForm), &MainForm); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } //--------------------------------------------------------------------------

Atrs

file:///D|/Manuales/intro/vcl/application.html (1 of 2) [27/02/2003 16:24:04]

La variable Application

Francisco Cortijo Bon

file:///D|/Manuales/intro/vcl/application.html (2 of 2) [27/02/2003 16:24:04]

TApplication - Propiedades, mtodos y eventos

Curso de C++ Builder TApplication - Propiedades, mtodos y eventos

q q q

1. Propiedades de las aplicaciones. 2. Mtodos de las aplicaciones. 3. Eventos de las aplicaciones.

1. Propiedades de las aplicaciones.


Propiedad Active Descripcin Especifica si la aplicacin est activa y tiene el foco. Hint especifica el texto que debe aparecer en el cuadro de ayuda o texto de sugerencia asociado a la aplicacin. Este cuadro aparece cuando ocurre el evento OnHint. Por defecto se muestra nicamente el cuadro asociado al componente sobre el que est el ratn por lo que usualmente se emplea esta propiedad para mostrar la informacin extensa de este componente en una barra de estado, por ejemplo. ShowHint determina si los cuadros de sugerencia estarn activados o desactivados para toda la aplicacin. Pueden emplearse las funciones GetShortHint() y GetLongHint() para obtener las dos partes de la propiedad Hint

Hint y ShowHint

file:///D|/Manuales/appendix/tapplication.html (1 of 4) [27/02/2003 16:24:05]

TApplication - Propiedades, mtodos y eventos

MainForm especifica qu formulario acta como ventana principal de la aplicacin. MainForm y ShowMainForm ShowMainForm especifica si la aplicacin debe mostrar la ventana principal al iniciar su ejecucin. Para ocultarla, establecer esta propiedad a false antes de la llamada a Application->Run y asegurarse de que la propiedad Visible del formulario est tambin a false.

Icon y Title

Especifican el icono y el texto, respectivamente, que aparecen en la barra de tareas de Windows cuando se minimiza la aplicacin. Pueden establecerse en tiempo de diseo seleccionando Project | Options | Application.

HelpFile y Para especificar el fichero de ayuda asociado a la aplicacin. CurrentHelpFile.

2. Mtodos de las aplicaciones.


Mtodo BringToFront() Descripcin Establece la ltima ventana activa como la que se muestra por encima de todas las dems. Crea un nuevo formulario. Generalmente, el programador no usa este mtodo ya que las lneas de cdigo para la creacin de formularios las aade automticamente C++ Builder. Se emplean para gestionar la ayuda asociada a una aplicacin. Generan un evento OnHelp, y si no hay un gestor para este evento, se gestiona a travs de WinHelp. Muestra un mensaje al usuario en cuadro de dilogo que puede incorporar botones. Devuelve un valor que depende del botn seleccionado para cerrar el cuadro de dilogo.

CreateForm() HelpCommand(), HelpContext() y HelpJump() MessageBox()

file:///D|/Manuales/appendix/tapplication.html (2 of 4) [27/02/2003 16:24:05]

TApplication - Propiedades, mtodos y eventos

Minimize() y Restore() Run() y Terminate()

Minimize() minimiza una aplicacin y la aloja en la barra de tareas de Windows, mientras que Restore() reestablece el tamao que tena la aplicacin antes de ser minimizada. Run() ejecuta la aplicacin, mientras Terminate() termina la ejecucin de una aplicacin. Muestra un cuadro de dilogo cuando se produce una excepcin que no es gestionada por la aplicacin. Para especificar qu excepciones pueden gestionarse en la aplicacin, construir un gestor para el evento OnException. Proporciona una manera de gestionar excepciones por defecto en la aplicacin.

ShowException()

HandleException()

3. Eventos de las aplicaciones.

Evento

Descripcin Ocurren cuando se activa o desactiva la aplicacin, respectivamente. Una aplicacin se activa cuando se genera la aplicacin (empieza a ejecutarse) o cuando estaba activa otra aplicacin y una ventana de la aplicacin a la que se refiere recibe el foco. Una aplicacin se desactiva cuando el usuario selecciona otra aplicacin. OnHint ocurre cuando el cursor se coloca sobre un control o una opcin de un men que puede mostrar un cuadro de sugerencia. Se suele escribir un gestor para este evento cuando se quiere mostrar el texto largo de sugerencia en la barra de estado.

OnActivate y OnDeactivate

OnHint y OnShowHint

OnShowHint ocurre cuando la aplicacin va a mostar un cuadro de sugerencia. Se suele usar para modificar la apariencia del cuadro. Pueden emplearse las funciones GetShortHint() y GetLongHint() para obtener las dos partes de la propiedad Hint

file:///D|/Manuales/appendix/tapplication.html (3 of 4) [27/02/2003 16:24:05]

TApplication - Propiedades, mtodos y eventos

OnMinimize y OnRestore OnHelp

Ocurren cuando la aplicacin se minimiza o se reestablece al tamao normal, respectivamente. Ocurre cuando la aplicacin recibe una peticin de ayuda. Los mtodos HelpContext() y HelpJump() gestionan automticamente este evento. Se emplea cuando se desea modificar el comportamiento por defecto de una aplicacin cuando se manifiesta alguna excepcin que no es tratada por el programa. Ocurre cuando se pulsa una tecla.

OnException

OnShortCut

Se emplea este gestor para realizar acciones antes de que el formulario o los controles del formulario gestionen los eventos oportunos a la pulsacin de teclas.

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/tapplication.html (4 of 4) [27/02/2003 16:24:05]

Eventos asociados a las teclas

Curso de C++ Builder Sobre los eventos asociados a la pulsacin de teclas

Cuando se pulsa una tecla se desencadenan los siguientes eventos, por este orden:

1. OnKeyDown, 2. OnKeyPress, y 3. OnKeyUp

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/tip/tip_tecla.html [27/02/2003 16:24:05]

TForm - Propiedades, mtodos y eventos

Curso de C++ Builder TForm - Propiedades, mtodos y eventos

1. Propiedades de los formularios.


r r

1.1. Propiedades en tiempo de diseo y ejecucin. 1.2. Propiedades en tiempo de ejecucin.

2. Mtodos de los formularios. 3. Eventos de los formularios.

1. Propiedades de los formularios.

1.1. Propiedades en tiempo de diseo y ejecucin.

Propiedad ActiveControl Enabled

Descripcin Establece qu componente tiene el foco cuando se abre el formulario. Indica si el formulario est activo (si puede recibir el foco).

file:///D|/Manuales/appendix/tform.html (1 of 6) [27/02/2003 16:24:06]

TForm - Propiedades, mtodos y eventos

AutoScroll, HorzScrollBar Controlan conjuntamente las barras de desplazamiento de un y formulario. VertScrollBar BorderIcons BorderStyle Caption y Name Color Cursor Font Indica qu iconos aparecen en la barra de ttulo de un formulario. Indica qu tipo de borde debe tener el formulario. Caption indica la cadena que aparece en la barra de ttulo del formulario mientras que Name indica con qu nombre se refiere al formulario en la aplicacin (en el cdigo). Color de fondo del formulario. Especifica qu cursor se muestra cuando est sobre el formulario. Permite especificar las propiedades de la fuente de letra que se usar en el formulario. Se aplica a todos los componentes ubicados en el formulario. Establece el icono que se ver en la barra de ttulo cuando se muestre el formulario en tiempo de ejecucin y cuando se minimize. Altura y anchura (en pxeles) del formulario. Altura y anchura (en pxeles) del rea de cliente del formulario (el rea de cliente es la que queda dentro de los bordes del formulario y por debajo de la barra de ttulo y de la barra de men). Al modificar estas propiedades se actualizan Width y Height. Coordenadas X e Y del formulario (su esquina superior izquierda) en la pantalla. Determina el tamao y la posicin del formulario. Para especificar si un formulario es o no parte de una aplicacin multiformulario. Para especificar el fichero de ayuda asociado a la aplicacin y gestionar la ayuda contextual.

Icon Height y Width ClientWidth y ClientHeight

Left y Top Position FormStyle HelpFile y HelpContext

file:///D|/Manuales/appendix/tform.html (2 of 6) [27/02/2003 16:24:06]

TForm - Propiedades, mtodos y eventos

Hint y ShowHint

Hint especifica el texto que debe aparecer en el cuadro de ayuda o texto de sugerencia asociado al formulario. Este cuadro aparece cuando ocurre el evento OnHint. Por defecto se muestra nicamente el cuadro asociado al componente sobre el que est el ratn por lo que usualmente se emplea esta propiedad para mostrar la informacin extensa de este componente en una barra de estado, por ejemplo. ShowHint determina si los cuadros de sugerencia estarn activados o desactivados para el formulario.

Visible

Indica si el formulario es visible o no. Los mtodos Show() y ShowModal() hacen que un formulario sea visible y lo colocan por encima de todos. Para establecer el estado inicial del formulario (normal, minimizado o maximizado) o consultar su estado.

WindowState

1.2. Propiedades en tiempo de ejecucin.

Propiedad Active

Descripcin Indica si el formulario est activo (si tiene el foco). El lienzo es la superficie del formulario sobre la que se puede dibujar. La propiedad Canvas da acceso a esta superficie para dibujar lneas, mapas de bits, texto, ... en el rea de cliente. Suele usarse con el gestor del evento OnPaint. Coordenadas de los cuatro puntos que delimitan el rea de cliente del formulario. El valor devuelto cuando se cierra un formulario modal (abierto con el mtodo ShowModal()). Proporciona informacin acerca del estado en que se encuentra un formulario (si se est creando, si es visible, si es modal, etc.).

Canvas

ClientRect ModalResult FormState

file:///D|/Manuales/appendix/tform.html (3 of 6) [27/02/2003 16:24:06]

TForm - Propiedades, mtodos y eventos

2. Mtodos de los formularios.

Mtodo BringToFront() y SendToBack() Hide() Print() Show() y ShowModal() Close() y CloseQuery()

Descripcin Coloca al formulario en primer plano o en ltimo, respectivamente. Oculta el formulario (establece la propiedad Visible a falso). Imprime el contenido del formulario. Para mostrar formularios. ShowModal() ejecuta (abre) el formulario modalmente: debe cerrarse para que el usuario pueda seguir trabajando con la aplicacin. Close() cierra el formulario tras llamar a CloseQuery() para asegurarse de que es correcto cerrarlo. Esta ltima llama al manipulador del evento OnCloseQuery. Activa el formulario y lo coloca en primer plano, poniendo a verdad la propiedad Active. Adems, el componente especificado en la propiedad ActiveControl recibe el foco. Devuelve verdad si el formulario puede recibir el foco (si las propiedades Visible y Enabled estn a verdad). Establece simultneamente los valores de las propiedades Top, Left, Width y Height.

SetFocus()

CanFocus() SetBounds()

ClientToScreen() Convierte las coordenadas del rea de cliente en coordenadas de y pantalla y viceversa. ScreenToClient() Invalidate(), Refresh(), Repaint() y Update()

Redibujar un formulario.

file:///D|/Manuales/appendix/tform.html (4 of 6) [27/02/2003 16:24:06]

TForm - Propiedades, mtodos y eventos

Release()

Destruye un formulario y libera toda la memoria asociada.

3. Eventos de los formularios.

Una accin puede desencadenar varios eventos y el orden en ocurren puede ser muy importante:

Eventos asociados a la creacin y destruccin de un formulario. Eventos asociados al movimiento y pulsacin con el ratn. Eventos asociados a la pulsacin de alguna tecla.

Evento OnActivate y OnDeactivate

Descripcin Ocurren cuando se activa o desactiva un formulario, respectivamente. Un formulario se activa cuando se recibe el foco y se desactiva cuando el foco pasa a otro formulario de la misma aplicacin. OnCreate ocurre cuando se crea inicialmente el formulario (slo ocurre un evento de este tipo por formulario) y OnDestroy cuando se destruye. El evento OnClose ocurre cuando se cierra un formulario. Hace una llamada a OnCloseQuery para asegurarse de que es correcto cerrarlo.

OnCreate y OnDestroy OnClose y OnCloseQuery

OnMouseDown, OnMouseMove, Para responder a los eventos que suceden al mover el ratn o OnMouseUp, cuando se pincha con l sobre el formulario. OnClick y OnDblClick
file:///D|/Manuales/appendix/tform.html (5 of 6) [27/02/2003 16:24:06]

TForm - Propiedades, mtodos y eventos

OnKeyDown, OnKeyUp y OnKeyPress OnHelp OnHide y OnShow

Para responder a los eventos que suceden al pulsar alguna tecla sobre el formulario. Ocurre cuando se recibe una peticin de ayuda en el formulario. Ocurren cuando se oculta o se muestra el formulario, respectivamente (cuando su propiedad Visible se establece a falso o verdad, respectivamente). OnShow ocurre justo antes de que el formulario se haga visible. Ocurre cuando el formulario necesita ser redibujado (refrescado). Esto ocurre muy frecuentemente, y aunque los componentes del formulario se redibujan por s mismos generalmente, a veces es preciso redibujar "manualmente" el formulario. Ocurre antes de que cualquier control sea redibujado. Ocurre cuando se modifica el tamao del formulario, justo despus de redimensionar el formulario. Ocurre cuando se pulsa una tecla, antes de que ocurra OnKeyDown.

OnPaint

OnResize OnShortCut

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/tform.html (6 of 6) [27/02/2003 16:24:06]

Eventos asociados a la creacin y destruccin de formularios

Curso de C++ Builder Sobre los eventos asociados a la creacin y destruccin de formularios

Cuando se crea un formulario se generan los siguientes eventos, que enumeramos ordenadamente:

1. 2. 3. 4. 5.

El constructor del formulario. OnCreate. OnShow. OnActivate. OnPaint.

De la misma manera, cuando se destruye el formulario se generan los siguientes eventos, que enumeramos ordenadamente:

1. 2. 3. 4.

OnCloseQuery. OnClose. OnDestroy. El destructor del formulario (si existe).

Atrs

file:///D|/Manuales/appendix/tip/tip_form.html (1 of 2) [27/02/2003 16:24:06]

Eventos asociados a la creacin y destruccin de formularios

Francisco Cortijo Bon

file:///D|/Manuales/appendix/tip/tip_form.html (2 of 2) [27/02/2003 16:24:06]

Eventos asociados al ratn

Curso de C++ Builder Sobre los eventos asociados al ratn

Los eventos del ratn presentan ciertas particularidades que se deben conocer. Si se quiere atender a la pulsacin del ratn sobre un formulario o un control, tan slo hay que atender al evento OnClick. Si se tienen que utilizar OnMouseDown y OnMouseUp hay que tener en cuenta que OnClick lleva involucrado los eventos OnMouseDown y OnMouseUp. As, una pulsacin del ratn genera los siguientes eventos, que enumeramos ordenadamente:

1. OnMouseDown. 2. OnClick. 3. OnMouseUp. De la misma manera, cuando el usuario pulsa dos veces sobre un formulario o un control se generan los siguientes eventos, que enumeramos ordenadamente:

1. 2. 3. 4.

OnMouseDown. OnClick. OnDblClick. OnMouseUp.

Atrs

file:///D|/Manuales/appendix/tip/tip_raton.html (1 of 2) [27/02/2003 16:24:06]

Eventos asociados al ratn

Francisco Cortijo Bon

file:///D|/Manuales/appendix/tip/tip_raton.html (2 of 2) [27/02/2003 16:24:06]

TComponent - Propiedades, mtodos y eventos

Curso de C++ Builder TComponent - Propiedades, mtodos y eventos

1. Propiedades de los componentes.


r r

1.1. Propiedades comunes ms importantes. 1.2. Otras propiedades de uso corriente.

2. Mtodos de los componentes. 3. Eventos de los componentes.

1. Propiedades de los componentes.

1.1. Propiedades comunes ms importantes. Aunque cada componente tiene sus propias propiedades, mtodos y eventos, si es verdad que existen algunas propiedades comunes, que comentaremos brevemente.

Propiedad Align

Descripcin Establece distintas posiciones y ajustes del componente relativos al componente que lo contiene.

file:///D|/Manuales/appendix/tcomponent.html (1 of 5) [27/02/2003 16:24:07]

TComponent - Propiedades, mtodos y eventos

Caption indica el texto que acompaa a algunos componentes. Name indica el nombre o identificador que se le asigna al componente en el programa y con el que se referir al componente en la aplicacin (en el cdigo). C++ Builder usar el valor de la propiedad Name para crear el puntero que referenciar al componente y el programador lo usar para referenciarlo.

Caption y Name

Color Cursor Font

Se refiere al color de fondo del componente. Establece qu icono se muestra cuando el usuario mueve el cursor sobre un componente. Permite especificar las propiedades de la fuente de letra que se usar en el componente. Para activar y desactivar componentes: cuando un componente se desactiva no puede recibir el foco, por lo que no responde al ratn, al teclado ni a eventos del temporizador. Hint especifica el texto que debe aparecer en el cuadro de ayuda o texto de sugerencia asociado a un componente. Tiene dos partes, separadas por la barra |. La primera (sugerencia breve) se visualiza cuando el usuario coloca el puntero sobre el componente. La segunda se presenta en la barra de estado. Esta informacin aparece cuando ocurre el evento OnHint. ShowHint determina si la ayuda de sugerencia breve se debe mostrar o no.

Enabled

Hint y ShowHint

Cuando se establecen a verdad, heredan el valor para la ParentColor, propiedad a la que hacen referencia de su componente padre. En ParentFont y otro caso, emplean el valor que tienen establecido para esa ParentShowHint propiedad. Visible Indica si el componente es visible o no.

file:///D|/Manuales/appendix/tcomponent.html (2 of 5) [27/02/2003 16:24:07]

TComponent - Propiedades, mtodos y eventos

1.2. Otras propiedades de uso corriente. Las siguientes propiedades, aunque se usan frecuentemente, no estn disponibles para todos los componentes.

Propiedad BorderStyle Height y Width HelpContext Left y Top TabOrder y TabStop

Descripcin Para diferenciar al componente del formulario o integrarlo en su fondo. Altura y anchura (en pxeles) del componente. Para asociar un nmero de ndice de un fichero de ayuda a un componente. Coordenadas X e Y del componente (su esquina superior izquierda). Para establecer el order de tabulacin y determinar si el componente forma o no parte de la secuencia de tabulacin, respectivamente.

2. Mtodos de los componentes.


No se emplean habitualmente porque las acciones que realizan se efectan modificando las propiedades del componente.

Mtodo

Descripcin

ClientToScreen() Convierte las coordenadas del rea de cliente en coordenadas de y pantalla y viceversa. ScreenToClient()

file:///D|/Manuales/appendix/tcomponent.html (3 of 5) [27/02/2003 16:24:07]

TComponent - Propiedades, mtodos y eventos

Hide() y Show() Invalidate(), Refresh(), Repaint() y Update() SetBounds() SetFocus() CanFocus()

Hide() oculta el componente. Puede volver a hacerse visible posteriormente con Show(). Ambos mtodos modifican la propiedad Visible.

Redibujar un componente.

Establece simultneamente los valores de las propiedades Top, Left, Width y Height. Sita el foco sobre un componente y lo convierte en el componente activo. Devuelve verdad si el componente puede recibir el foco (si las propiedades Visible y Enabled estn a verdad).

3. Eventos de los componentes.

Una accin puede desencadenar varios eventos y el orden en ocurren puede ser muy importante:

Eventos asociados al movimiento y pulsacin con el ratn. Eventos asociados a la pulsacin de alguna tecla.

Evento

Descripcin

file:///D|/Manuales/appendix/tcomponent.html (4 of 5) [27/02/2003 16:24:07]

TComponent - Propiedades, mtodos y eventos

OnMouseDown, OnMouseMove, Para responder a los eventos que suceden al mover el ratn o OnMouseUp, cuando se pincha con l sobre el componente. OnClick y OnDblClick OnEnter ocurre cuando se activa un componente (recibe el foco) siempre que el foco se transfiera desde otro componente del mismo formulario. OnEnter y OnExit OnExit ocurre cuando el componente pierde el foco, siempre que el foco se transfiera a otro componente del mismo formulario.

OnKeyDown, OnKeyUp y OnKeyPress

Para responder a los eventos que suceden al pulsar alguna tecla cuando el foco est en un componente. Este evento ocurre cuando un objeto tiene que ser redibujado. Si el objeto es un PaintBox, este gestor se encargar de dibujar sobre el Canvas y si no se proporciona este gestor, el PaintBox no se ver en tiempo de ejecucin.

OnPaint

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/tcomponent.html (5 of 5) [27/02/2003 16:24:07]

Propiedad Name

Curso de C++ Builder Sobre la propiedad Name

A modo de ejemplo, si retomamos el ejemplo inicial de este curso (proyecto Inicial), observar el contenido del fichero que C++ Builder crea como fichero de declaracin del formulario, main.h. Recordar que el formulario principal se llam, finalmente, MainForm. En main.h:
//-------------------------------------------------------------------------#ifndef mainH #define mainH //-------------------------------------------------------------------------#include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //-------------------------------------------------------------------------class TMainForm : public TForm { __published: // IDE-managed Components TLabel *LabelEdit; TEdit *Edit; TRadioButton *RadioButton1; TRadioButton *RadioButton2; TCheckBox *CheckBox; TButton *ExitButton; TButton *OKButton; TLabel *LabelOutput; void __fastcall ExitButtonClick(TObject *Sender); void __fastcall FormCreate(TObject *Sender); void __fastcall CheckBoxClick(TObject *Sender); void __fastcall OKButtonClick(TObject *Sender); private: // User declarations public: // User declarations __fastcall TMainForm(TComponent* Owner); }; //-------------------------------------------------------------------------extern PACKAGE TMainForm *MainForm; //-----------------------------------------------------------------------file:///D|/Manuales/appendix/tip/tip_name.html (1 of 2) [27/02/2003 16:24:07]

Propiedad Name

--#endif

Observar que, por ejemplo, al primer botn de radio se le asign el valor RadioButton1 a su propiedad Name. En el listado anterior, RadioButton1 es un puntero a un objeto de tipo TRadioButton. En main.cpp nos referimos a este componente usando el valor de la propiedad Name de la siguiente manera:
//-------------------------------------------------------------------------void __fastcall TMainForm::OKButtonClick(TObject *Sender) { if (RadioButton1->Checked) { if (Edit->Text == "") LabelOutput->Caption = "Escogi Opcin 1, Sr/Sra. desconocido/a"; ...... } //--------------------------------------------------------------------------

Accedemos a la propiedad Checked de RadioButton1 mediante el operador -> porque RadioButton1 es un puntero.

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/tip/tip_name.html (2 of 2) [27/02/2003 16:24:07]

Ejemplos - Pizarra

Curso de C++ Builder Pizarra

1. Crear y configurar el proyecto.

Para ms informacin, pinchar el siguiente enlace:

En primer lugar, crear el directorio Pizarra y, si procede, una nueva aplicacin ( File | New Applicaction). 1. Cambiar el nombre y ttulo del formulario principal: Con el inspector de objetos, cambiar la propiedad Caption por PIZARRA y la propiedad Name por MainForm. 2. Guardar (File | Save As) la unidad asociada al formulario (Unit1.cpp, por defecto) como FuncsPizarra.cpp. Observar que Unit1.h ha cambiado automticamente a FuncsPizarra.h 3. Guardar (File | Save Project As) el proyecto (Project1.bpr, por defecto) como Pizarra.bpr. 4. Dar un nombre a la aplicacin y fijar un icono (Project | Options | Application). Dar como ttulo: PIZARRA y seleccionar un icono. Ahora podemos construir el ejecutable y probarlo: seleccionar Project | Build Pizarra y a continuacin, Run | Run.

2. Configurar el formulario principal.

file:///D|/Manuales/intro/ejemplos/pizarra/index.html (1 of 4) [27/02/2003 16:24:07]

Ejemplos - Pizarra

El formulario principal deber tener el siguiente aspecto:

Fijar manualmente el tamao a 300 X 400 (Height = 300 y Width = 400). Contiene 3 componentes: 1. En la parte superior, alineado en lo alto, un componente PaintBox (solapa System). Fijar las propiedades Name = PaintBox, Align = alTop y Height = 225. 2. Debajo del PaintBox un componente Bevel (solapa Additional). Fijar las siguientes propiedades: Name = Linea, Align = alTop, Style = bsLowered y Height = 8. 3. Debajo del Bevel, centrado horizontalmente un componente BitBtn (solapa Additional). Fijar las siguientes propiedades: Name = ExitBtn, Kind = bkClose y Caption = &Salir.

3. Escribir el cdigo.

file:///D|/Manuales/intro/ejemplos/pizarra/index.html (2 of 4) [27/02/2003 16:24:07]

Ejemplos - Pizarra

En primer lugar, escribiremos el cdigo asociado al evento OnPaint del componente PaintBox. Seleccionar en el inspector de objetos dicho componente, y tras seleccionar la pestaa Events haremos doble click en el gestor del evento OnPaint. El gestor de este evento quedar como sigue:
//-----------------------------------------------------------

void __fastcall TMainForm::PaintBoxPaint(TObject *Sender) { // Dibujar un circulo PaintBox->Canvas->Pen->Color = clBlack; PaintBox->Canvas->Brush->Color = clYellow; PaintBox->Canvas->Ellipse (100, 100, 150, 150); // Dibujar un cuadrado PaintBox->Canvas->Pen->Color = clRed; PaintBox->Canvas->Brush->Color = clRed; PaintBox->Canvas->Rectangle (200, 100, 250, 150); } //-----------------------------------------------------------

Finalmente, escribiremos el cdigo asociado al evento OnClick del componente BitBtn (ExitBtn). Seleccionar en el inspector de objetos dicho componente, y tras seleccionar la pestaa Events haremos doble click en el gestor del evento OnClick. El gestor de este evento quedar como sigue:
//-----------------------------------------------------------

void __fastcall TMainForm::ExitBtnClick(TObject *Sender) { Application->Terminate(); } //-----------------------------------------------------------

4. Generar el ejecutable.
file:///D|/Manuales/intro/ejemplos/pizarra/index.html (3 of 4) [27/02/2003 16:24:07]

Ejemplos - Pizarra

Ahora podemos construir el ejecutable y probarlo: seleccionar Project | Build Pizarra y a continuacin, Run | Run. El resultado de la ejecucin ser el siguiente:

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/pizarra/index.html (4 of 4) [27/02/2003 16:24:07]

Estructura y configuracin de un proyecto de C++ Builder

Curso de C++ Builder Estructura y configuracin de un proyecto

Estructura habitual de un proyecto escrito en C++


Una aplicacin escrita en C++ se compone de un mdulo (fichero) que contiene la funcin main() y, opcionalmente, de una serie de mdulos adicionales que pueden contener declaraciones de clases, declaraciones de funciones (prototipos), definiciones de clases, etc. Para la creacin de un ejecutable se requiere: 1. Un fichero makefile en el que se especifica la dependencia entre los diferentes mdulos y la manera en la que se generan los mdulos objeto, bibliotecas y el ejecutable final. 2. Ejecutar el programa make para que interprete el fichero makefile y desencadene las rdenes oportunas para la creacin del ejecutable, de acuerdo a lo especificado en el fichero makefile.

Ficheros de proyecto en C++ Builder


En C++ Builder la gestin de proyectos software se realiza automticamente y el usuario no necesita construir el fichero makefile ni ejecutar make para obtener el ejecutable: C++ Builder se encarga de todo sto. Para este trabajo estructura los ficheros asociados a una aplicacin en un proyecto. Se puede decir que un fichero de proyecto es un fichero makefile. La extensin de estos ficheros es .bpr (Borland Project).

file:///D|/Manuales/appendix/project/index.html (1 of 4) [27/02/2003 16:24:08]

Estructura y configuracin de un proyecto de C++ Builder

Ejemplo. A modo de ejemplo, emplearemos el proyecto Inicial, que se desarrolla en los seis ejercicios introductorios. Consiste en desarrollar una sencilla aplicacin que consta de una nica ventana. El proyecto se llamar Inicial.bpr En todo proyecto existe un fichero que contiene la funcin principal. En aplicaciones que hacen uso de la VCL la funcin main() se llama WinMain() y se aloja en un fichero cuyo nombre coincide con el del proyecto.
q q

Habitualmente no es preciso trabajar sobre este fichero. Si fuera preciso, para mostrar en el editor de cdigo el fichero que contiene a la funcin WinMain(), seleccionar Project | View Source). Ejemplo. La funcin WinMain() se alojar en el fichero Inicial.cpp

Adems, cualquier aplicacin contendr al menos una ventana. Para cada ventana existirn dos mdulos adicionales: 1. Un mdulo con extensin .cpp con el cdigo asociado a esa ventana (usualmente contiene los gestores de los eventos que se pueden gestionar en esa ventana). 2. Un mdulo cabecera con extensin .h que contiene la declaracin de los componentes que se incluyen en la ventana. Ejemplo. En este ejemplo, los ficheros asociados a la ventana principal (y nica) se llamarn main.cpp y main.h.

Cmo configurar un proyecto en C++ Builder


El primer consejo es que cada aplicacin debera estar en un directorio propio donde se guardarn todos los ficheros asociados a la aplicacin.

file:///D|/Manuales/appendix/project/index.html (2 of 4) [27/02/2003 16:24:08]

Estructura y configuracin de un proyecto de C++ Builder

Ejemplo. Crear un directorio (p.e. Ejercicio) para guardar los ficheros asociados al proyecto.

Ahora se procede a configurar la aplicacin. Consiste, bsicamente en proporcionar nombres significativos al proyecto y a los ficheros asociados al proyecto. A) Si se acaba de arrancar C++ Builder aparece, por defecto aparece un formulario vaco llamado Form1 asociado al proyecto Project1.bpr. B) Si existe un proyecto vigente, lo ms cmodo es crear una nueva aplicacin (File | New Application) salvando, si se desea el proyecto vigente. En cualquier caso se crean, por defecto: 1. Project1.bpr, fichero de proyecto. 2. Project1.cpp, fichero que contiene la funcin WinMain(), 3. Unit1.cpp, fichero que contiene las funciones asociadas al formulario principal (constructor de la ventana y que posteriormente contendr, adems, los gestores de los eventos que puede gestionar), y 4. Unit1.h (especificacion de los componentes del formulario principal). Puede comprobarse usando el gestor de proyectos (View | Project Manager). Los pasos a seguir son los siguientes: 1. Cambiar el nombre y ttulo del formulario principal utilizando el inspector de objetos. Ejemplo. Cambiar la propiedad Caption por Form de Prueba y la propiedad Name por MainForm.

2. Guardar ficheros asociados a ventanas (File | Save As) en el directorio adecuado para dar nombres significativos a los ficheros.

file:///D|/Manuales/appendix/project/index.html (3 of 4) [27/02/2003 16:24:08]

Estructura y configuracin de un proyecto de C++ Builder

Ejemplo. Guardar Unit1.cpp como main.cpp. (Unit1.h cambia automticamente a main.h).

3. Guardar el proyecto: (File | Save Project As) en el directorio adecuado. Ejemplo. Guardar Project1.bpr como Inicial.bpr. (Observar que Project1.cpp ha cambiado automticamente a Inicial.cpp, y que ste contiene a la funcin WinMain). Comprobar que Inicial.bpr tiene la estructura de un fichero makefile. Observar que el proyecto vigente se llama ahora Inicial. Podemos comprobarlo desplegando el men Project. 4. Dar un nombre a la aplicacin y fijar un icono. Estos datos aparecern al minimizar el programa durante su ejecucin. Selecionar Project | Options | Application. Ejemplo. Dar como ttulo: Ejemplo inicial y seleccionar cualquier icono.

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/project/index.html (4 of 4) [27/02/2003 16:24:08]

C++ Builder - Ejercicios

Curso de C++ Builder ndice de ejercicios


Ejercicios introductorios Diseo de un formulario. Uso del inspector de objetos para modificar propiedades. Uso del inspector de objetos para escribir gestores de eventos con el editor de cdigo. Modificacin y consulta de propiedades en tiempo de ejecucin. Mtodos asociados a componentes. Gestores de eventos. Ejercicios adicionales Ejemplos de aplicaciones simples y de consola. Pizarra Controles de edicin Editor Programacin dirigida a objetos en C++Builder Ejemplo 0 Ejemplo 1 Ejemplo 2 Seccin 2.2 2.2 2.2 3.2 3.2 3.2 Seccin 2.6 4.5 4.5 4.5 Seccin 5.5.2 5.6.2 5.7.2

file:///D|/Manuales/exercises.html (1 of 2) [27/02/2003 16:24:08]

C++ Builder - Ejercicios

Ejemplo 3 Reproductor de sonidos Programacin concurrente Ejemplos de programacin con hebras q Creacin de una hebra q Ejecucin de una hebra q Control de la ejecucin de una hebra q Coordinacin entre hebras: Synchronize q Coordinacin entre hebras: Bloqueo de objetos q Coordinacin entre hebras: Secciones crticas q Sincronizacin entre hebras: TEvent Acceso a bases de datos Un componente 'data-aware' TDBDateTimePicker Un formulario Un dilogo de bsqueda genrico Una aplicacin sencilla (Paradox) Gestin de una pequea base de datos culinaria Una aplicacin algo ms compleja (InterBase) Diccionario de citas Ejercicio Desarrollo completo de una aplicacin

6.3 6.5 Seccin

Seccin

Atrs

file:///D|/Manuales/exercises.html (2 of 2) [27/02/2003 16:24:08]

Ejercicio 1. Diseo de un formulario

Curso de C++ Builder Ejercicio 1. Diseo de un formulario

1. Colocar componentes en un formulario y redimensionarlo para que quede (aproximadamente) como se indica en la figura E1.1 Figura E1.1. Disear este formulario.

Todos los componentes necesarios para realizar este ejemplo se encuentran en la pgina de componentes Standard. 2. Crear y configurar el proyecto: Para ms informacin, pinchar el siguiente enlace:

1. Directorio: Ejercicio,
file:///D|/Manuales/intro/ejemplos/ej1.html (1 of 2) [27/02/2003 16:24:09]

Ejercicio 1. Diseo de un formulario

2. Unidad asociada al formulario (Unit1.cpp, por defecto): main.cpp, 3. Proyecto (Project1.bpr, por defecto): Inicial.bpr. 3. Generar el ejecutable: Seleccionar Project | Build. 4. Ejecutar el "programa": Seleccionar Run | Run.

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/ej1.html (2 of 2) [27/02/2003 16:24:09]

Ejercicio 2. Uso del inspector de objetos para modificar propiedades

Curso de C++ Builder Ejercicio 2. Uso del inspector de objetos para modificar propiedades

Cambiar el formulario diseado en el ejercicio 1 para que tenga el aspecto que se indica en la figura E2.1. Figura E2.1. El formulario de la figura 6 modificado.

Las modificaciones se realizarn usando el Inspector de Objetos (pestaa Properties). En la lista siguiente se detallan las modificaciones a realizar. Observar que, bsicamente, se trata de modificar los valores de las propiedades Caption y Name:
q

Caption: Se refiere al ttulo o leyenda que acompaa a los componentes (por ejemplo, al texto que aparece sobre un botn). Name: Se refiere al nombre con el que se va a referenciar al componente desde el programa. Al ser un identificador (como un nombre de variable, por

file:///D|/Manuales/intro/ejemplos/ej2.html (1 of 3) [27/02/2003 16:24:09]

Ejercicio 2. Uso del inspector de objetos para modificar propiedades

ejemplo) debe ser significativo. Por defecto, C++ Builder asigna nombres como Button1 y Button2 y es conveniente asignarles otros ms clarificadores como OKButton o ExitButton, por ejemplo. Cuando se coloca un componente en un formulario, C++ Builder crea un puntero al componente en la declaracin del formulario (fichero main.h en este ejemplo) y gracias a ello se puede acceder al componente a travs del cdigo. C++ Builder emplea la propiedad Name del componente para denominar al puntero. As, las modificaciones a realizar son las siguientes:
q q q q q q q q q

Form1 : Caption = Form de Prueba y Name = MainForm. Label1 : Caption = Nombre y Name = LabelEdit. Edit1 : Dejar vaco el valor de Text y Name = Edit. RadioButton1 : Caption = Opcin 1 y Name = RadioButton1. RadioButton2 : Caption = Opcin 2 y Name = RadioButton2. CheckBox1 : Caption = Activar opciones, Name = CheckBox y Checked = true. Button1 : Caption = OK, Name = OKButton y Enabled = false. Button2 : Caption = Salir y Name = ExitButton. Label2 : Dejar vaco el valor de Caption y Name = LabelOutput. Activar el cuadro de dilogo asociado a la propiedad Font y establecer los siguientes valores: Font = MS Serif, Font Style = Bold, Size = 10 y Color = Marine.

Generar el ejecutable y ejecutar el "programa". El resultado se muestra en la figura E2.2. Figura E2.2. Resultado de la ejecucin tras modificar propiedades en tiempo de diseo.

file:///D|/Manuales/intro/ejemplos/ej2.html (2 of 3) [27/02/2003 16:24:09]

Ejercicio 2. Uso del inspector de objetos para modificar propiedades

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/ej2.html (3 of 3) [27/02/2003 16:24:09]

Ejercicio 3. Uso del inspector de objetos para escribir gestores de eventos con el editor de cdigo

Curso de C++ Builder Ejercicio 3. Uso del inspector de objetos para escribir gestores de eventos con el editor de cdigo

Vamos a construir el gestor del evento que se genera al hacer click sobre el botn de salir. Se trata de que al pinchar sobre este botn la aplicacin termine su ejecucin. Seleccionar el componente ExitButton y en la pestaa Events del inspector de objetos, hacer doble click en OnClick. El editor de cdigo muestra el siguiente cdigo, generado automticamente:
//-----------------------------------------------------------void __fastcall TMainForm::ExitButtonClick(TObject *Sender) { } //------------------------------------------------------------

Escribir el siguiente cdigo:


//-----------------------------------------------------------void __fastcall TMainForm::ExitButtonClick(TObject *Sender) { Application->Terminate(); } //------------------------------------------------------------

Ahora, generar el ejecutable y ejecutar el programa: al hacer click sobre el botn de salir, el programa deja de ejecutarse.
file:///D|/Manuales/intro/ejemplos/ej3.html (1 of 2) [27/02/2003 16:24:09]

Ejercicio 3. Uso del inspector de objetos para escribir gestores de eventos con el editor de cdigo

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/ej3.html (2 of 2) [27/02/2003 16:24:09]

Ejemplos - Aplicaciones simples

Curso de C++ Builder Ejemplos de aplicaciones simples

1. Aplicaciones de consola.

Una aplicacin de consola no utiliza los objetos de la VCL, y el aspecto de una aplicacin de este tipo es el generado por los compiladores "tradicionales", ejecutndose sobre una consola MS-DOS. En cualquier caso, C++ Builder permite la creacin de este tipo de aplicaciones. Veamos cmo. Una aplicacin de consola se crea usando el asistente Console Wizard. Seleccionar File | New | Console Wizard y en el asistente, indicar que se va a crear una aplicacin de consola (Console). El editor de cdigo aparece de la siguiente manera:

Observar que el editor de cdigo no presenta las lneas necesarias para la inclusin de las
file:///D|/Manuales/intro/ejemplos/simples/index.html (1 of 6) [27/02/2003 16:24:10]

Ejemplos - Aplicaciones simples

definiciones de objetos de la VCL y la funcin principal es la conocida main(), al contrario que ocurre en las aplicaciones "visuales", donde sta se llama WinMain(). Escribir el siguiente cdigo:
#pragma hdrstop #include <condefs.h> #include <iostream.h> #include <conio.h> //-----------------------------------------------------------

#pragma argsused int main(int argc, char* argv[]) { for (int i=0; i<5; i++) cout << "Valor de i = " << i << endl; getch(); return 0; } //-----------------------------------------------------------

Finalmente, guardar el proyecto y ejecutar el programa. Seleccionar File | Save Project As y guardar Project1.bpr como Console.bpr. Ahora podemos construir el ejecutable y probarlo: seleccionar Project | Build Console y a continuacin, Run | Run. El resultado de la ejecucin ser el siguiente:

file:///D|/Manuales/intro/ejemplos/simples/index.html (2 of 6) [27/02/2003 16:24:10]

Ejemplos - Aplicaciones simples

2. Aplicaciones visuales sencillas.

Pueden construirse aplicaciones visuales (hacen uso de la VCL) sin necesidad de usar el diseador de formularios.

1. Ejemplo 1: Saludo. En este ejemplo escribiremos un programa que lanza una ventana de mensaje con un saludo. El primer paso es crear una aplicacin de la manera usual: Seleccionar File | New Application. Como la aplicacin no tendr un formulario y por defecto se asocia uno a la aplicacin debemos borrarlo. Activar el formulario y a continuacin seleccionar Project | Remove from project. Unit1.cpp tiene asociado el formulario principal Form1. Confirmar el borrado y de esta forma se eliminan tanto Unit1.cpp como Unit1.h del proyecto vigente. Para escribir el cdigo del programa, seleccionar Project | View Source y escribir el siguiente cdigo:
//-----------------------------------------------------------

#include <vcl.h>

//-----------------------------------------------------------

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { ShowMessage ("Hola"); return 0; } //-----------------------------------------------------------

Finalmente, guardar el proyecto y ejecutar el programa. Seleccionar File | Save Project As y guardar Project1.bpr como Saludo.bpr. Ahora podemos construir el ejecutable y probarlo: seleccionar Project | Build Saludo y a continuacin, Run | Run. El resultado de la ejecucin ser el siguiente:

file:///D|/Manuales/intro/ejemplos/simples/index.html (3 of 6) [27/02/2003 16:24:10]

Ejemplos - Aplicaciones simples

2. Ejemplo 2: Ciclo (mltiples ventanas secuenciales). Este programa presenta los valores guardados en un vector en una ventana de mensajes (recordar el ejemplo anterior), presentando cada valor individualmente. Como antes, en primer lugar se crea una aplicacin: Seleccionar File | New Application. Activar el formulario para eliminarlo del proyecto: seleccionar Project | Remove from project. Finalmente, para escribir el cdigo del programa, seleccionar Project | View Source y escribir el siguiente cdigo:
//-----------------------------------------------------------

#include <vcl.h>

//-----------------------------------------------------------

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { for (int i=0 ;i<5 ;i++){ ShowMessage ("Valor de i = " + AnsiString(i)); } return 0; } //-----------------------------------------------------------

Guardar el proyecto (File | Save Project As) llamndolo Ciclo.bpr, construir el ejecutable (Project | Build Ciclo) y ejecutarlo Run | Run). El resultado de la ejecucin, en cada iteracin, ser el siguiente. Para pasar a la siguiente iteracin hay que pulsar el botn OK, de forma que en cada iteracin aparece una sla ventana. Primera iteracin Segunda iteracin . . . . . . Quinta iteracin

file:///D|/Manuales/intro/ejemplos/simples/index.html (4 of 6) [27/02/2003 16:24:10]

Ejemplos - Aplicaciones simples

......

3. Ejemplo 3: Resultado compuesto en una nica ventana. En este ejemplo se crea un vector dinmico de 5 enteros y se muestra su contenido en una nica ventana. Se procede como en los dos casos anteriores, y llamaremos al proyecto Vector.bpr. El cdigo que escribiremos es el siguiente:
//-----------------------------------------------------------

#include <vcl.h>

//-----------------------------------------------------------

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { int *vector; AnsiString cadena = ""; vector = new int[5]; for (int i=0; i<5; i++) { vector[i] = i*2; cadena = cadena + "vector[" + AnsiString (i) + "] = " + AnsiString (vector[i]) + "\n"; } ShowMessage (cadena); delete []vector; return 0; }
file:///D|/Manuales/intro/ejemplos/simples/index.html (5 of 6) [27/02/2003 16:24:10]

Ejemplos - Aplicaciones simples

//-----------------------------------------------------------

La ejecucin de este programa produce el siguiente resultado:

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/simples/index.html (6 of 6) [27/02/2003 16:24:10]

Ejemplos - Una aplicacin con componentes de edicin

Curso de C++ Builder Construccin de una aplicacin con componentes de edicin

1. Crear y configurar el proyecto.

Para ms informacin, pinchar el siguiente enlace:

En primer lugar, crear el directorio Edicion y, si procede, una nueva aplicacin ( File | New Applicaction). 1. Cambiar el nombre y ttulo del formulario principal: Con el inspector de objetos, cambiar la propiedad Caption por Controles de edicin y la propiedad Name por MainForm. 2. Guardar (File | Save As) la unidad asociada al formulario (Unit1.cpp, por defecto) como FuncsEdicion.cpp. Observar que Unit1.h ha cambiado automticamente a FuncsEdicion.h 3. Guardar (File | Save Project As) el proyecto (Project1.bpr, por defecto) como Edicion.bpr. 4. Dar un nombre a la aplicacin y fijar un icono (Project | Options | Application). Dar como ttulo: Controles de Edicin y seleccionar un icono. Ahora podemos construir el ejecutable y probarlo: seleccionar Project | Build Edicion y a continuacin, Run | Run.

2. Configurar el formulario principal.

El formulario principal debe tener el siguiente aspecto:

file:///D|/Manuales/intro/ejemplos/controles/index.html (1 of 5) [27/02/2003 16:24:10]

Ejemplos - Una aplicacin con componentes de edicin

Contiene 8 componentes: tres Label (solapa Standard), tres Edit (solapa Standard), y dos botones BitBtn (solapa Additional). Utilizando el inspector de objetos, cambiar las propiedades de estas componentes prestando especial cuidado al nombre (Name) de forma que los nombres queden como se indica en la figura:

3. Configurar el formulario secundario. Aadir un nuevo formulario al proyecto: seleccionar File | New Form y fijar Name =SaludoBox y Caption= Cuadro de salutacin. Este formulario tiene un nico componente Label llamada Label. El aspecto del formulario ser el siguiente:

file:///D|/Manuales/intro/ejemplos/controles/index.html (2 of 5) [27/02/2003 16:24:10]

Ejemplos - Una aplicacin con componentes de edicin

Guardar el formulario (con los ficheros asociados). Seleccionar File | Save ally guardar Unit1.cppcomo Saludo.cpp(observar que Unit1.hcambia a Saludo.h).

4. Escribir el cdigo. En este caso, slo se escribir cdigo para el evento OnClick del componente BotonOK del formulario principal. Seleccionar en el inspector de objetos dicho componente, la pestaa Events y hacer doble click el gestor del evento OnClick. El gestor de este evento quedar como sigue:
//-----------------------------------------------------------

void __fastcall TMainForm::BotonOKClick(TObject *Sender) { if (EditNombre->Text == "" || EditApellido1->Text == "" || EditApellido2->Text == "" ) { Application->MessageBox ( "Debe especificar todos los campos", "Error en la entrada de datos", MB_OK); } else { SaludoBox->Label->Caption = "Bienvenido, " + EditNombre->Text + " " + EditApellido1->Text + " " + EditApellido2->Text; SaludoBox->Show(); EditNombre->Text = ""; EditApellido1->Text = ""; EditApellido2->Text = ""; EditNombre->SetFocus(); } } //-----------------------------------------------------------

5. Generar el ejecutable. Ahora podemos construir el ejecutable y probarlo: seleccionar Project | Build Edicion y a continuacin, Run | Run. Observar que se produce un error de compilacin - muy habitual, todo hay que decirlo - ya que
file:///D|/Manuales/intro/ejemplos/controles/index.html (3 of 5) [27/02/2003 16:24:10]

Ejemplos - Una aplicacin con componentes de edicin

no se puede encontrar la definicin de SaludoBox, objeto que es usado en FuncsEdicion.cpp. De hecho, si miramos FuncsEdicion.cpp observaremos que este fichero no incluye a Saludo.h. Estando activo en el editor de cdigo FuncsEdicion.cpp, seleccionar File | Include Unit Hdr y seleccionar Saludo. Observar que se aade la lnea #include "Saludo.h". Volver a generar el ejecutable y ejecutar el programa. Como ejemplo de ejecucin, si el usuario introduce los siguientes datos en las lneas de edicin:

Al pulsar el botn de confirmacin, se produce el siguiente resultado:

6. Ejercicios adicionales.

1. Resulta poco profesional que la nica posibilidad de cerrar un formulario sea pinchar sobre el botn del aspa situado en el marco de una ventana. Aadir al formulario secundario un botn para cerrarlo. 2. Modificar el cdigo asociado al mtodo BotonOKClick de manera que la ventana de saludo se ejecute modalmente.

file:///D|/Manuales/intro/ejemplos/controles/index.html (4 of 5) [27/02/2003 16:24:10]

Ejemplos - Una aplicacin con componentes de edicin

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/controles/index.html (5 of 5) [27/02/2003 16:24:10]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto

En este ejemplo se explica cmo crear rpidamente una aplicacin para Windows con C++ Builder. La aplicacin que se va a presentar consiste en un editor de texto con bastante funcionalidad, aunque muy mejorable. No debe entenderse que la aplicacin presentada est cerrada, ms bien al contrario, y el alumno puede aadirle ms funcionalidad, lo que le permitir ampliar sus conocimientos sobre programacin de aplicaciones visuales con C++ Builder. Este ejercicio se estructura como sigue: 1. Crear y Configurar el proyecto. Mostramos cmo crear un proyecto (conjunto de ficheros de programa y formularios asociados a una aplicacin) y cmo configurarlo. Bsicamente, a asociar nombres representativos a los ficheros descartando los que C++ Builder asocia por defecto. 2. Configurar el formulario principal. Mostramos con profundidad cmo configurar un formulario, desde aadir una barra rpida hasta cuadros de dilogo. En esta seccin se presentan los componentes habituales de una aplicacin Windows. 3. Aadir mens al formulario. Mostramos diversas tcnicas para aadir mens y submens y cmo incorporar un men cotextual. 4. Escribir el cdigo del programa. Una vez diseado el formulario hay que escribir el cdigo C++ de los manipuladores de eventos asociados a los componentes 5. Aadir un nuevo formulario (Acerca de ...)

file:///D|/Manuales/intro/ejemplos/editor/index.html (1 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Aqu mostramos cmo se pueden aadir nuevos formularios. 6. Sobre la barra de estado y los cuadros de pista (Hints). Mostramos cmo aadir cuadros de pista a los botones rpidos y cmo mostrar informacin en la barra de estado.

Como referencia, esta es la estructura del proyecto que vamos vamos a crear, tal como debe verse en el gestor de proyectos.

1. Crear y configurar el proyecto. Para ms informacin, pinchar el siguiente enlace:

En primer lugar, crear el directorio EjemploEditor y, si procede, una nueva aplicacin ( File | New Applicaction). 1. Cambiar el nombre y ttulo del formulario principal:
file:///D|/Manuales/intro/ejemplos/editor/index.html (2 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Con el inspector de objetos, cambiar la propiedad Captionpor Mi editor de textoy la propiedad Namepor MainForm. 2. Guardar (File | Save As) la unidad asociada al formulario (Unit1.cpp, por defecto) como FuncsEditor.cpp. Observar que Unit1.h ha cambiado automticamente a FuncsEditor.h 3. Guardar (File | Save Project As) el proyecto (Project1.bpr, por defecto) como MiEditor.bpr. 4. Dar un nombre a la aplicacin y fijar un icono (Project | Options | Application). Dar como ttulo: Mi editor de texto 1.0 y seleccionar un icono. Ahora podemos construir el ejecutable y probarlo: seleccionar Project | Build MiEditor y a continuacin, Run | Run.

2. Configurar el formulario principal.

2.1. Agregar un componente Memo. Seleccionar, en la solapa Standard de la paleta de componentes, el componente Memo. Colocarlo sobre el formulario (no nos preocupamos de su tamao ni de su alineacin respecto al formulario). Cambiar la propiedad Name por Memo, seleccionar la propiedad Lines y dejar limpio su contenido con el editor de cadenas. Guardar los ficheros: File | Save All

2.2. Agregar una barra rpida.


r

Crear un componente Bevel. Seleccionar un componente Bevel (solapa Additional), fijar Name= Bevel, Height = 2 y alinearlo en lo alto (Align =alTop).

Crear un panel para albergar los botones de la barra rpida. Seleccionar un componente Panel (solapa Standard) y colocarlo en algn

file:///D|/Manuales/intro/ejemplos/editor/index.html (3 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

lugar del formulario. Fijar:


s s s s s

Name = SpeedBar Height = 32 BevelOuter = bvNone Caption = (Dejar en blanco) Align = alTop

Colocar los botones de acceso rpido de la barra rpida. Se colocarn los botones para abrir fichero, salvar fichero y salir del programa. Para el botn Abrir Fichero: Seleccionar un componente SpeedButton (solapa Additional) y colocarlo en el panel. Cambiar las propiedades:
s s s

Name = FileOpenBtn Left = 4 Glyph: Pinchar dos veces en la propiedad Glyph y seleccionar el icono fileopen.bmp.

Repetir estos pasos para los botones Salvar Fichero (Name =FileSaveBtn, Glyph: filesave.bmp) y Salir (Name = ExitBtn, Glyph: dooropen.bmp).

file:///D|/Manuales/intro/ejemplos/editor/index.html (4 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

2.3. Agregar una barra de estado.

Seleccionar un componente StatusBar (solapa Win32). Fijar Name = StatusBar.

2.4. Reajustar el componente Memo.

Seleccionar el componente Memo y fijar la propiedad Align= alClient. Aadir una barra de scroll vertical: cambiar la propiedad ScrollBars a ssVertical.

2.5. Aadir las componentes no visuales OpenDialog y SaveDialog

Colocar en cualquier sitio del formulario los componentes OpenDialog y SaveDialog (solapa Dialogs). Estos son componentes no visuales, por lo que el lugar
file:///D|/Manuales/intro/ejemplos/editor/index.html (5 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

de ubicacin no es importante. Cambiar las propiedades Name a OpenDialog y SaveDialog, respectivamente. El aspecto del formulario ser el de la figura siguiente. Los componentes no visuales OpenDialog y SaveDialog no se ven en tiempo de ejecucin.

Guardar todos los ficheros del proyecto (File | Save All), construir el proyecto (Project | Build MiEditor) y ejecutarlo (Run | Run).

3. Aadir mens al formulario.

En primer lugar, aadiremos un men principal (seccin 3.1) junto con los submens asociados: Ficheros (seccin 3.2), Edicin (seccin 3.3 y Ayuda (seccin 3.4). El men y los submens son los tpicos de las aplicaciones Windows. Finalmente, crearemos un men contextual (seccin 3.5). Para crear el men principal y los submens, seleccionar el componente no visual
file:///D|/Manuales/intro/ejemplos/editor/index.html (6 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

MainMenu (solapa Standard) y colocarlo en algn lugar del formulario. Fijar Name=MainMenu. A continuacin, disear el men. Se har con el diseador de mens: pinchar dos veces sobre el componente MainMenu.

3.1. Diseo del men principal.

Las cabeceras de los submens sern: Ficheros, Edicion y Ayuda. Deseamos que se abra un submen asociado a cada una de estas categoras cuando se pinche con el ratn sobre stas.
r r r

Para el submen Ficheros: Name=FileMenu y Caption=&Ficheros Para el submen Edicion: Name=EditMenu y Caption=&Edicion Para el submen Ayuda: Name=HelpMenu y Caption=&Ayuda

3.2. Men Ficheros.

file:///D|/Manuales/intro/ejemplos/editor/index.html (7 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Aadir las opciones: Nuevo, Abrir, Guardar, Guardar como, (separador), Imprimir, Configurar impresora, (separador) y Salir. Para cada opcin se procede como antes:
r r r r r r r

r r

Nuevo: Name=FileNew y Caption=&Nuevo Abrir: Name=FileOpen y Caption= &Abrir, Guardar: Name=FileSave y Caption= &Guardar, Guardar como: Name=FileSaveAs y Caption= Guardar &como, Incluir un separador: Caption = Imprimir: Name=FilePrint, Caption=&Imprimir y Enabled=false, Conf. impresora: Name=FilePrintSetUp, Caption=Config&urar impresora y Enabled= false Incluir un separador: Caption = Salir: Name=FileExit y Caption=&Salir

3.3. Men Edicin.

file:///D|/Manuales/intro/ejemplos/editor/index.html (8 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Aadir las opciones: Deshacer, (separador),Cortar, Copiar, Pegar, Seleccionar todo, (separador), Buscar, Reemplazar, (separador) y Ajustar. Este submen se crear usando una plantilla de men. Seleccionar del men principal la cabecera Edicion. Pulsar el botn derecho del ratn y seleccionar Insert from Template | Edit Menu. Borrar la antigua cabecera Edicion. Camiar la nueva cabecera Edit para dejarla Name=EditMenu y Caption=&Edicion. A continuacin, modificar el submen Edicion para que quede:
r r r r r r

r r r r r

Deshacer:Name=EditUndo, Caption=&Deshacer, ShortCut=Ctrl+Z Incluir un separador: Caption = Cortar: Name=EditCut, Caption=C&ortar, y ShortCut=Ctrl+X, Copiar: Name=EditCopy, Caption=&Copiar y ShortCut=Ctrl+C, Pegar: Name=EditPaste, Caption=P&egar y ShortCut=Ctrl+V, Seleccionat todo: Name=EditSelectAll, Caption=Seleccionar &todo y ShortCut=Ctrl+A, Incluir un separador: Caption = Buscar: Name=EditFind, Caption=&Buscar y Enabled=false, Reemplazar: Name=EditReplace, Caption=&Reemplazar y Enabled=false Incluir un separador: Caption = Ajustar: Name=EditWordWrap, Caption=&Ajustar, y Checked=true

file:///D|/Manuales/intro/ejemplos/editor/index.html (9 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

3.4. Men Ayuda.

Solamente tendr una opcin: Acerca de ... . Establecer las propiedades Name=HelpAbout y Caption=Ace&rca de ... Finalmente, cerrar el diseador de mens. El aspecto del formulario ser el siguiente:

3.5. Men Contextual.

Para crear el men contextual, seleccionar el componente no visual PopUpMenu


file:///D|/Manuales/intro/ejemplos/editor/index.html (10 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

(solapa Standard) y colocarlo en algn lugar del formulario. Fijar Name=PopUpMenu. Este men se disear con el diseador de mens, de la misma manera que se ha hecho con el men principal. Aadir las opciones: Cortar, Copiar, Pegar, (separador) y Acerca de. Para cada opcin:
r r r r r

Cortar: Name=PopUpCut, Caption=C&ortar, y ShortCut=Ctrl+X, Copiar: Name=PopUpCopy, Caption=&Copiar y ShortCut=Ctrl+C, Pegar: Name=PopUpPaste, Caption=P&egar y ShortCut=Ctrl+V, Incluir un separador: Caption = Acerca de ... : Name=PopUpAbout y Caption=Ace&rca de ... .

El men contextual puede asociarse a cualquier componente que tenga asociada la propiedad PopupMenu. En este caso se asociar al componente Memo para que al pulsar el botn derecho del ratn se despliegue el men que acabamos de crear. Para esto, seleccionar el componente Memo, acceder a la propiedad PopupMenu y seleccionar PopUpMenu (el nico disponible).

4. Escribir el cdigo del programa.

Cada opcin del men y cada botn de la barra rpida debe tener asociada una accin. La accin se asocia a cada componente mediante el gestor de eventos del inspector de objetos. Todos los manipuladores de eventos se escriben con una metodologa similar. Detallaremos cmo se hace el de la opcin Ficheros | Salir, y los dems se completarn siguiendo las lneas aqu descritas. Seleccionar Ficheros | Salir del menu principal. Se activa el editor de cdigo, mostrando el gestor que se va a completar:
//-----------------------------------------------------------void __fastcall TMainForm::FileExitClick(TObject *Sender) { } //------------------------------------------------------------

file:///D|/Manuales/intro/ejemplos/editor/index.html (11 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Completar la funcin de la siguiente forma:


//-----------------------------------------------------------void __fastcall TMainForm::FileExitClick(TObject *Sender) { Application->Terminate(); } //------------------------------------------------------------

Como el botn rpido para salir ExitBtn debe realizar la misma tarea, le asignamos las misma funcin al evento OnClick. Para ello, seleccionar el componente ExitBtn en el inspector de objetos, pulsar en la pestaa Events y en en evento OnClick. Para seleccionar una de las funciones ya escritas, desplegar la lista de funciones pulsando sobre la flecha que aparece a la derecha del evento OnClick (ahora slo est FileExitClick()) y seleccionarla. Dicho de otra forma, la funcin FileExitClick() se activa desde Ficheros | Salir y desde el botn rpido ExitBtn. Para cada opcin, proceder de la misma forma. As, el resultado final debe ser:
r

Opcin: Ficheros | Nuevo Opcin: Ficheros | Abrir y botn rpido FileOpenBtn Opcin: Ficheros | Guardar y botn rpido FileSaveBtn Opcin: Ficheros | Guardar como Opcin: Edicin | Deshacer Opcin: Edicin | Cortar y Cortar del men contextual. Opcin: Edicin | Copiar y Copiar del men contextual. Opcin: Edicin | Pegar y Pegar del men contextual. Opcin: Edicin | Seleccionar todo

file:///D|/Manuales/intro/ejemplos/editor/index.html (12 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto


r

Opcin: Edicin | Ajustar

5. Aadir un nuevo formulario (Acerca de...) Seleccionar File | New Form. Sobre este formulario, disear una ventana modal titulada Acerca de Mi editor de texto con el siguiente aspecto:

Fijar las propiedades del formulario Caption = Acerca de Mi editor de texto, Name = AboutBox y BorderStyle = bsDialog y configurarlo: 1. Aadir tres componentes Label (solapa Standard) con textos (Caption): Mi editor de texto, Versin 1.0, y Curso de Programacin Visual, respectivamente. 2. Aadir un icono (el mismo que se asoci a la aplicacin) seleccionando un componente Image (solapa Additional). Para este componente, fijar Autosize = true. 3. Aadir un botn de OK. Corresponde al componente BitBtn (solapa Additional). Fijar Kind = bkOK. 4. Crear un marco que englobe a los tres componentes Label. Seleccionar el componente Bevel (solapa Additional) y enmarcar el texto. Fijar Shape = bsFrame.

file:///D|/Manuales/intro/ejemplos/editor/index.html (13 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Almacenar la unidad. Seleccionar File | Save y darle el nombre About.cpp Aadir esta unidad al proyecto. Seleccionar FuncsEditor.cpp y File | Include Unit Hdr. Seleccionar About. Ahora, cuando se seleccione Ayuda | Acerca de ... o Acerca de ... en el men contextual debe abrirse la ventana que hemos creado. El cdigo que abre esta ventana se completa como sigue: seleccionar la opcin Ayuda | Acerca de ... y completar el manipulador HelpAboutClick() de la siguiente forma:
//-----------------------------------------------------------

void __fastcall TMainForm::HelpAboutClick(TObject *Sender) { AboutBox->ShowModal(); } //-----------------------------------------------------------

Asignar la misma funcin al gestor del evento OnClick de PopUpAbout. Finalmente, construir el proyecto y ejecutarlo.

6. Sobre la barra de estado y los cuadros de pista (Hints). Se puede asociar a cada componente un cuadro de pista (Hint) fijando al valor de su propiedad Hint al texto que se quiere mostrar. Si se desea que aparezca un texto ms amplio en la barra de estado, ste se especifica tambin en la misma propiedad separado por la barra |. Por ejemplo, seleccionar el botn FileOpenBtn y fijar la propiedad Hint a Abrir fichero | Abrir un fichero existente y fijar ShowHint = true. Salvar, construir el proyecto y ejecutar. Observar que al poner el cursor sobre el botn se muestra el cuadro de pista pero no en la barra de estado. Modificar las propiedades Hint de los botones FileSaveBtn y ExitBtn fijndolas a Guardar fichero | Guardar en un fichero el texto mostrado y
file:///D|/Manuales/intro/ejemplos/editor/index.html (14 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Salir | Terminar la ejecucin del programa, respectivamente, y fijar para ambos ShowHint = true. Para que aparezca el texto largo en la barra de estado basta con establecer la propiedad AutoHint de la barra de estado a true. Finalmente, salvar, construir el proyecto y ejecutar.

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/index.html (15 of 15) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Ficheros | Nuevo

//---------------------------------------------------------void __fastcall TMainForm::FileNewClick(TObject *Sender) { // Abre un nuevo fichero. Primero hay que verificar // que el fichero actual tiene que guardarse. if (Memo->Modified) { // Mostrar un cuadro de mensaje. int result = Application->MessageBox( "El fichero activo ha cambiado. Salvar los cambios?", "!Cuidado!", MB_YESNOCANCEL); // Si se pulsa YES, guardar el archivo actual. if (result == IDYES) FileSaveClick(Sender); // Si se pulsa CANCEL, no hacer nada. if (result == IDCANCEL) return; } // Borrar el contenido de Memo, si lo hay. if (Memo->Lines->Count > 0) Memo->Clear(); // Sustituir el valor de la propiedad FileName del cuadro // de dialogo Save por espacios en blanco. Asi se sabe // que el fichero no se ha guardado aun. SaveDialog->FileName = "";
file:///D|/Manuales/intro/ejemplos/editor/fich_nuevo.html (1 of 2) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

} //-----------------------------------------------------------

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/fich_nuevo.html (2 of 2) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Ficheros | Abrir y botn FileOpenBtn

//---------------------------------------------------------void __fastcall TMainForm::FileOpenClick(TObject *Sender)

// Abrir un fichero. Verificar en primer lugar si hay que // salvar el archivo actual. Igual que en FileNewClick()

if (Memo->Modified) {

// Mostrar un cuadro de mensaje.

int result = Application->MessageBox( "El fichero activo ha cambiado. Salvar los cambios?",

file:///D|/Manuales/intro/ejemplos/editor/fich_abrir.html (1 of 3) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

"!Cuidado!", MB_YESNOCANCEL);

// Si se pulsa YES, guardar el archivo actual.

if (result == IDYES) FileSaveClick(Sender);

// Si se pulsa CANCEL, no hacer nada.

if (result == IDCANCEL) return;

// Abrir el cuadro de dilogo File Open.

OpenDialog->FileName = "";

if (OpenDialog->Execute()) {

// Borrar el contenido de Memo, si lo hay.

if (Memo->Lines->Count > 0) Memo->Clear();

file:///D|/Manuales/intro/ejemplos/editor/fich_abrir.html (2 of 3) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

// Leer el fichero a Memo.

Memo->Lines->LoadFromFile(OpenDialog->FileName);

SaveDialog->FileName = OpenDialog->FileName;

//----------------------------------------------------------

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/fich_abrir.html (3 of 3) [27/02/2003 16:24:12]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Ficheros | Guardar y botn FileSaveBtn

//-----------------------------------------------------------

void __fastcall TMainForm::FileSaveClick(TObject *Sender)

// Si ya se ha especificado un nombre de fichero no es // necesario abrir el cuadro de dilogo Guardar Fichero. // Solo hay que guardarlo con SaveToFile().

if (SaveDialog->FileName != "") {

Memo->Lines->SaveToFile(SaveDialog->FileName);

file:///D|/Manuales/intro/ejemplos/editor/fich_guardar.html (1 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

// Establecer ahora la propiedad Modified a FALSE.

Memo->Modified = false;

// Si no se ha dado un nombre, ejecutar SaveAs().

else FileSaveAsClick(Sender);

//-----------------------------------------------------------

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/fich_guardar.html (2 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Ficheros | Guardar como

//-----------------------------------------------------------

void __fastcall TMainForm::FileSaveAsClick(TObject *Sender)

SaveDialog->Title = "Save As";

if (SaveDialog->Execute()) {

Memo->Lines->SaveToFile(SaveDialog->FileName); Memo->Modified = false;

file:///D|/Manuales/intro/ejemplos/editor/fich_guardar_como.html (1 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

//-----------------------------------------------------------

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/fich_guardar_como.html (2 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Edicin | Deshacer

//-----------------------------------------------------------

void __fastcall TMainForm::EditUndoClick(TObject *Sender)

Memo->Undo(); // Llamada a TMemo->Undo()

//-----------------------------------------------------------

file:///D|/Manuales/intro/ejemplos/editor/edic_deshacer.html (1 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/edic_deshacer.html (2 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Edicin | Cortar y Cortar del men contextual.

//-----------------------------------------------------------

void __fastcall TMainForm::EditCutClick(TObject *Sender)

Memo->CutToClipboard(); // Llamada a TMemo->CutToClipboard()

//-----------------------------------------------------------

file:///D|/Manuales/intro/ejemplos/editor/edic_cortar.html (1 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/edic_cortar.html (2 of 2) [27/02/2003 16:24:13]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Edicin | Copiar y Copiar del men contextual.

//-----------------------------------------------------------

void __fastcall TMainForm::EditCopyClick(TObject *Sender)

Memo->CopyToClipboard(); //Llamada a TMemo->CopyToClipboard()

//-----------------------------------------------------------

file:///D|/Manuales/intro/ejemplos/editor/edic_copiar.html (1 of 2) [27/02/2003 16:24:14]

Ejemplos - Editor de texto

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/edic_copiar.html (2 of 2) [27/02/2003 16:24:14]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Edicin | Pegar y Pegar del men contextual.

//-----------------------------------------------------------

void __fastcall TMainForm::EditPasteClick(TObject *Sender)

Memo->PasteFromClipboard(); // TMemo->PasteFromClipboard()

//-----------------------------------------------------------

file:///D|/Manuales/intro/ejemplos/editor/edic_pegar.html (1 of 2) [27/02/2003 16:24:14]

Ejemplos - Editor de texto

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/edic_pegar.html (2 of 2) [27/02/2003 16:24:14]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Edicin | Seleccionar todo

//-----------------------------------------------------------

void __fastcall TMainForm::EditSelectAllClick(TObject *Sender)

Memo->SelectAll(); // TMemo->SelectAll()

//-----------------------------------------------------------

file:///D|/Manuales/intro/ejemplos/editor/edic_seleccionar_todo.html (1 of 2) [27/02/2003 16:24:14]

Ejemplos - Editor de texto

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/edic_seleccionar_todo.html (2 of 2) [27/02/2003 16:24:14]

Ejemplos - Editor de texto

Curso de C++ Builder Un sencillo editor de texto


Opcin: Edicin | Ajustar

//-----------------------------------------------------------

void __fastcall TMainForm::EditWordWrapClick(TObject *Sender)

// Modificar la propiedad TMemo::WordWrap.

Memo->WordWrap = !Memo->WordWrap;

EditWordWrap->Checked = Memo->WordWrap;

// Si WordWrap est activo, una barra. Si no, dos.

file:///D|/Manuales/intro/ejemplos/editor/edic_ajustar.html (1 of 2) [27/02/2003 16:24:14]

Ejemplos - Editor de texto

if (Memo->WordWrap) Memo->ScrollBars = ssVertical; else Memo->ScrollBars = ssBoth;

//-----------------------------------------------------------

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/editor/edic_ajustar.html (2 of 2) [27/02/2003 16:24:14]

OOP - Ejemplo 0

Curso de C++ Builder Ejemplo 0


Corresponde al final de la seccin 5.2.4, tras la herencia y antes de ABSTRACCIN.

EJEMPLO.CPP
//---------------------------------------------------------------------#include <vcl.h> #pragma hdrstop USERES("Ejemplo.res"); USEFORM("Ppal.cpp", PpalFrm); USEUNIT("ObjGraf.cpp"); //----------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TPpalFrm), &PpalFrm); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } //----------------------------------------------------------------------

PPAL.H
//---------------------------------------------------------------------file:///D|/Manuales/intro/ejemplos/oop/Ejemplo0.html (1 of 7) [27/02/2003 16:24:15]

OOP - Ejemplo 0

#ifndef PpalH #define PpalH //---------------------------------------------------------------------#include #include #include #include #include <Classes.hpp> <Controls.hpp> <StdCtrls.hpp> <Forms.hpp> <ExtCtrls.hpp>

#include "ObjGraf.h" #include <Buttons.hpp> //---------------------------------------------------------------------class TPpalFrm : public TForm { __published: // IDE-managed Components TPaintBox *PaintBox; TBitBtn *BotonSalir; void __fastcall FormCreate(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); void __fastcall PaintBoxPaint(TObject *Sender); void __fastcall BotonSalirClick(TObject *Sender); private: // User declarations

public: // User declarations __fastcall TPpalFrm(TComponent* Owner); }; //---------------------------------------------------------------------extern PACKAGE TPpalFrm *PpalFrm; //---------------------------------------------------------------------#endif

PPAL.CPP
//---------------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "Ppal.h" //---------------------------------------------------------------------file:///D|/Manuales/intro/ejemplos/oop/Ejemplo0.html (2 of 7) [27/02/2003 16:24:15]

OOP - Ejemplo 0

#pragma package(smart_init) #pragma resource "*.dfm" TPpalFrm *PpalFrm; // Punteros a objetos de las clases derivadas. TCirculo *Cir1, *Cir2; TCuadrado *Cuad1, *Cuad2; //----------------------------------------------------------------------

__fastcall TPpalFrm::TPpalFrm(TComponent* Owner) : TForm(Owner) { } //----------------------------------------------------------------------

void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Cir1 = new TCirculo (PaintBox, clBlack, 100, 100, Cir2 = new TCirculo (PaintBox, clGreen, 210, 40, Cuad1 = new TCuadrado (PaintBox, clRed, 200, 150, Cuad2 = new TCuadrado (PaintBox, clYellow, 120, 70, }

30); 20); 45); 25);

//---------------------------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { delete Cir1; delete Cir2; delete Cuad1; delete Cuad2; } //---------------------------------------------------------------------void __fastcall TPpalFrm::PaintBoxPaint(TObject *Sender) { Cir1->Mostrar(); Cir2->Mostrar(); Cuad1->Mostrar(); Cuad2->Mostrar(); } //---------------------------------------------------------------------void __fastcall TPpalFrm::BotonSalirClick(TObject *Sender) { Application->Terminate(); }
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo0.html (3 of 7) [27/02/2003 16:24:15]

OOP - Ejemplo 0

//----------------------------------------------------------------------

OBJGRAF.H
//---------------------------------------------------------------------#ifndef ObjGrafH #define ObjGrafH //*************************************************/ // Definicion de la clase base TObjGraf //*************************************************/ class TObjGraf { public: int X; int Y; TColor TPaintBox // Propiedades Color; *PaintBox;

// Constructor de objetos TObjGraf TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0); // Otros metodos virtual void Mostrar (void) = 0; // Metodo virtual puro };

//*************************************************/ // Definicion de la clase derivada TCirculo. // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { public: int Radio; // Metodo constructor TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack,
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo0.html (4 of 7) [27/02/2003 16:24:15]

OOP - Ejemplo 0

int _X=0, int _Y=0, int _Radio=1); // Instanciacion del metodo virtual puro de la clase TObjGraf void Mostrar (void); }; //*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf { public: int Lado; // Metodo constructor TCuadrado (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Lado=1); // Instanciacion del metodo virtual puro de la clase TObjGraf void Mostrar (void); }; //---------------------------------------------------------------------#endif

OBJGRAF.CPP
//---------------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "ObjGraf.h" //---------------------------------------------------------------------#pragma package(smart_init) /*****************************************************/ // Metodos asociados a la clase base TObjGraf /*****************************************************/

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo0.html (5 of 7) [27/02/2003 16:24:15]

OOP - Ejemplo 0

TObjGraf :: TObjGraf (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y) { PaintBox = _PaintBox; Color = _Color; X = _X; Y = _Y; }

/*****************************************************/ // Metodos asociados a la clase derivada TCirculo. // TCirculo deriva de la clase base TObjGraf. /*****************************************************/ TCirculo :: TCirculo (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Radio) : TObjGraf (_PaintBox, _Color, _X, _Y) { Radio = _Radio; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCirculo :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } /*****************************************************/ // Metodos asociados a la clase derivada TCuadrado. // TCuadrado deriva de la clase base TObjGraf. /*****************************************************/ TCuadrado :: TCuadrado (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Lado) : TObjGraf (_PaintBox, _Color, _X, _Y) { Lado = _Lado; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCuadrado :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Rectangle(X, Y, X+Lado, Y+Lado); }

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo0.html (6 of 7) [27/02/2003 16:24:15]

OOP - Ejemplo 0

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo0.html (7 of 7) [27/02/2003 16:24:15]

Programacin Orientada a Objetos en C++

Curso de C++ Builder Programacin Orientada a Objetos en C++

q q q q q

5.1. El Paradigma de la POO en C++. 5.2. Creacin y Destruccin de Objetos. 5.3. Encapsulamiento. 5.4. Constructores y Destructores (Inicializacin de Clases I). 5.5. Herencia.
r r r

5.5.1. Herencia de Constructores y Destructores (Inicializacin de Clases II). 5.5.2. Clases Abstractas. 5.5.3. Herencia Mltiple.

5.6. Abstraccin.
r r

5.6.1. Restricciones de acceso en C++. 5.6.2. Propiedades Virtuales.

5.7. Polimorfismo.
r r

5.7.1. Sobrecarga de funciones.. 5.7.2. Polimorfismo en las clases y mtodos virtuales..

En esta seccin no se pretende dar una teora completa de P.O.O. tan slo se presentarn los conceptos necesarios para una correcta programacin en C++ Builder. La P.O.O. es un paradigma de programacin que se fundamenta en los conceptos de objeto y clase. En primer lugar, definamos que entendemos por objeto y clase: Objeto: Una entidad autnoma con una funcionalidad concreta y bien definida. Clase: Especificacin de las caractersticas de un conjunto de objetos. Un objeto es una instancia de una clase. Los conceptos presentados en esta seccin se ilustrarn usando un ejemplo que se ir completando poco a poco a medida que se introduzcan nuevos conceptos. Es ms, este mismo ejemplo se emplea en las secciones dedicadas al tratamiento de excepciones y a la programacin con hebras. As, preparemos el camino creando un proyecto:

file:///D|/Manuales/intro/5.html (1 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++


q

Crear un proyecto (File | New | Application) Cambiar el nombre del formulario (Name=PpalFrm). Colocar un PaintBox de la pgina de componentes System que se llame PaintBox, con Align=alTop. Dejar espacio por debajo del PaintBox para colocar un botn. Colocar un bevel de ancho 4 y alinearlo en lo alto (Align=alTop). La idea es que delimite la parte inferior del PaintBox. Colocar un botn bit que permita terminar la ejecucin del programa. El botn estar centrado horizontalmente en la parte inferior del formulario. Guardar el cdigo del formulario como Ppal.cpp y el proyecto como Ejemplo.bpr. Crear una unidad (File | New | Unit). Guardarla con el nombre ObjGraf.cpp Cuando se crea una unidad de esta manera se crean, en realidad, dos ficheros, uno con extensin .cpp y otro con extensin .h. As, disponemos de dos ficheros: ObjGraf.h, que contendr las declaraciones de las clases con las que vamos a trabajar, y ObjGraf.cpp, que contendr la definicin (implementacin de los mtodos) de stas.

En ObjGraf.h:
//-------------------------------------------------#ifndef ObjGrafH #define ObjGrafH // Definicin de la clase TObjGraf class TObjGraf {}; #endif //--------------------------------------------------

Ntese que el nombre de la clase va precedido por una T, y, aunque no es obligatorio, si es muy recomendable ya que es una convencin de C++ Builder que casi todos los nombres de clases vayan precedidos por T. Muy Importante: Con el ejemplo anterior slo conseguimos definir la clase, pero no se crea ningn objeto.

5.1. El Paradigma de la POO en C++


Existen cuatro principios bsicos que cualquier sistema orientado a objetos debe incorporar, que se
file:///D|/Manuales/intro/5.html (2 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

esquematizan en la figura 5.1. Figura 5.1. Pilares de la POO.

5.2. Creacin y Destruccin de Objetos


Ya se ha dicho que una clase es nicamente una especificacin. Para poder utilizar la funcionalidad contenida en la misma, se deben instanciar las clases. 1. Creacin por Declaracin. Un objeto se puede instanciar de una forma simple, declarando una variable del tipo de la clase. En Ppal.h:
#include "ObjGraf.h"

En Ppal.cpp: Pulsando dos veces en OnCreate de la pestaa Events del editor de objetos de PpalFrm:
//-------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { TObjGraf ObjGraf1(); TObjGraf ObjGraf2; }
file:///D|/Manuales/intro/5.html (3 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

//--------------------------------------------------

Aunque esta forma es posible, y bastante utilizada en la programacin de C++ clsica, en C++ Builder se utiliza en muy contadas ocasiones. Esto es as por dos razones, fundamentalmente: 1. La duracin de los objetos suele ir ms all de una simple funcin o bloque. Debido al enfoque de la programacin dirigida por eventos, suele ser habitual que un objeto se cree en un gestor de eventos y se destruya en otro. 2. No se puede usar esta modalidad de creacin con la VCL. Por lo tanto, nosotros no la utilizaremos.

2. Creacin Dinmica Es la forma habitual de crear objetos en C++ Builder, y se realiza mediante el operador new . Cuando usamos new para instanciar un objeto, se usa una variable que referencie o apunte al nuevo objeto creado (de otra manera ste quedara totalmente inaccesible). En definitiva, se requiere la declaracin previa de un puntero a objetos del tipo del que se va a crear. En Ppal.cpp:
TObjGraf * ObjGraf; // Variable Global. // ObjGraf es un puntero a objetos de tipo TObjGraf //-------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { ObjGraf = new TObjGraf; } //--------------------------------------------------

La forma de establecer el estado inicial o destruir las componentes de un objeto se estudiarn en el apartado dedicado a Constructores y Destructores (seccin 5.4). Cuidado! Cuando se utiliza esta forma de instanciacin de clases es responsabilidad nicamente del programador la correcta destruccin de los mismos.

3. Destruccin de objetos

file:///D|/Manuales/intro/5.html (4 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

Cuando un objeto deja de ser til hay que eliminarlo. De esta manera la aplicacin recupera los recursos (memoria) que ese objeto haba acaparado cuando se cre. La destruccin de objetos creados en tiempo de ejecucin con new se realiza mediante el operador delete. En Ppal.cpp: Pulsando dos veces en OnDestroy de la pestaa Events del editor de objetos de PpalFrm:
//-------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { delete ObjGraf; } //--------------------------------------------------

5.3. Encapsulamiento
En la programacin clsica (lenguaje C, p.e.) existen datos y procedimientos que actan sobre esos datos. No hay una relacin aparente entre datos y procedimientos (funciones) y esta relacin se establece de manera ms o menos pecisa de acuerdo a la profesionalidad del programador. En un objeto podemos distinguir dos aspectos bien diferenciados:
q q

Estado -----------> Propiedades Comportamiento ---> Mtodos

En P.O.O. los datos y los procedimientos que los gestionan estn relacionados explcitamente y se "encapsulan" en un objeto. La especificacin de las propiedades de un objeto y los mtodos de acceso se realiza en la declaracin de la clase de la que se instancia el objeto. En la figura 5.2 esquematizamos las propiedades y mtodos que se van a asociar a los objetos de la clase TObjGraf: Figura 5.2. Propiedades y mtodos de los objetos de la clase TObjGraf.

La declaracin de propiedades y mtodos de los objetos de la clase TObjGraf se realiza de la siguiente manera:
file:///D|/Manuales/intro/5.html (5 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

En ObjGraf.h:
//-------------------------------------------------class TObjGraf { public: int X; int Y; TColor Color; TPaintBox *PaintBox;

// Propiedades

void Mostrar (void); // Mtodos }; //--------------------------------------------------

Acceso a Miembros de un Objeto Para acceder a los miembros de un objeto se usan los operadores tpicos de acceso a miembros: el operador . para referencia directa al objeto y el operador -> para acceso a travs de un puntero. Como nosotros siempre creamos los objetos con new, y los referenciamos mediante un puntero, el operador de acceso que utilizaremos es el operador -> En Ppal.cpp:
//-------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { ... int ValorY; ... ObjGraf->X = 5; ValorY = ObjGraf->Y; ObjGraf->Mostrar(); //Equivalente a (*Obj).Mostrar(); } //--------------------------------------------------

Nota: Los puntos suspensivos no son una palabra reservada de C++, simplemente significan que se omite una parte del cdigo, ya sea porque es irrelevante o porque ya se ha expuesto anteriormente.

5.4. Constructores y Destructores (Inicializacin de Clases I)


Son mtodos que permiten establecer el estado inicial y final de un objeto. Los constructores se pueden

file:///D|/Manuales/intro/5.html (6 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

definir con un conjunto de argumentos arbitrario, pero no pueden devolver nada. Y los destructores no pueden recibir ni devolver ningn valor. El constructor debe llamarse igual que la clase, y el destructor el nombre de la clase precedido del carcter ~ Un constructor se ejecuta cuando se crea un nuevo objeto: 1) por declaracin, 2) cuando se crea dinmicamente con el operador new. Un destructor se ejecuta cuando el objeto deja de existir: 1) porque su mbito acaba, 2) cuando se libera explcitamente con el operador delete. En ObjGraf.h:
class TObjGraf { ... // Constructor de objetos TObjGraf TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0); // El destructor sera: ~TObjGraf (void); };

En ObjGraf.cpp:
TObjGraf :: TObjGraf (TPaintBox * _PaintBox, TColor _Color, int _X, int _Y) { PaintBox = _PaintBox; Color = _Color; X = _X; Y = _Y; }

En Ppal.cpp:
void __fastcall TPpalFrm::FormCreate(TObject *Sender) { ObjGraf = new TObjGraf (PaintBox, clRed, 10, 10); }

Importante: No es necesario escribir un destructor salvo si el objeto requiere memoria dinmica adicional. De ser as, la tarea del destructor ser, bsicamente, liberar la memoria dinmica que ocupa el objeto que se va a destruir.

5.5. Herencia
Cuando una clase hereda de otra, la clase derivada incorpora todos los miembros de la clase base adems
file:///D|/Manuales/intro/5.html (7 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

de los suyos propios. La herencia es una herramienta muy importante en muchos aspectos del desarrollo de aplicaciones:
q q q

Organizacin del diseo. Reusabilidad de clases (propias o no). Mejora del mantenimiento.

Tomando como base la clase TObjGraf se van a construir dos nuevas clases, TCirculo y TCuadrado, que derivan de TObjGraf. Esto significa que los objetos de estas clases tienen asociados las propiedades y mtodos de la clase base, TObjGraf, adems de los suyos propios. En la figura 5.3 esquematizamos el mecanismo de herencia para las nuevas clases y las nuevas propiedades que se asocian a los objetos de las clases derivadas. Figura 5.3. Las clases TCirculo y TCuadrado heredan las propiedades y mtodos de la clase TObjGraf.4

En ObjGraf.h:
//*************************************************/ // Definicion de la clase derivada TCirculo // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { public: int Radio; // Propiedad exclusiva de TCirculo }; //*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf { public: int Lado; // Propiedad exclusiva de TCuadrado

file:///D|/Manuales/intro/5.html (8 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

};

Antes del nombre de la clase base hay que poner public, esto es as porque C++ permite tambin la herencia private. Pero sta no se suele usar, por lo que nosotros supondremos que slo existe la public.

5.5.1. Herencia de Constructores y Destructores (Inicializacin de Clases II) Los constructores y destructores de una clase no son heredadas automticamente por sus descendientes. Deberemos crear en las clases hijas sus propios constructores y destructores. Es posible, no obstante, emplear los constructores de la clase base pero hay que indicarlo explcitamente. De ser as, es necesario saber: 1. que los constructores y destructores de las clases base son invocados automticamente antes que los constructores de las clases derivadas, y 2. que los destructores de las clases derivadas se invocan antes que los de las clases base. Para determinar con qu parmetros se llaman a los constructores de las clases base, se utiliza la lista de inicializacin. En ObjGraf.h:
//*************************************************/ // Definicion de la clase derivada TCirculo // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { public: int Radio; // Propiedad exclusiva de TCirculo // Metodo constructor TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1); }; //*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf { public: int Lado; // Propiedad exclusiva de TCuadrado

file:///D|/Manuales/intro/5.html (9 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

// Metodo constructor TCuadrado (TPaintBox * _PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Lado=1); };

En ObjGraf.cpp:
TCirculo :: TCirculo (TPaintBox * _PaintBox, TColor _Color, int _X, int _Y, int _Radio) : TObjGraf (_PaintBox, _Color, _X, _Y) { Radio = _Radio; } TCuadrado :: TCuadrado (TPaintBox * _PaintBox, TColor _Color, int _X, int _Y, int _Lado) : TObjGraf (_PaintBox, _Color, _X, _Y) { Lado = _Lado; }

5.5.2. Clases Abstractas Clase abstracta: es una clase que no est completamente especificada (posee mtodos sin implementar), por lo tanto no se pueden crear instancias de la misma. Una clase abstracta se usa para servir de clase base a otras clases. En terminologa C++ se dice que una clase abstracta es aquella que posee al menos un mtodo virtual puro.
q q

Virtual: obliga a las clases derivadas a implementar ese mtodo. Puro: no pueden crearse instancias de esa clase.

En ObjGraf.h:
class TObjGraf { public: ... // Otros metodos virtual void Mostrar (void) = 0; // Metodo virtual puro }; class TCirculo : public TObjGraf {

file:///D|/Manuales/intro/5.html (10 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

public: ... // Instanciacion del metodo virtual puro de la clase TObjGraf void Mostrar (void); }; class TCuadrado : public TObjGraf { public: ... // Instanciacion del metodo virtual puro de la clase TObjGraf void Mostrar (void); };

En ObjGraf.cpp:
void TCirculo :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } ... void TCuadrado :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Rectangle(X, Y, X+Lado, Y+Lado); }

Por qu se especifica el mtodo Mostrar en TObjGraf, como virtual puro, en lugar de omitirlo? Fundamentalmente podemos considerar dos razones para usar mtodos virtuales puros: 1. Para obligar a que las clases descendientes los implementen. De esta forma estamos seguros de que todas las clases descendientes no abstractas de TObjGraf poseen el mtodo, y se podr invocar con seguridad. 2. Para evitar que se puedan crear instancias de la clase abstracta. En este estado, si probamos a ejecutar el programa, nos aparecer un error: no se puede crear una instancia de una clase abstracta. Porqu?: Recordar que en Ppal.cpp el gestor asociado al evento OnCreate del formulario est escrito como sigue:
//--------------------------------------------------

file:///D|/Manuales/intro/5.html (11 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

void __fastcall TPpalFrm::FormCreate(TObject *Sender) { ObjGraf = new TObjGraf (PaintBox, clRed, 10, 10); }; //--------------------------------------------------

As, creemos entonces objetos de las clases hijas: 1. En primer lugar, en Ppal.cpp hay que borrar la declaracin de la variable global:
TObjGraf *ObjGraf; // Variable Global.

y en su lugar se declararn cuatro punteros, dos para referenciar a objetos de tipo TCirculo y otros dos para referenciar a objetos de tipo TCuadrado:
// Punteros a objetos de las clases derivadas. TCirculo *Cir1, *Cir2; TCuadrado *Cuad1, *Cuad2;

2. En segundo lugar, modificaremos la funcin FormCreate para que cree dos objetos de cada clase referenciados por los punteros declarados anteriormente:
//-------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Cir1 = new TCirculo (PaintBox, clBlack, 100, 100, Cir2 = new TCirculo (PaintBox, clGreen, 210, 40, Cuad1 = new TCuadrado (PaintBox, clRed, 200, 150, Cuad2 = new TCuadrado (PaintBox, clYellow, 120, 70, }; //--------------------------------------------------

30); 20); 45); 25);

3. Finalmente, modificaremos la funcin FormDestroy para que elimine los objetos creados:
//-------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { delete Cir1; delete Cir2; delete Cuad1; delete Cuad2;

file:///D|/Manuales/intro/5.html (12 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

} //--------------------------------------------------

Ahora, al ejecutar el programa se crean y se destruyen objetos de las clases derivadas, aunque no se visualizan en la ventana. Porqu? En ningn momento se ha llamado al mtodo Mostrar() asociado a cada objeto. Para mostrar los objetos, basta con indicarlo en el gestor asociado al evento OnPaint del componente PaintBox:
//-------------------------------------------------void __fastcall TPpalFrm::PaintBoxPaint(TObject *Sender) { Cir1->Mostrar(); Cir2->Mostrar(); Cuad1->Mostrar(); Cuad2->Mostrar(); } //--------------------------------------------------

En este punto, el proyecto debe estar como se indica en el proyecto Ejemplo0. El resultado es el mostrado en la figura 5.4: 4 Figura 5.4. Resultado del proyecto Ejemplo.bpr.

Ejercicio: Construir la clase TTriangulo y modificar el proyecto para que proporcione un resultado similar al de la figura 5.5.

file:///D|/Manuales/intro/5.html (13 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

Figura 5.5. Resultado del proyecto Ejemplo.bpr mostrando objetos de la clase TTriangulo.

5.5.3. Herencia Mltiple La herencia mltiple es el hecho de que una clase derivada se genere a partir de varias clases base.

Ejemplo: En un concesionario de coches podramos considerar la siguiente jerarqua de clases:


class TProducto { long Precio; ... }; class TVehiculo { int NumRuedas; ... }; class TCocheEnVenta : public TProducto, public TVehiculo { ... };

Observar que los objetos de la clase TCocheEnVenta derivan de las clases TProducto y TVehiculo.

file:///D|/Manuales/intro/5.html (14 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

Existen dos formas para que una clase saque partido de las ventajas de otra, una es la herencia, y la otra es que una clase contenga un objeto de la otra clase. Ninguna de las dos posibilidades es mejor que la otra, en cada caso particular habr que estudiar cual es la mejor opcin. Por ejemplo, si quisieramos disear una clase (TMarco) que represente un marco (representado por un cuadrado y un crculo), podemos decidir distintas estrategias a la hora de llevarlo a cabo:
q q q q

Que herede de TCirculo y TCuadrado. Que herede de TObjGraf y contenga un objeto de la clase TCirculo y otro de TCuadrado. Que herede de TCirculo y contenga un objeto de la clase TCuadrado. Que herede de TCuadrado y contenga un objeto de la clase TCirculo.

5.6. Abstraccin
Es la ocultacin de detalles irrelevantes o que no se desean mostrar. Podemos distinguir en una clase dos aspectos desde el punto de vista de la abstraccin:
q q

Interfaz: lo que se puede ver/usar externamente de un objeto. Implementacin: cmo lleva a cabo su cometido.

Resumiendo: nos interesa saber qu nos ofrece un objeto, pero no cmo lo lleva a cabo.

5.6.1. Restricciones de acceso en C++ En C++ se puede especificar el acceso a los miembros de una clase utilizando los siguientes especificadores de acceso:
q q q

public: Interfaz de la clase. private: Implementacin de la clase. protected: Implementacin de la familia.

Estos especificadores no modifican ni la forma de acceso ni el comportamiento, nicamente controlan desde dnde se pueden usar los miembros de la clase:
q q q

public: desde cualquier sitio. private: desde los mtodos de la clase. protected: desde los mtodos de la clase y desde los mtodos de las clases derivadas.

En ObjGraf.h:

//*************************************************/
file:///D|/Manuales/intro/5.html (15 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

// Definicion de la clase base TObjGraf //*************************************************/ class TObjGraf { private: int X; int Y; protected: // Pueden acceder los objetos de esta clase y sus descendientes. TColor Color; TPaintBox * PaintBox; public: // Pueden usarlas todas. // Puede acceder SOLO los objetos de esta clase.

// Constructor de objetos TObjGraf TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0); // Otros metodos virtual void Mostrar (void) = 0; // Metodo virtual puro };

Modificar de la misma manera las clases TCirculo y TCuadrado para que sus propiedades Radio y Lado queden protegidas y los mtodos pblicos:
//*************************************************/ // Definicion de la clase derivada TCirculo. // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { protected: // Pueden acceder los objetos de esta clase y sus descendientes. int Radio; public: // Metodo constructor TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1); void Mostrar (void); // Instanciacion del metodo virtual puro // de la clase TObjGraf };

file:///D|/Manuales/intro/5.html (16 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

//*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf { protected: // Pueden acceder los objetos de esta clase y sus descendientes. int Lado; public: // Metodo constructor TCuadrado (TPaintBox * _PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Lado=1); void Mostrar (void); // Instanciacion del metodo virtual puro // de la clase TObjGraf };

As, si en Ppal.cpp escribiramos:


//-------------------------------------------------void __fastcall TPpalFrm::FormCreate (TObject *Sender) { ... Cir1->Mostrar(); // Se puede. Cir1->X = 10; // No se puede porque X es private. } //--------------------------------------------------

En realidad estos tres especificadores de acceso son los propios de C++, pero en C++ Builder existe otro adicional, que es el __published. No vamos a dar mucha importancia a este modificador, porque su uso est restringido al IDE. Cuando en una clase veamos una seccin __published quiere decir que los miembros contenidos en la misma son mantenidos automticamente por el IDE y no deberemos modificar nada en dicha seccin, ya que de lo contrario los resultados pueden ser imprevisibles. Es una buena tcnica de programacin no permitir el acceso pblico a las propiedades de un objeto, ya que si esto ocurriera podra peligrar la integridad del objeto. Entonces cmo se puede cambiar el estado de un objeto desde el exterior? 1. Ofreciendo mtodos (pblicos) que se encarguen de modificar las propiedades (privadas) que se desee. De esta manera son los mtodos los que acceden a las propiedades y el usuario de la clase slo accede a travs de ellos. Esta es la tcnica clsica que se emplea en C++ 2. A travs de los mtodos y de las propiedades "virtuales". Esta tcnica es exclusiva de C++ Builder y la describimos en la siguiente seccin.
file:///D|/Manuales/intro/5.html (17 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

5.6.2. Propiedades Virtuales Son propiedades definidas mediante mtodos de lectura (read) y/o escritura (write). Se llaman virtuales porque, realmente, no existen. El usuario de la clase usa estas propiedades como si fueran propiedades reales y en ltima instancia se traducen en la llamada a un mtodo o en el acceso a una propiedad real. Es ms, si una propiedad virtual se usa para lectura (p.e. en la parte derecha de una asignacin) se traduce en una accin diferente que si esa popiedad virtual se usa para escritura. La accin que se produce cuando la propiedad virtual es de lectura se especifica, sintcticamente, mediante la palabra reservada read mientras que si se usa para escritura se especifica con write. Veamos un ejemplo. En ObjGraf.h:
//*************************************************/ // Definicion de la clase base TObjGraf //*************************************************/ class TObjGraf { private: int FX; int FY; // Puede acceder SOLO los objetos de esta clase. // OJO: Se ha cambiado el nombre a // los miembros X e Y por FX y FY.

void SetX (int _X); void SetY (int _Y); virtual int GetAncho (void) = 0; // Metodo virtual puro virtual int GetAlto (void) = 0; // Metodo virtual puro protected: TColor TPaintBox public: // Pueden acceder los objetos de esta clase y descendientes. FColor; *PaintBox; // OJO: Se ha cambiado Color por FColor

// Pueden usarlas todas.

// Constructor de objetos TObjGraf TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0); // Otros metodos virtual void Mostrar (void) = 0; // Metodo virtual puro // NUEVAS FORMAS DE ACCESO CON PROPIEDADES VIRTUALES. __property int X = __property int Y = __property TColor Color = {read=FX, {read=FY, {read=FColor, write=SetX }; write=SetY }; write=FColor};

file:///D|/Manuales/intro/5.html (18 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

__property int __property int };

Ancho = Alto =

{read=GetAncho {read=GetAlto

}; };

Observaciones:
q

Observar que la "antigua" propiedad X (resp. Y) se llama ahora FX (resp. FY). Adems, hay una propiedad virtual (pblica) llamada X (resp. Y). Estas propiedades estn declaradas en la clase TObjGraf lo que significa que sus descendientes tambin las heredan. Si en Ppal.cpp se usara esta propiedad para lectura:
int CX = Cir1->X;

En realidad es como si se hiciera


int CX = Cir1->FX;

ya que cuando se accede para lectura a la propiedad (virtual) X en realidad se accede a la propiedad (real) FX. La ltima instruccin, no obstante, povocara un error porque FX es una propiedad privada. Si se usara esta propiedad para escritura:
Cir1->X = 100;

En realidad es como si se hiciera


Cir1->SetX(100);

ya que cuando se accede para escritura a la propiedad (virtual) X en realidad se llama al mtodo SetX(). La ltima instruccin, no obstante, povocara un error porque SetX() es un mtodo privado. Al "redirigir" la escritura al mtodo SetX() podemos controlar la validez del parmetro y corregir, en su caso, el valor: una ventaja adicional.
q

La propiedad virtual Color tiene asociado el mismo mtodo de acceso para lectura y escritura: devuelve o escribe, directamente, en la propiedad real FColor. Finalmente, observar que las propiedades virtuales Ancho y Alto no tienen asociados mtodos de acceso para escritura.

Como hemos incorporado dos nuevos mtodos a la clase base TObjGraf (GetAncho() y GetAlto()) y stos se han declarado virtuales puros necesitamos instanciarlos en las clases derivadas:

file:///D|/Manuales/intro/5.html (19 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

//*************************************************/ // Definicion de la clase derivada TCirculo. // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { protected: // Pueden acceder los objetos de esta clase y descendientes.

int Radio; inline int GetAncho inline int GetAlto public: // Metodo constructor TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1); void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf }; //*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf { protected: // Pueden acceder los objetos de esta clase y descendientes. (void) {return(Radio*2);} (void) {return(Radio*2);}

int Lado; inline int GetAncho inline int GetAlto public: // Metodo constructor TCuadrado (TPaintBox * _PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Lado=1); void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf }; (void) {return(Lado);} (void) {return(Lado);}

Ahora, aadimos (en ObjGraf.cpp) las funciones write de las propiedades virtuales X e Y:

file:///D|/Manuales/intro/5.html (20 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

// Funciones de escritura de las propiedades virtuales X e Y void TObjGraf :: SetX (int _X) { if (_X < 0) // Coordenada negativa FX = 0; // Ajustar al margen izquierdo else if (_X > (PaintBox->Width - Ancho)) // Demasiado alta FX = PaintBox->Width - Ancho; // Ajustar al margen derecho else FX = _X; // Correcto: escribir sin modificar } void TObjGraf :: SetY (int _Y) { if (_Y < 0) // Coordenada negativa FY = 0; // Ajustar al margen superior else if (_Y > (PaintBox->Height - Alto)) // Demasiado alta FY = PaintBox->Height - Alto; // Ajustar al margen inferior else FY = _Y; // Correcto: escribir sin modificar }

Muy importante: Cambiamos el constructor de la clase TObjGraf porque no se puede llamar a los mtodos virtuales puros de una propiedad virtual desde un constructor de una clase base. En este caso, no se puede llamar a los mtodos virtuales puros (GetAncho() y GetAlto()) de las propiedades virtuales (Ancho y Alto) desde el constructor de la clase base TObjGraf. En ObjGraf.cpp:
TObjGraf :: TObjGraf (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y) { PaintBox = _PaintBox; FColor = _Color; // MUY IMPORTANTE: Estas tres lineas han cambiado: FX = _X; // No se puede llamar a los metodos virtuales puros FY = _Y; // (GetAncho, GetAlto) para fijar el valor de una // propiedad virtual (Alto, Ancho) desde un // constructor de la clase base. }

En este punto, el proyecto debe estar como se indica en el proyecto Ejemplo1. El resultado el el mismo que el mostrado en la figura 5.4.

file:///D|/Manuales/intro/5.html (21 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

Experimentacin con las propiedades virtuales. 1. Los constructores no verifican coordenadas. Los objetos grficos (Cir1, Cir2, Cuad1 y Cuad2) se crean con sus correspondientes constructores, que en ltima instancia llaman al constructor de la clase base para establecer los valores de las propiedades reales FX, FY, FColor y PaintBox. La consecuencia es que si se crea un crculo, por ejemplo, con coordenadas incorrectas no se corrigen ya que como el constructor de la clase base no puede utilizar la propiedad virtual X para escritura no se emplea el mtodo SetX(). Como demostracin, en la funcin FormCreate()de Ppal.cppcambiar la lnea:

Cir1

= new TCirculo

(PaintBox, clBlack,

100, 100, 30);

por:

Cir1

= new TCirculo

(PaintBox, clBlack,

-100, 100, 30);

Observar que el crculo negro no se muestra. 2. Lectura/escritura a travs de propiedades virtuales. Modificar la funcin PaintBoxPaint() de Ppal.cpp aadiendo esta lnea al principio:

if (Cir1->X < 0) Cir1->X = 100;

Observar que la propiedad virtual X se usa para lectura y escritura. La lnea anterior fija la coordenada X al valor 100. Un ejemplo ms clarificador es cambiar la lnea anterior por:

if (Cir1->X < 0) Cir1->X = -200;

Observar que el crculo negro tiene el valor 0 en la coordenada X: este valor se ha fijado a travs del mtodo de escritura SetX().

5.7. Polimorfismo

file:///D|/Manuales/intro/5.html (22 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

Es demostrar comportamientos distintos segn la situacin. Puede darse de tres formas diferentes:
q

Funciones: sobrecarga. Clases: es al que se refiere normalmente el concepto de polimorfismo. Enlace dinmico: mtodos virtuales.

5.7.1.Sobrecarga de funciones. Ocurre cuando en una clase existen dos mtodos con idntico nombre pero con distinta lista de parmetros. El compilador los considera como dos mtodos distintos y aplicar cada uno de ellos en la situacin apropiada. Por ejemplo, podra sobrecargarse el constructor de la clase TObjGraf aadiendo un nuevo constructor de copia: En ObjGraf.h:
TObjGraf (TObjGraf *ObjGraf);

En ObjGraf.cpp:
TObjGraf::TObjGraf (TObjGraf *ObjGraf) { PaintBox = ObjGraf->PaintBox; FColor = ObjGraf->Color; FX = ObjGraf->FX; FY = ObjGraf->FY; }

5.7.2. Polimorfismo en las clases y mtodos virtuales. Una clase se puede comportar como cualquiera de sus antecesoras (en la asignacin por ejemplo). Como tenemos variables (punteros) que pueden contener objetos de distintas clases, el compilador no sabe qu tipo de objeto es al que realmente apunta la variable (en tiempo de compilacin) por lo tanto hay retrasar el enlace a tiempo de ejecucin. El enlace dinmico es retrasar el enlace de una llamada a un mtodo (funcin) al tiempo de ejecucin. Para ilustrar el polimorfismo, crearemos una nueva clase, TPelota, que derive de la clase TCirculo. Una pelota (un objeto de tipo TPelota, para ser ms precisos) es un crculo que tiene la capacidad de

file:///D|/Manuales/intro/5.html (23 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

movimiento. Para implementar el movimiento de una pelota necesitamos incorporar nuevas propiedades y mtodos propios a la clase TPelota. Sin embargo, en este momento nos interesa poner de manifiesto el polimorfismo, lo que conseguimos a travs del mtodo Mostrar() asociado a la clase TPelota. Antes, modificamos la declaracin del mtodo Mostrar() de la clase TCirculo para obligar a sus descendientes a implementar su propio mtodo Mostrar(): basta con indicar que en el mtodo Mostrar() de la clase TCirculo es virtual. En ObjGraf.h:
//*************************************************/ // Definicion de la clase derivada TCirculo. // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { private: ... public: ... // Ahora, el metodo Mostrar() se declara virtual, aunque no es puro: // 1) Por ser virtual: cualquier clase que derive de TCirculo debe // tener su propio metodo Mostrar(), // 2) Por no ser puro: puede llamarse a este metodo con objetos TCirculo. virtual void Mostrar (void); ... };

Ahora nos centramos en la nueva clase TPelota. Antes, por comodidad y claridad, definimos un tipo por enumeracin para la direccin del movimiento: En ObjGraf.h:
// Tipo definido por enumeracion para la direccion de TPelota. Codificacion: /* NO 10 \ O 8 --/ 9 SO */ enum TDireccion {S=1, N=2, E=4, O=8, SE=5, NE=6, SO=9, NO=10}; N 2 | * | 1 S NE 6 / --- 4 E \ 5 SE

file:///D|/Manuales/intro/5.html (24 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

La declaracin de la clase TPelota se har en ObjGraf.h:


//*************************************************/ // Definicion de la clase derivada TPelota. // TPelota deriva de la clase TCirculo, que a su // vez deriva de la clase base TObjGraf //*************************************************/ class TPelota: public TCirculo { private: int FDirX; // Dir. en el eje X int FDirY; // Dir. en el eje Y int FVelocidad; // Velocidad del movimiento void TDireccion public: // Constructores TPelota (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1, TDireccion _Direccion=SE, int _Velocidad=5); // Otros metodos void Mostrar (void); void Borrar (void); void Mover (void); __property int Velocidad = {read = write= __property TDireccion Direccion = {read = write= }; FVelocidad, FVelocidad}; GetDireccion, SetDireccion}; SetDireccion (TDireccion _Direccion); GetDireccion (void);

La implementacin de los mtodos propios de la clase TPelota se har en ObjGraf.cpp:

/*****************************************************/ // Metodos asociados a la clase derivada TPelota. // TPelota deriva de la clase TCirculo, que a su // vez deriva de la clase base TObjGraf /*****************************************************/ TPelota :: TPelota (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Radio, TDireccion _Direccion, int _Velocidad) : TCirculo (_PaintBox, _Color, _X, _Y, _Radio) { Direccion = _Direccion; Velocidad = _Velocidad;
file:///D|/Manuales/intro/5.html (25 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

} // Instanciacion del metodo virtual puro de la clase TObjGraf // y virtual en TCirculo. void TPelota :: Mostrar (void) { PaintBox->Canvas->Pen->Color = clBlack; // Observar la diferencia PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } // Otras funciones propias de TPelota void TPelota :: Borrar (void) { PaintBox->Canvas->Pen->Color = PaintBox->Color; PaintBox->Canvas->Brush->Color = PaintBox->Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } void TPelota :: Mover (void) { Borrar (); X += FDirX * Velocidad; Y += FDirY * Velocidad; Mostrar (); } void TPelota :: SetDireccion (TDireccion _Dir) { FDirY = (_Dir & 1) ? +1 : ((_Dir & 2) ? -1 : 0); FDirX = (_Dir & 4) ? +1 : ((_Dir & 8) ? -1 : 0); } TDireccion TPelota :: GetDireccion (void) { TDireccion _Dir; _Dir = (TDireccion) ((FDirY == +1) ? 1 : ((FDirY == -1 ) ? 2 : 0)); _Dir = (TDireccion) (_Dir + (FDirX == +1) ? 4 : ((FDirX == -1 ) ? 8 :0)); return (_Dir); }

Finalmente, para ilustrar el polimorfismo nos basaremos en la existencia de diferentes mtodos con el mismo nombre: Mostrar(), que provocan diferentes acciones dependiendo del tipo de objetos al que se aplican. Vamos a crear dinmicamente cuatro objetos de diferentes clases. Estos objetos van a ser referenciados (mediante punteros) desde un vector de objetos de tipo TObjGraf *. El polimorfismo se va a manifestar invocando a la funcin Mostrar() para cada uno de esos objetos.

file:///D|/Manuales/intro/5.html (26 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

En Ppal.cpp declararemos la variable global:


TObjGraf **Objs;

que se interpreta como: Objs es un puntero a una zona de memoria que contendr punteros a objetos de tipo TObjGraf. As, en Ppal.cpp:
//---------------------------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Objs = new TObjGraf * [4]; Objs[0] Objs[1] Objs[2] Objs[3] } //---------------------------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { for (int i=0; i<4; i++) delete Objs[i]; delete []Objs; } //---------------------------------------------------------------------void __fastcall TPpalFrm::PaintBoxPaint(TObject *Sender) { for (int i=0; i<4; i++) Objs[i]->Mostrar(); } //---------------------------------------------------------------------= = = = new new new new TCirculo TCuadrado TCirculo TPelota (PaintBox, (PaintBox, (PaintBox, (PaintBox, clBlack, clRed, clGreen, clYellow, 100, 100, 30); 200, 150, 45); 210, 40, 20); 120, 70, 25);

// POLIMORFISMO

En este punto, el proyecto debe estar como se indica en el proyecto Ejemplo2. El resultado es el mostrado en la figura 5.6: Figura 5.6. Resultado del proyecto Ejemplo.bpr.

file:///D|/Manuales/intro/5.html (27 of 28) [27/02/2003 16:24:17]

Programacin Orientada a Objetos en C++

Pgina principal Francisco Cortijo Bon

file:///D|/Manuales/intro/5.html (28 of 28) [27/02/2003 16:24:17]

Tratamiento de excepciones

Curso de C++ Builder Tratamiento de excepciones

q q q q q

6.1. Lanzamiento de excepciones. 6.2. Especificacin de excepciones. 6.3. Captura de excepciones. 6.4. Excepciones no tratadas. 6.5. Excepciones de la VCL.

Las excepciones son situaciones anmalas que requieren un tratamiento especial. No tienen por qu ser errores!! Si se consigue dominar su programacin, la calidad de las aplicaciones que se desarrollen aumentar considerablemente. El funcionamiento general del mecanismo de lanzamiento y tratamiento de excepciones es el siguiente:
q q

Existe un mtodo que invoca la ejecucin de otro. Este mtodo ms interno se encuentra en una situacin que puede considerarse como excepcional. Por lo tanto lanza una excepcin. En este momento termina la ejecucin del mtodo ms interno y se retorna inmediatamente al mtodo llamador. El mtodo llamador debe capturar la excepcin y la trata. Parte del tratamiento de la excepcin puede ser volver a lanzarla al mtodo que invoc a este.

La correcta programacin de excepciones significa disear los algoritmos pensando nicamente en la forma habitual en la que deben ejecutarse, manejando las situaciones extraordinarias a parte. De esta manera se consigue un diseo mucho ms estructurado, legible, robusto y fcil de mantener.

Ejemplo. Cuando solicitamos memoria al sistema, lo habitual es que exista suficiente memoria disponible y no haya ningn problema. Pero si queremos realizar una aplicacin robusta deberemos de tener en cuenta la eventualidad de que dicha memoria no se conceda, lo cual complica enormemente un sencillo algoritmo. Veamos una funcin escrita en C que simplemente intenta asignar memoria dinmica para tres enteros:
void SinExcepciones (void) { int *p1, *p2, *p3;

file:///D|/Manuales/intro/6.html (1 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

p1 = (int*) malloc(sizeof(int)); if (p1 == NULL) { printf("No hay suficiente memoria"); abort(); } p2 = (int*) malloc(sizeof(int)); if (p2 == NULL) { printf("No hay suficiente memoria"); abort(); } p3 = (int*) malloc(sizeof(int)); if (p3 == NULL) { printf("No hay suficiente memoria"); abort(); } }

Si programamos en C++ y hacemos uso de las excepciones:


void ConExcepciones (void) { int *p1, *p2, *p3; try { p1 = new int; // Comportamiento normal. p2 = new int; p3 = new int; } catch(...){ // Comportamiento excepcional.

printf("No hay suficiente memoria"); abort(); } }

El ANSI C++ especifica que si una instruccin new falla (no hay memoria disponible) debe lanzar la excepcin bad_alloc (definida en el fichero de cabecera new). Las instrucciones que pueden provocar el lanzamiento de una excepcin (la "zona crtica") se encierran en un bloque try. Si alguna de las instrucciones del bloque try provocara una excepcin el flujo del programa se dirige al final de ese bloque, buscando un bloque catch que capture la excepcin (si no lo encontrara, el programa terminara -ver seccin 6.4-). En este caso, la instruccin catch(...) captura cualquier excepcin, y en particular, la excepcin bad_alloc. El tratamiento que se efecta es, en este caso, mostrar un mensaje de error y terminar la ejecucin del programa.

file:///D|/Manuales/intro/6.html (2 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

Ejemplo. El siguiente programa (proyecto Division) lee dos valores y calcula el cociente entre ambos. Si el divisor es cero, se intenta realizar una divisin por cero y el programa lanza una excepcin de divisin por cero (EZeroDivide).
//---------------------------------------------------------------#include <vcl.h> #pragma hdrstop //---------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { AnsiString Valor; float Dividendo, Divisor, Cociente; // Leer datos de entrada: dividendo y divisor Valor = InputBox ("Divisin", "Dividendo", ""); Dividendo = StrToFloat (Valor); Valor = InputBox ("Divisin", "Divisor", ""); Divisor = StrToFloat (Valor); // // // // Leer dividendo y convertirlo. Leer divisor y convertirlo.

// Calcular cociente. Zona critica: peligro si Divisor == 0 Cociente = Dividendo / Divisor; // Mostrar el resultado ShowMessage ("Cociente = " + AnsiString(Cociente)); return (0); } //----------------------------------------------------------------

Cuando se produce la excepcin, al no estar tratada por el programa, el entorno se hace cargo de ella y muestra la siguiente ventana: Figura 6.1. Ventana de error que surge debido a una excepcin EDivByZero no tratada.

Para proteger la instruccin crtica, recoger y tratar la excepcin, introducir la siguiente modificacin:
file:///D|/Manuales/intro/6.html (3 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

try { Cociente = Dividendo / Divisor; ShowMessage ("Cociente = " + AnsiString(Cociente)); } catch (...) { ShowMessage ("El divisor no puede ser cero."); }

Para ceder el control de la gestin de excepciones a nuestro programa debemos desabilitar la opcin por la que el entorno integrado gestiona las interrupciones e indicar que se van a gestionar por el programa: seleccionaremos Tools | Debuggber Options y abriremos la carpeta OS Exceptions para dejarla como se indica en la figura 6.2. Figura 6.2. Ventana Debugger Options

Con esto indicamos al depurador de C++ Builder que nuestro programa se encargar de manejar las excepciones C++ que ocurran. Ahora, al ejecutar el programa e intoducir el valor 0 como divisor se muestra la ventana mostrada en la figura 6.3 Figura 6.3. Ventana resultante de la gestin de la excepcin.

file:///D|/Manuales/intro/6.html (4 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

6.1. Lanzamiento de excepciones


El lanzamiento de una excepcin se realiza llamando a la funcin throw(). Cuando se lanza una excepcin, en realidad lo que se hace es crear un objeto de la clase que se le indique a throw(), y precisamente ser dicho objeto la excepcin en s. Suele ser muy til crear clases de excepciones propias para controlar las situaciones anmalas de nuestra aplicacin. Por ejemplo, En ObjGraf.h:
//*************************************************/ // Definicion de la clase EFueraRango // Clase de excepcion por entrar en "fuera de rango": // salirse de los limites del PaintBox al calcular // las nuevas coordenadas de dibujo de la pelota. //*************************************************/ class EFueraRango {};

Con lo que podramos lanzar una excepcin de la siguiente manera:


throw EfueraRango();

Nota: Aunque las excepciones sean clases, en C++ Builder existe la convencin de que su nombre empiece por la letra E, y no por T como el resto de las clases. Aunque en el ejemplo anterior la clase creada para la excepcin, no tiene ningn miembro (propiedades o mtodos), se le pueden aadir. stos servirn para poder incorporar informacin en el objeto excepcin, acerca de la situacin en la que se produjo la excepcin, que podr ser utilizada por la seccin de cdigo que lo trate. Por ejemplo, si tuvieramos un mtodo que lanzara una excepcin por falta de memoria, podra ser interesante que incorporara una propiedad que indicara cual era el mximo de memoria disponible cuando se lanz la excepcin.

6.2. Especificacin de excepciones


C++ cuenta con una caracterstica denominada especificacin de excepciones, que sirve para enumerar, en
file:///D|/Manuales/intro/6.html (5 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

una declaracin, las excepciones que puede lanzar un mtodo. Si queremos que un mtodo pueda lanzar un determinado tipo de excepcin deberemos especificarlo de esta manera. En ObjGraf.h, en la clase TObjGraf:
//*************************************************/ // Definicion de la clase base TObjGraf //*************************************************/ class TObjGraf { private: int FX; int FY; void SetX void SetY EFueraRango (int _X) throw (EFueraRango); // Si hay problemas,crean un (int _Y) throw (EFueraRango); // objeto de clase

virtual int GetAncho (void) = 0; // Metodo virtual puro virtual int GetAlto (void) = 0; // Metodo virtual puro ...

En ObjGraf.cpp:
// Funciones de escritura de las propiedades virtuales X e Y void TObjGraf :: SetX (int _X) throw (EFueraRango) { if (_X < 0) { // Coordenada negativa FX = 0; // Ajustar al margen izquierdo throw EFueraRango(); // Lanzar excepcion } else if (_X > (PaintBox->Width - Ancho)) { // Demasiado alta FX = PaintBox->Width - Ancho; // Ajustar al margen derecho throw EFueraRango(); // Lanzar excepcion } else FX = _X; // Correcto: escribir sin modificar } void TObjGraf :: SetY (int _Y) throw (EFueraRango) { if (_Y < 0) { // Coordenada negativa FY = 0; // Ajustar al margen superior throw EFueraRango(); // Lanzar excepcion } else if (_Y > (PaintBox->Height - Alto)) { // Demasiado alta FY = PaintBox->Height - Alto; // Ajustar al margen inferior throw EFueraRango(); // Lanzar excepcion

file:///D|/Manuales/intro/6.html (6 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

} else FY = _Y; // Correcto: escribir sin modificar }

6.3. Captura de excepciones


El bloque susceptible de producir alguna excepcin ("zona crtica") se encierra en un bloque try, la captura (discriminacin de la excepcin que se ha producido) se efecta en una instruccin catch y su procesamiento se realiza a continuacin, en el bloque catch. try { <bloque de instrucciones crticas> } catch (<tipo excepcin1> <variable1>) { <manejador 1> } catch (<tipo excepcin2> <variable2>) { ... } Podemos especificar tantos bloques catch para un bloque try como deseemos, en el momento que ocurra una excepcin se ejecutar el bloque catch cuya clase concuerde con la de la excepcin. Si se especifica catch (...) se capturar cualquier excepcin. La excepcin no tiene porqu lanzarse explcitamente en el bloque try sino que puede ser consecuencia de la ejecucin de una funcin que se ha llamado dentro de ese bloque. En ObjGraf.cpp:
void TPelota :: Mover (void) { Borrar (); try { X += FDirX * Velocidad; } catch (EFueraRango) { FDirX = -FDirX; }; try { Y += FDirY * Velocidad; } catch (EFueraRango) { FDirY = -FDirY; }; Mostrar (); }
file:///D|/Manuales/intro/6.html (7 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

En este ejemplo, la instruccin "crtica":


X += FDirX * Velocidad;

se traduce a:
X = X + FDirX * Velocidad;

y como X es una propiedad virtual, en realidad se trata de hacer:


SetX (FX + FDirX * Velocidad);

donde se observa que es el mtodo SetX() el que puede provocar el lanzamiento de la excepcin. En Ppal.cpp: 1. Dejar nicamente la siguiente declaracin global:
TPelota *Pelota;

2. Modificar las funciones FormCreate() y FormDestroy() para que queden:


//---------------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Pelota = new TPelota (PaintBox, clYellow, 120, 70, 25); } //---------------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { delete Pelota; }

3. Eliminar el manejador del evento OnPaint del componente PaintBox (borrando su cuerpo solamente). 4. Aadir a PpalFrm un TTimer (Carpeta System) y fijar Interval=100. En el evento OnTimer poner:
//---------------------------------------------------------void __fastcall TPpalFrm::Timer1Timer(TObject *Sender) { Pelota->Mover(); } //----------------------------------------------------------

NOTA: El entorno debe estar configurado para que el programa gestione las excepciones, no el entorno. Si no fuera s, seleccionar Tools | Debuggber Options, abrir la carpeta OS Exceptions y dejarla como se indica en
file:///D|/Manuales/intro/6.html (8 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

la figura 6.2.

En este punto, el proyecto debe estar como se indica en el proyecto Ejemplo3. El resultado es el mostrado en la figura 6.4: Figura 6.4. Dos instantes del movimiento de la pelota.

6.4. Excepciones no tratadas


Si una excepcin que ha sido lanzada no encuentra un manejador apropiado, se llamar a la funcin terminate(), la cual por defecto realiza un abort(). Pero se puede definir nuestra propia funcin terminate() con la orden set_terminate(). Algo muy parecido ocurre si un mtodo lanza una excepcin de un tipo que no tiene listado en su especificacin de excepciones, entonces se llama a la funcin unexpected() la cual por defecto llama a terminate(). Pero de igual manera que con terminate() podemos definir nuestra propia funcin unexpected() con set_unexpected().

6.5. Excepciones de la VCL


Si se utilizan componentes de la VCL en las aplicaciones, es necesario comprender el mecanismo de tratamiento de excepciones de la VCL. El motivo es que las excepciones estn integradas en numerosas clases y se lanzan automticamente cuando se presenta un situacin no esperada. Si no se realiza un tratamiento de la excepcin, la VCL llevar a cabo un tratamiento por defecto. Normalmente, aparece un mensaje que describe el tipo de error que se ha producido. 1. Clases de Excepciones. C++ Builder incorpora un extenso conjunto de clases de excepcin integradas que permiten tratar automticamente errores de divisin por cero, de E/S de archivos, de conversiones de tipos y otras
file:///D|/Manuales/intro/6.html (9 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

muchas situaciones anmalas. Todas las clases excepcin de VCL se derivan de un objeto raz denominado Exception, que encapsula las propiedades y mtodos fundamentales de todas las excepciones por parte de las aplicaciones. 2. Tratamiento de Excepciones de la VCL Las excepciones de tipo VCL, como todas las clases de la VCL deben de localizarse en el heap (creacin dinmica), por lo que se deber tener en cuenta lo siguiente:
r

Las clases de excepcin de tipo VCL solamente pueden capturarse por puntero o por referencia (preferible). Las excepciones de tipo VCL deben lanzarse con sintaxis "por valor".

Las excepciones pueden pasarse a un bloque catch que toma un parmetro de tipo Exception. Emplear la siguiente sintaxis para capturar las excepciones de la VCL:
catch (const exception_class & exception_variable)

Se especifica la clase de excepcin que se desea capturar y se proporciona una variable por medio de la cual hacer referencia a la excepcin. Por ejemplo,
//-------------------------------------------------------#include <vcl.h> #pragma hdrstop //-------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { throw Exception("Mi excepcin VCL"); } catch (const Exception & E) { ShowMessage("Clase de la excepcin capturada: " + AnsiString(E.ClassName()) + "\nMensaje: " + E.Message); } return (0); } //--------------------------------------------------------

La sentencia throw del ejemplo anterior crea una instancia de la clase Exception y llama a su constructor. Todas las excepciones que descienden de Exception cuentan con un mensaje que puede presentarse en pantalla, pasarse a los constructores y recuperarse mediante la propiedad Message. El resultado de la ejecucin del programa anterior es el mostrado en la figura 6.5 Figura 6.5. Ejemplo de lanzamiento y captura de excepcin VCL.

file:///D|/Manuales/intro/6.html (10 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

3. Clases de excepcin tpicas Aunque las excepciones no tienen porque indicar un error en la ejecucin de una aplicacin, las excepciones de la VCL si suelen ser errores. Veamos una seleccin de las clases de excepcin ms utilizadas en C++ Builder. Clase EAccessViolation EDatabaseError EDBEditError EDivByZero EZeroDivide EInOutError EInvalidPointer EPrinterError Descripcin Error de acceso a memoria. Especifica un error de acceso a base de datos. Datos incompatibles con una mscara especificada. Captura errores de divisin por cero (para divisin entera y real, respectivamente). Representa un error de E/S de archivo. Operaciones no vlidas con punteros. Indica un error de impresin.

Aunque todas estas clases funcionen de la misma manera, cada una de ellas tiene particularidades derivadas de la excepcin concreta que indican.

Ejemplo. El siguiente programa (proyecto Division2) es una ampliacin del proyecto Division. En ste se van a discriminar distintas excepciones, ms que capturar cualquier excepcin.
//--------------------------------------------------------------------#include <vcl.h> #pragma hdrstop //--------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {

file:///D|/Manuales/intro/6.html (11 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

AnsiString Valor; float Dividendo, Divisor, Cociente; float sigo = true; while (sigo) { try { // Leer dividendo y convertirlo Valor =InputBox ("Division", "Dividendo", ""); Dividendo = StrToFloat (Valor); if (Dividendo == 0) sigo = false; else { // Leer divisor y convertirlo Valor =InputBox ("Division", "Divisor", ""); Divisor = StrToFloat (Valor); Cociente = (Dividendo / Divisor); ShowMessage ("Cociente = " + AnsiString(Cociente)); } } // try // Se captura si se ha realizado una divisin por cero. catch (EZeroDivide & ) { ShowMessage ("El divisor no puede ser cero."); } // Ms general: se alcanza si no se captura la anterior. catch (Exception & e) { ShowMessage ("Se produjo una excepcin: "+AnsiString(e.ClassName())+ "\n " + e.Message); } } // while sigo return (0); } //---------------------------------------------------------------------

Si se intenta realizar una division por cero el resultado es el que se indica en la figura 6.6: Figura 6.6. Ejemplo de divisin por cero.

file:///D|/Manuales/intro/6.html (12 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

Si se introdujera un dato incorrecto, la funcin StrToFloat() lanzara una excepcin EConvertError que se captura con el ltimo bloque catch (ver figura 6.7). Figura 6.7. Ejemplo de entrada incorrecta.

Es ms, si se produjera algn tipo de desbordamiento tambin podra controlarse con el ltimo bloque catch (ver figura 6.8). Figura 6.8. Ejemplos de desbordamiento: A) En la entrada de datos y B) En el clculo del cociente.

file:///D|/Manuales/intro/6.html (13 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

Si quitramos el primer bloque catch podra capturarse la interrupcin EZeroDivide (ver figura 6.9). Figura 6.9. Otra manera de capturar la divisin por cero.

Para finalizar, si aadimos el siguiente bloque catch entre los dos anteriores:
catch (EMathError & e) { ShowMessage ("Operacin no vlida: " + e.Message); }
file:///D|/Manuales/intro/6.html (14 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

y consideramos (una parte de) la jerarqua de clases de excepciones:


TObject-->Exception-->EExternal-->EMathError-->(EZeroDivide, EOverflow, ...)

el alumno deber interpretar el resultado de la figura 6.10: Figura 6.10. Otra manera de capturar desbordamientos: A) En la entrada de datos y B) En el clculo del cociente.

EJERCICIO: Reproductor de sonidos.

file:///D|/Manuales/intro/6.html (15 of 16) [27/02/2003 16:24:19]

Tratamiento de excepciones

Pgina principal Francisco Cortijo Bon

file:///D|/Manuales/intro/6.html (16 of 16) [27/02/2003 16:24:19]

OOP - Ejemplo 3

Curso de C++ Builder Ejemplo 3


Corresponde al final de la seccin 7. En este ejemplo se muestra el tratamiento de excepciones para el movimiento de la pelota.

EJEMPLO.CPP
//----------------------------------------------------------------------

#include <vcl.h> #pragma hdrstop USERES("Ejemplo3.res"); USEFORM("Ppal.cpp", PpalFrm); USEUNIT("ObjGraf.cpp"); //---------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TPpalFrm), &PpalFrm); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } //----------------------------------------------------------------------

PPAL.H
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (1 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

//---------------------------------------------------------------------#ifndef PpalH #define PpalH //---------------------------------------------------------------------#include #include #include #include #include <Classes.hpp> <Controls.hpp> <StdCtrls.hpp> <Forms.hpp> <ExtCtrls.hpp>

#include "ObjGraf.h" #include <Buttons.hpp> //---------------------------------------------------------------------class TPpalFrm : public TForm { __published: // IDE-managed Components TPaintBox *PaintBox; TBitBtn *BotonSalir; TTimer *Timer1; void __fastcall FormCreate(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); void __fastcall BotonSalirClick(TObject *Sender); void __fastcall Timer1Timer(TObject *Sender); private: // User declarations

TPelota *Pelota; public: // User declarations __fastcall TPpalFrm(TComponent* Owner); }; //---------------------------------------------------------------------extern PACKAGE TPpalFrm *PpalFrm; //---------------------------------------------------------------------#endif

PPAL.CPP
//---------------------------------------------------------------------#include <vcl.h> #pragma hdrstop
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (2 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

#include "Ppal.h" //---------------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TPpalFrm *PpalFrm; //---------------------------------------------------------------------__fastcall TPpalFrm::TPpalFrm(TComponent* Owner) : TForm(Owner) { } //---------------------------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Pelota = new TPelota (PaintBox, clYellow, 120, 70, 25); } //---------------------------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { delete Pelota; } //---------------------------------------------------------------------void __fastcall TPpalFrm::BotonSalirClick(TObject *Sender) { Application->Terminate(); } //---------------------------------------------------------------------void __fastcall TPpalFrm::Timer1Timer(TObject *Sender) { Pelota->Mover(); } //----------------------------------------------------------------------

OBJGRAF.H
//---------------------------------------------------------------------#ifndef ObjGrafH #define ObjGrafH
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (3 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

//*************************************************/ // Definicion de la clase EFueraRango // Clase de excepcion por entrar en "fuera de rango": // salirse de los limites del PaintBox al calcular // las nuevas coordenadas de dibujo de la pelota. //*************************************************/ class EFueraRango {}; //*************************************************/ // Definicion de la clase base TObjGraf //*************************************************/ class TObjGraf { private: int FX; int FY; void SetX void SetY EFueraRango (int _X) throw (EFueraRango); // Si hay problemas,crean un (int _Y) throw (EFueraRango); // objeto de clase

virtual int GetAncho (void) = 0; // Metodo virtual puro virtual int GetAlto (void) = 0; // Metodo virtual puro protected: TColor TPaintBox public: // Constructores de objetos TObjGraf TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0); TObjGraf (TObjGraf *ObjGraf); FColor; *PaintBox;

// Otros metodos virtual void Mostrar (void) = 0; // Metodo virtual puro __property __property __property __property __property }; int int TColor int int X Y Color Ancho Alto = = = = = {read=FX, write=SetX }; {read=FY, write=SetY }; {read=FColor, write=FColor}; {read=GetAncho }; {read=GetAlto };

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (4 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

//*************************************************/ // Definicion de la clase derivada TCirculo. // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { private: int FRadio; inline int GetAncho inline int GetAlto public: // Constructores TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1); // Otros metodos void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf __property int Radio = }; {read=FRadio, write=FRadio}; (void) {return(FRadio*2);} (void) {return(FRadio*2);}

//*************************************************/ // Definicion de la clase derivada TPelota. // TPelota deriva de la clase TCirculo, que a su // vez deriva de la clase base TObjGraf //*************************************************/ enum TDireccion {S=1, N=2, E=4, O=8, SE=5, NE=6, SO=9, NO=10}; /* Tipo definido por enumeracion para la direccion de TPelota La codificacion es:

NO 10 \ \ O 8 ---/ / 9 SO */

N 2 | | | | 1 S

NE 6 / / ---- 4 E \ \ 5 SE

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (5 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

class TPelota: public TCirculo { private: int FDirX; int FDirY; int FVelocidad; void TDireccion public : // Constructores TPelota (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1, TDireccion _Direccion=SE, int _Velocidad=5); // Otros metodos void Mostrar (void); void Borrar (void); void Mover (void); __property int Velocidad = {read = FVelocidad, write=FVelocidad}; __property TDireccion Direccion = {read = GetDireccion, write=SetDireccion}; }; SetDireccion (TDireccion _Direccion); GetDireccion (void);

//*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf { private: int FLado; inline int GetAncho inline int GetAlto public: // Constructores TCuadrado (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Lado=1); // Otros metodos (void) {return(FLado);} (void) {return(FLado);}

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (6 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf __property int Lado = }; //---------------------------------------------------------------------#endif {read=FLado, write=FLado};

OBJGRAF.CPP
//---------------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "ObjGraf.h" //---------------------------------------------------------------------#pragma package(smart_init) /*****************************************************/ // Metodos asociados a la clase base TObjGraf /*****************************************************/ // Constructores TObjGraf :: TObjGraf (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y) { PaintBox = _PaintBox; FColor = _Color; FX = _X; FY = _Y; } TObjGraf :: TObjGraf (TObjGraf *ObjGraf) { PaintBox = ObjGraf->PaintBox; FColor = ObjGraf->Color; FX = ObjGraf->FX; FY = ObjGraf->FY; } // Funciones de escritura de las propiedades virtuales X e Y void TObjGraf :: SetX (int _X) throw (EFueraRango)
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (7 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

{ if (_X < 0) { FX = 0; throw EFueraRango(); } else if (_X > (PaintBox->Width - Ancho)) { FX = PaintBox->Width - Ancho; throw EFueraRango(); } else FX = _X; }

void TObjGraf :: SetY (int _Y) throw (EFueraRango) { if (_Y < 0) { FY = 0; throw EFueraRango(); } else if (_Y > (PaintBox->Height - Alto)) { FY = PaintBox->Height - Alto; throw EFueraRango(); } else FY = _Y; } /*****************************************************/ // Metodos asociados a la clase derivada TCirculo. // TCirculo deriva de la clase base TObjGraf. /*****************************************************/ TCirculo :: TCirculo (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Radio) : TObjGraf (_PaintBox, _Color, _X, _Y) { Radio = _Radio; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCirculo :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); }

/*****************************************************/

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (8 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

// Metodos asociados a la clase derivada TPelota. // TPelota deriva de la clase TCirculo, que a su // vez deriva de la clase base TObjGraf /*****************************************************/ TPelota :: TPelota (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Radio, TDireccion _Direccion, int _Velocidad) : TCirculo (_PaintBox, _Color, _X, _Y, _Radio) { Direccion = _Direccion; Velocidad = _Velocidad; }

// Instanciacion del metodo virtual puro de la clase TObjGraf void TPelota :: Mostrar (void) { PaintBox->Canvas->Pen->Color = clBlack; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } // Otras funcione propias de TPelota void TPelota :: Borrar (void) { PaintBox->Canvas->Pen->Color = clBtnFace; // PaintBox->Color; PaintBox->Canvas->Brush->Color = clBtnFace; //PaintBox->Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } void TPelota :: Mover (void) { Borrar (); try { X += FDirX * Velocidad; } catch (EFueraRango) { FDirX = -FDirX; }; try { Y += FDirY * Velocidad; } catch (EFueraRango) { FDirY = -FDirY; }; Mostrar (); }

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (9 of 10) [27/02/2003 16:24:20]

OOP - Ejemplo 3

void TPelota :: SetDireccion (TDireccion _Dir) { FDirY = (_Dir & 1) ? +1 : ((_Dir & 2) ? -1 : 0); FDirX = (_Dir & 4) ? +1 : ((_Dir & 8) ? -1 : 0); } TDireccion TPelota :: GetDireccion (void) { TDireccion _Dir; _Dir = (TDireccion) ((FDirY == +1) ? 1 : ((FDirY == -1 ) ? 2 : 0)); _Dir = (TDireccion) (_Dir + (FDirX == +1) ? 4 :((FDirX == -1 )? 8:0)); return (_Dir); }

/*****************************************************/ // Metodos asociados a la clase derivada TCuadrado. // TCuadrado deriva de la clase base TObjGraf. /*****************************************************/ TCuadrado :: TCuadrado (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Lado) : TObjGraf (_PaintBox, _Color, _X, _Y) { Lado = _Lado; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCuadrado :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Rectangle(X, Y, X+Lado, Y+Lado); }

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo3.html (10 of 10) [27/02/2003 16:24:20]

Ejemplos - Sonidos

Curso de C++ Builder Sonidos

En este ejemplo se crar un formulario que contendr un componente MediaPlayer que servir para reproducir ficheros .WAV. Utilizaremos la gestin de excepciones para controlar la correcta ejecucin del programa. 1. Crear y configurar el proyecto. Para ms informacin, pinchar el siguiente enlace:

En primer lugar, crear el directorio Sonidos. y, si procede, una nueva aplicacin ( File | New Application). Guardar proyecto: Salvar Unit1.cpp como Ppal.cpp y Project1.bpr como Sonidos.bpr

2. Configurar el formulario. Configurar el formulario para que tenga el aspecto mostrado en la figura siguiente:

Cambiar el ttulo (Caption por Sonidos) y aadir los siguientes componentes: 1. Cuatro botones normales (Button) llamados (Name): LogoffBtn, MSSoundBtn, ErrorBtn y OtrosBtn con el texto (Caption) indicado en la figura anterior. 2. Un botn BitBtn para terminar. 3. Un control MediaPlayer (pestaa System) no visible (Visible=false).
file:///D|/Manuales/intro/ejemplos/Sonidos/index.html (1 of 4) [27/02/2003 16:24:20]

Ejemplos - Sonidos

4. Un cuadro de dilogo OpenDialog (pestaa Dialogs).

3. Escribir los gestores de eventos asociados a la pulsacin de los botones. La gestin de las interrupciones capturadas se realiza con una funcin comn cuyo prototipo es:
void Error (AnsiString & name, Exception & e);

que se escribir por encima de todas las funciones de Ppal.cpp. As, los gestores de los eventos OnClick asociados a los botones sern los siguientes:
//-------------------------------------------------------------void __fastcall TForm1::LogoffBtnClick(TObject *Sender) { MediaPlayer1->FileName = "C:\\WINDOWS\\MEDIA\\Logoff.wav"; try { MediaPlayer1->Open(); MediaPlayer1->Wait = true; MediaPlayer1->Play(); MediaPlayer1->Close(); } catch (Exception & e) { Error (MediaPlayer1->FileName, e); } } //-------------------------------------------------------------void __fastcall TForm1::MSSoundBtnClick(TObject *Sender) { MediaPlayer1->FileName = "C:\\WINDOWS\\MEDIA\\The Microsoft Sound.wav"; try { MediaPlayer1->Open(); MediaPlayer1->Wait = true; MediaPlayer1->Play(); MediaPlayer1->Close(); } catch (Exception & e) { Error (MediaPlayer1->FileName, e); } } //-------------------------------------------------------------void __fastcall TForm1::ErrorBtnClick(TObject *Sender) { MediaPlayer1->FileName = "C:\\WINDOWS\\MEDIA\\NoEsta.wav"; try { MediaPlayer1->Open(); MediaPlayer1->Wait = true; MediaPlayer1->Play();
file:///D|/Manuales/intro/ejemplos/Sonidos/index.html (2 of 4) [27/02/2003 16:24:20]

Ejemplos - Sonidos

MediaPlayer1->Close(); } catch (Exception & e) { Error (MediaPlayer1->FileName, e); } } //-------------------------------------------------------------void __fastcall TForm1::OtrosBtnClick(TObject *Sender) { OpenDialog1->Title = "Abrir un fichero de sonido"; OpenDialog1->Filter = "Ficheros de sonido (*.wav) | *.WAV"; OpenDialog1->InitialDir = "C:\\WINDOWS"; if (OpenDialog1->Execute()) { MediaPlayer1->FileName = OpenDialog1->FileName; try { MediaPlayer1->Open(); MediaPlayer1->Wait = true; MediaPlayer1->Play(); MediaPlayer1->Close(); } catch (Exception & e) { Error (MediaPlayer1->FileName, e); } } // if (OpenDialog1->Execute()) } //-------------------------------------------------------------void Error (AnsiString & name, Exception & e) { ShowMessage ("Fallo en la reproduccin del fichero de sonido: " + name + "\nExcepcin: " + AnsiString(e.ClassName()) + "\nDetalles: " + AnsiString(e.Message)); } //--------------------------------------------------------------

Cuando se ejecuta este programa, si se pulsa en el botn Error (se supone que el fichero de sonido que se quiere reproducir no existe) aparece la siguiente ventana:

En cambio, si se quiere reproducir un fichero cuyo formato no sea .wav aparece la siguiente ventana:

file:///D|/Manuales/intro/ejemplos/Sonidos/index.html (3 of 4) [27/02/2003 16:24:20]

Ejemplos - Sonidos

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/Sonidos/index.html (4 of 4) [27/02/2003 16:24:20]

C++ Builder

Curso de C++ Builder Programacin con Hebras


Introduccin
q

Por qu usar hebras?

La clase TThread
q q q

Creacin de hebras Liberacin de hebras Prioridad de una hebra

Ejecucin de hebras
q q q

El mtodo Execute() Variables locales a las hebras Control de la ejecucin de una hebra: Suspend, Resume & Terminate

Coordinacin entre hebras


q

Uso de recursos compartidos


r r r

La hebra principal de la VCL Bloqueo de objetos Secciones crticas

Sincronizacin entre hebras


r

Esperar la finalizacin de una hebra

file:///D|/Manuales/threads/index.html (1 of 2) [27/02/2003 16:24:20]

C++ Builder

Esperar a que se complete una tarea

Ejemplos

Pgina principal Fernando Berzal Galiano

file:///D|/Manuales/threads/index.html (2 of 2) [27/02/2003 16:24:20]

C++ Builder

Curso de C++ Builder Programacin con Hebras


Introduccin

Una aplicacin multihebra es una aplicacin que contiene varas vas simultneas de ejecucin. Consideraciones:
q q q q

Cada hebra supone una carga adicional al sistema. El diseo de aplicaciones multihebra es complejo. La depuracin de las aplicaciones es difcil. Las hebras han de coordinarse de algn modo.

Por qu usar Hebras?


El uso de hebras (de paralelismo, en general) proporciona una serie de ventajas frente a las limitaciones de los sistemas monotarea. Ejemplo: Supongamos que nuestra aplicacin tiene que ocuparse de la realizacin de copias de seguridad de los datos con los que trabaja. Con una nica hebra tendramos que programar las copias de seguridad fuera del horario habitual de trabajo (y si tiene que funcionar las 24 horas del da?). Con varias hebras, podemos aprovechar los perodos de inactividad del sistema. Aprovechamiento de los recursos del sistema Cuando se utiliza una sola hebra, el programa debe detener completamente la ejecucin mientras espera a que se realice cada tarea. La CPU permanece ocupada
file:///D|/Manuales/threads/introduction.html (1 of 2) [27/02/2003 16:24:21]

C++ Builder

completamente (o inactiva) hasta que el proceso actual termine. Si se utilizan varias hebras, el sistema puede usarse para realizar varias tareas simultneamente (vg: reproduccin de MP3s en background). Establecimiento de prioridades Como es lgico, se le asigna mayor prioridad a las tareas ms importantes (vg: las que requieran una respuesta ms rpida). Multiprocesamiento real En un sistema multiprocesador, si la aplicacin se descompone en varias hebras, el sistema operativo podr asignar cada una a una de las CPUs del sistema.

Estructuracin: Paralelismo implcito En muchas ocasiones, un programa puede disearse como varios procesos paralelos que funcionen de forma independiente. La descomposicin de una aplicacin en varias hebras puede resultar muy beneficiosa en trminos de desacoplamiento de cdigo (tareas independientes se implementan por separado) y de calidad del diseo (frente a futuras ampliaciones, por ejemplo). IMPORTANTE: El objetivo principal del uso de hebras es mejorar el rendimiento del sistema. El diseador/programador deber decidir hasta qu punto deben utilizarse.

Fernando Berzal Galiano

file:///D|/Manuales/threads/introduction.html (2 of 2) [27/02/2003 16:24:21]

C++ Builder

Curso de C++ Builder Programacin con Hebras


La clase TThread

C++ Builder proporciona la clase abstracta TThread para la creacin de hebras. Para definir una hebra se debe crear un descendiente de TThread, para lo cual se ha de crear una clase derivada de TThread. Para facilitar el trabajo, C++Builder incluye un asistente que lo hace por nosotros. Ejemplo: Crear una hebra Abrimos el repositorio en su pgina New (al que se accede desde la opcin del men File->New...). Seleccionamos el elemento Thread Object. Denominamos THebraPelota a la clase derivada de TThread. Ya hemos creado nuestra primera hebra en una unidad independiente (que almacenaremos en los ficheros HPelota.cpp y HPelota.h). La clase TThread es abstracta porque posee un mtodo virtual puro denominado Execute(), que ser el que rellenemos con el cdigo asociado a la hebra. Como sucede con cualquier otra clase, en una clase derivada de TThread se pueden aadir todos los miembros (propiedades y mtodos) que se necesiten. Obligatoriamente slo hay que implementar:
q

El constructor de la clase (que nos permitir definir la inicializacin de la hebra) El mtodo Execute (la funcin main() de la hebra, que contendr el cdigo asociado a la tarea que tenga que realizar la hebra).

file:///D|/Manuales/threads/TThread.html (1 of 4) [27/02/2003 16:24:21]

C++ Builder

Inicializacin de las hebras


La inicializacin de una hebra se realiza en su constructor, donde se establecen los valores iniciales de cuantas propiedades sean necesarias. Antes de invocar al constructor de una clase derivada de TThread, se invoca al constructor de su clase base (TThread): __fastcall TThread(bool CreateSuspended); ste recibe como parmetro false si deseamos que la hebra se ejecute inmediatamente despus de ser creada o true si queremos que quede suspendida inicialmente. Dos caractersticas de las hebras conviene establecerlas en el constructor: su prioridad y cundo debe liberarse la hebra.

Asignacin de una Prioridad por Defecto


La prioridad de una hebra indica qu grado de preferencia tiene la hebra cuando el sistema operativo reparte el tiempo de CPU entre las distintas hebras que se estn ejecutando en el sistema. Para indicar la prioridad del objeto de hebra hay que fijar el valor de la propiedad Priority: Valor Prioridad tpIdle Se ejecuta cuando el sistema est inactivo. tpLowest Dos puntos por debajo del valor normal. tpLower Un punto por debajo del valor normal. tpNormal La hebra tiene la prioridad normal. tpHigher Un punto por encima del valor normal. tpHighest Dos puntos por encima del valor normal. tpTimeCritical La hebra tiene la prioridad ms alta. Si se aumenta mucho la prioridad de una hebra que requiera muchos recursos (vg: CPU) puede ocurrir que las dems hebras de la aplicacin (y del sistema) no lleguen a procesarse a la velocidad adecuada. Ejemplo:
file:///D|/Manuales/threads/TThread.html (2 of 4) [27/02/2003 16:24:21]

C++ Builder

Si tenemos un proceso que consume una cantidad considerable de tiempo de CPU, puede ser interesante dar la posibilidad al usuario de cancelar el proceso durante su ejecucin. Esto se puede conseguir creando una hebra con prioridad normal para ese proceso y otra hebra de alta prioridad que nicamente est a la espera de que el usuario pulse un botn de cancelacin. La hebra de alta prioridad no consumir tiempo de CPU porque estar bloqueada pero, en el caso de que el usuario pulse el botn, responder rpidamente.

Liberacin de las hebras


A menudo las hebras de una aplicacin se ejecutan una sola vez. Si este es el caso, lo ms sencillo es dejar que el objeto hebra se libere a s mismo, estableciendo la propiedad FreeOnTerminate a true. Sin embargo, hay casos en que el objeto hebra representa una tarea que debe realizarse varias veces. Si la aplicacin requiere varias instancias del mismo objeto hebra (para ejecutar la hebra varias veces), se puede aumentar el rendimiento de la aplicacin almacenando las hebras en una cach para utilizarlas ms adelante, en lugar de destruirlas y crearlas de nuevo cada vez. Para ello, basta con fijar el valor de la propiedad FreeOnTerminate a false. En este caso, ser responsabilidad del programador la liberacin de la hebra. MUY IMPORTANTE: Antes de liberar una hebra hay que asegurarse de que no se est ejecutando (ya veremos cmo). Ejemplo:
q

En HPelota.h:

#include "ObjGraf.h"

En la clase THebraPelota:
... public: TPelota *Pelota; __fastcall THebraPelota(TPaintBox *PaintBox);
file:///D|/Manuales/threads/TThread.html (3 of 4) [27/02/2003 16:24:21]

C++ Builder

__fastcall ~THebraPelota(void); ...


q

En HPelota.cpp:

#include <stdlib.h> ... __fastcall THebraPelota::THebraPelota (TPaintBox *PaintBox) : TThread(false) { Priority = tpNormal; FreeOnTerminate = true; Pelota = new TPelota ( // Objeto pelota... PaintBox, // ...aletorio. (TColor)(random(0xFF) | (random(0xFF)*0x100) | (random(0xFF)*0x10000)), random(PaintBox->Width), random(PaintBox->Height), random(20)+1, TDireccion((random(2)+1) | (random(2)+1)*4)); } __fastcall THebraPelota::~THebraPelota(void) { delete Pelota; }

Fernando Berzal Galiano

file:///D|/Manuales/threads/TThread.html (4 of 4) [27/02/2003 16:24:21]

C++ Builder

Curso de C++ Builder Programacin con Hebras


Ejecucin de las hebras

El mtodo Execute es la funcin principal de una hebra. Una hebra puede concebirse como un programa que se ejecuta dentro de la aplicacin. Una hebra no es un programa independiente porque comparte el mismo espacio con las dems hebras de la aplicacin. Por tanto, es necesario asegurarse de no escribir en la memoria que utilizan las otras hebras. Por otro lado, puede utilizarse la memoria compartida entre las hebras para establecer una comunicacin entre ellas. Ejemplo:
q

En HPelota.cpp:

void __fastcall THebraPelota::Execute() { while (true) { // Cdigo de la Hebra. Pelota->Mover(); Sleep(100); } }

Variables locales a las hebras


Con la palabra clave __thread podemos definir variables globales que son locales a una hebra. Habr una copia de la variable para cada una de las hebras que se creen: la variable es global para las funciones de una hebra pero no se comparte con otras hebras. Ejemplo:

file:///D|/Manuales/threads/execution.html (1 of 4) [27/02/2003 16:24:21]

C++ Builder

int __thread x;

Las variables __thread han de ser estticas (no pueden ser punteros) y no pueden inicializarse en tiempo de ejecucin). No es aconsejable utilizar este tipo de variables, ya que se puede conseguir lo mismo aadiendo una variable de instancia a la clase de la hebra.

Control de la ejecucin de una hebra


Una hebra puede encontrarse en dos estados:
q q

Ejecutndose. Suspendida.

Las hebras pueden iniciarse y suspenderse tantas veces como sea necesario antes de que finalice su ejecucin. Para detener una hebra temporalmente hay que realizar una llamada al mtodo Suspend(). Cuando resulte conveniente reanudar la ejecucin de la hebra se debe realizar una llamada al mtodo Resume(). Suspend() y Resume() utilizan un contador interno, de forma que es posible anidar las llamadas a Suspend() y Resume(). La hebra no reanuda su ejecucin hasta que todas las suspensiones hayan tenido su correspondiente llamada a Resume(). La ejecucin de una hebra termina normalmente cuando termina la ejecucin del mtodo Execute(). Para hacer que la ejecucin de una hebra finalice de forma prematura hay realizar una llamada al mtodo Terminate(). Terminate() cambia el valor de la propiedad Terminated a true, indicando as que la hebra ha de finalizar su ejecucin en cuanto sea posible. Por tanto, el mtodo Execute() ha de comprobar peridicamente el valor de la propiedad Terminated y detener la ejecucin de la hebra cuando est a true. Ejemplo:

file:///D|/Manuales/threads/execution.html (2 of 4) [27/02/2003 16:24:21]

C++ Builder

En HPelota.cpp:

void __fastcall THebraPelota::Execute() { while (!Terminated) { // Cdigo de la Hebra. Pelota->Mover(); Sleep(100); } }

Cuando se crea una hebra, el estado inicial de sta depender del parmetro que se le pase a su constructor: ejecutndose (false) o suspendida (true). Si se crea una hebra inicialmente suspendida se ha de invocar al mtodo Resume() para comenzar su ejecucin. Ejemplo:
q

En Ppal.h: Para usar la unidad HPelota desde un formulario:


#include "HPelota.h" ... private: // User declarations THebraPelota **Objs; ...

En Ppal.cpp:

#include <stdlib.h> ... void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Objs = new THebraPelota*[4]; randomize(); for (int i=0; i<4; ++i) Objs[i] = new THebraPelota (PaintBox);

file:///D|/Manuales/threads/execution.html (3 of 4) [27/02/2003 16:24:21]

C++ Builder

} void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { for (int i=0; i<4; ++i) Objs[i]->Terminate(); Sleep(3000); // Esperar tres segundos... // ...a que se liberen todas las hebras delete[] Objs; }

Nota: La sentencia Sleep(3000), es una chapuza para evitar que se cuelgue la aplicacin al liberar las hebras (ms adelante veremos como solucionar este problema correctamente).

Fernando Berzal Galiano

file:///D|/Manuales/threads/execution.html (4 of 4) [27/02/2003 16:24:21]

C++ Builder

Curso de C++ Builder Programacin con Hebras


Coordinacin entre hebras

El cdigo ejecutado por una hebra debe tener en cuenta la posible existencia de otras hebras que se ejecuten concurrentemente. Hay que tener cuidado para evitar que dos hebras accedan a un recurso compartido (vg: objeto o variable global) al mismo tiempo. Adems, la ejecucin de una hebra puede depender del resultado de las tareas que realicen en otras hebras. Por tanto, las distintas hebras de una aplicacin han de coordinar su ejecucin.

Uso de recursos compartidos


Cuando varias hebras comparten el uso de un recurso, pueden ocurrir situaciones no deseadas si dos o ms hebras acceden (o intentan acceder) al mismo recurso simultneamente. Para evitar conflictos con otras hebras, puede que se necesite bloquear la ejecucin de otras hebras al acceder a objetos o variables compartidas. Hay que tener cuidado de no bloquear innecesariamente la ejecucin de otras hebras (para no disminuir el rendimiento de la aplicacin). Ejemplo: Si ejecutamos el ejemplo anterior, aunque el funcionamiento de la aplicacin es correcto, la visualizacin en el PaintBox sufre algunos errores de forma aleatoria. Esto se debe a que los mtodos Mostrar() y Borrar() de las distintas hebras se entrelazan en el acceso al Canvas del PaintBox. Se ha de evitar el acceso simultneo de las hebras al componente Canvas del PaintBox!.

La hebra principal de la VCL


No existe garanta alguna (en general) de que los mtodos de los componentes de C++ Builder funcionen correctamente cuando son compartidos por varias hebras. Es decir, al acceder a propiedades o ejecutar mtodos pueden efectuarse algunas operaciones que utilicen memoria no protegida de las acciones de otras hebras.
file:///D|/Manuales/threads/coordination.html (1 of 6) [27/02/2003 16:24:22]

C++ Builder

Por este motivo se reserva una hebra, la hebra principal de la VCL, para el acceso a los objetos de la VCL. sta es la hebra que gestiona todos los mensajes de Windows que reciben los componentes de la aplicacin. Si todos los objetos acceden a sus propiedades e invocan a sus mtodos dentro de una nica hebra, no hay por qu preocuparse. Para usar la hebra VCL principal hay que crear un mtodo que realice las acciones necesarias y llamarlo utilizando el mtodo Synchronize(). Ejemplo:
q

En ObjGraf.h y en ObjGraf.cpp: El mtodo Synchronize() recibe cmo parmetro un mtodo del tipo void __fastcall <mtodo> (void), por lo que hay que cambiar la definicin del mtodo Mover() de TPelota:
void __fastcall Mover (void);

En HPelota.cpp:

void __fastcall THebraPelota::Execute() { while (!Terminated) { Synchronize(Pelota->Mover); Sleep(100); } }

No siempre es necesario utilizar la hebra VCL principal (de hecho, en algunos casos no se puede usar y tendremos que emplear otros mecanismos como las secciones crticas). Algunos componentes estn preparados para funcionar con hebras (son thread-safe) y no hay necesidad de usar el mtodo Synchronize(). Esto permite aumentar el rendimiento de la aplicacin porque no es necesario esperar a que la hebra VCL principal entre en su bucle de mensajes (y, adems, no bloqueamos esta hebra). Los componentes de acceso a datos funcionan correctamente con hebras si pertenecen a distintas sesiones (con la excepcin de los controladores de Access, que utilizan la biblioteca ADO).

file:///D|/Manuales/threads/coordination.html (2 of 6) [27/02/2003 16:24:22]

C++ Builder
q

Los objetos grficos funcionan correctamente con hebras. No se necesita utilizar la hebra VCL principal acceder a TFont, TPen, TBrush, TBitmap, TMetafile ni TIcon. Para compartir el uso de objetos lienzo (TCanvas y descendientes) hay que bloquearlos antes. Algunos componentes (por ejemplo, TList) tienen una versin adecuada para funcionar con varias hebras (TThreadList).

Bloqueo de objetos
Algunos componentes cuentan con mecanismos de bloqueo para que puedan compartirse por varias hebras. Por ejemplo, los objetos de tipo lienzo (TCanvas y sus descendientes) cuentan con un mtodo Lock() que impide a las otras hebras acceder al objeto hasta que se realiza una llamada al mtodo Unlock(). En el caso de TThreadList, una llamada a TThreadList::LockList() devuelve el objeto de tipo TList asociado e impide que otras hebras accedan a la lista hasta que se realice una llamada a UnlockList(). Las llamadas a los mtodos TCanvas::Lock o TThreadList::LockList pueden anidarse con seguridad. El desbloqueo no se produce hasta que se haya realizado una llamada de desbloqueo por cada llamada de bloqueo. Ejemplo:
q

En HPelota.cpp: Eliminar la llamada al mtodo Synchronize() realizada desde el mtodo THebraPelota::Execute().

En ObjGraf.cpp: Tanto en TPelota::Mostrar() como en TPelota::Borrar():


PaintBox->Canvas->Lock(); ... PaintBox->Canvas->Unlock();

Secciones crticas
Si un objeto no cuenta con mecanismos de bloqueo incorporados, siempre se puede utilizar una seccin crtica. Las secciones crticas funcionan como puertas que permiten el paso de una sola hebra cada vez. Para utilizar una seccin crtica hay que crear una instancia global de
file:///D|/Manuales/threads/coordination.html (3 of 6) [27/02/2003 16:24:22]

C++ Builder

TCriticalSection. TCriticalSection cuenta con dos mtodos: Acquire() (que impide a otras hebras acceder a la seccin crtica) y Release() (que elimina el bloqueo). Cada seccin crtica se asocia a un recurso que se desea compartir por varias hebras. Todas las hebras que accedan a un mismo recurso debern utilizar el mtodo Acquire() de la correspondiente seccin crtica para asegurarse de que el recurso no est siendo utilizado por ninguna otra hebra. Al finalizar sus operaciones, las hebras tienen que realizar una llamada al mtodo Release() para que las dems hebras puedan acceder al recurso invocando al mtodo Acquire(). Si se omite la llamada a Release() el recurso quedara bloqueado para siempre. Ejemplo:
q

En ObjGraf.cpp:

#include <syncobjs.hpp> TCriticalSection *SC = new TCriticalSection(); // Habra que destruirla!!! ...

En TPelota::Mostrar() y en TPelota::Borrar(), eliminar el bloqueo del objeto de tipo TCanvas y emplear en su lugar la seccin crtica:
{ SC->Acquire(); ... SC->Release(); }

Sincronizacin entre hebras


Puede que las distintas hebras de una aplicacin realicen tareas que no sean completamente independientes, por lo cual ser necesario que en ciertas ocasiones una hebra espere a que otra termine la ejecucin de una accin determinada.

file:///D|/Manuales/threads/coordination.html (4 of 6) [27/02/2003 16:24:22]

C++ Builder

Ejemplo: Tenemos que dos hebras que calculan el total de ingresos y el total de gastos de una compaa respectivamente. Una tercera hebra ha de obtener el balance final, por lo que deber esperar a que las dos hebras anteriores terminen su trabajo.

Esperar la finalizacin de una hebra


Para esperar a que finalice la ejecucin de otra hebra, se puede utilizar el mtodo WaitFor() de la otra hebra. WaitFor() bloquea la ejecucin de la hebra actual hasta que la otra hebra se haya cerrado, ya sea por haber finalizando la ejecucin de su mtodo Execute() o por haberse producido una excepcin. WaitFor() devuelve un valor entero que es el valor de la propiedad ReturnValue de la hebra. La propiedad ReturnValue puede cambiarse en el mtodo Execute() y su significado se lo daremos nosotros. Ejemplo:
q

En Ppal.cpp:

void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { int i; for (i=0; i<4; i++) Objs[i]->Terminate(); for (i=0; i<4; i++) Objs[i]->WaitFor(); delete[] Objs; }

Esperar a que se complete una tarea: Sucesos


En algunas ocasiones es necesario esperar a que otra hebra haya realizado una tarea determinada sin que ello implique que haya finalizado su ejecucin. En estos casos hay que utilizar un objeto de tipo suceso (TEvent).

file:///D|/Manuales/threads/coordination.html (5 of 6) [27/02/2003 16:24:22]

C++ Builder

Cuando una hebra completa una operacin de la que dependen otras hebras, realiza una llamada a TEvent::SetEvent(). SetEvent() activa una seal que cualquier otra hebra puede detectar invocando al mtodo TEvent::WaitFor(). Para desactivar esa seal existe el mtodo TEvent::ResetEvent(). El mtodo WaitFor() espera un tiempo determinado (establecido en milisegundos al llamar al mtodo) hasta que se active la seal. WaitFor() puede devolver uno de los siguientes valores: Valor Significado wrSignaled La seal asociada al suceso se ha activado. wrTimeout Ha transcurrido el tiempo especificado sin que la seal se activase. wrAbandoned El objeto de tipo TEvent se destruy antes de que se llegase al time-out. Se ha producido un error durante la espera. El cdigo del error concreto se wrError puede obtener de la propiedad TEvent::LastError. Si se desea seguir a la espera de un suceso indefinidamente puede pasar el valor INFINITE como parmetro del mtodo WaitFor(). Pero tenga cuidado, la hebra se quedar bloqueada para siempre si nunca llegara a producirse el evento que espera. NOTA: El componente TEvent no es ms que un wrapper de un evento de Windows.

Fernando Berzal Galiano

file:///D|/Manuales/threads/coordination.html (6 of 6) [27/02/2003 16:24:22]

Acceso a bases de datos

Curso de C++ Builder Acceso a bases de datos


Introduccin
q q q

Bases de datos locales Bases de datos cliente/servidor Arquitecturas multicapa

El motor de bases de datos de Borland (BDE)


q

Configuracin del driver para InterBase

Componentes de acceso a bases de datos


q q

El asistente para formularios de bases de datos Bases de datos de demostracin

Controles de acceso a datos


q q q

Bases de datos con fechas Rejillas Pistas y trucos

El componente TDataSource
file:///D|/Manuales/databases/index.html (1 of 3) [27/02/2003 16:24:22]

Acceso a bases de datos

TDataLink: Componentes "data-aware"

Conjuntos de datos
q q q q q q q

TDataSet y sus derivados Cursores Actualizaciones en cach El componente TTable: Tablas El componente TQuery: Consultas SQL El componente TStoredProc: Procedimientos almacenados El componente TField: Acceso a los campos

Sesiones y conexiones
q q

El componente TSession El componente TDatabase

Herramientas y utilidades
q q q q q

BDE Administrator Database Desktop SQL Explorer SQL Monitor Datapump

Ejemplos y ejercicios
q q q

Un componente 'data-aware': TDBDateTimePicker Un formulario: Un dilogo de bsqueda genrico Una aplicacin sencilla (Paradox): Gestin de una pequea base de datos culinaria Una aplicacin algo ms compleja (InterBase): Diccionario de citas Ejercicio: Desarrollo completo de una aplicacin

Apndice: SQL
file:///D|/Manuales/databases/index.html (2 of 3) [27/02/2003 16:24:22]

Acceso a bases de datos

Pgina principal Fernando Berzal Galiano

file:///D|/Manuales/databases/index.html (3 of 3) [27/02/2003 16:24:22]

C++ Builder

Curso de C++ Builder Acceso a Bases de Datos


Acceso a bases de datos relacionales

La mayora de las aplicaciones de gestin requieren el acceso a bases de datos. C++ Builder incluye componentes que facilitan enormemente el desarrollo de aplicaciones que interactan con bases de datos. Usualmente trabajaremos con bases de datos relacionales (bases de datos constituidas por tablas). Antes de seguir, definamos dos conceptos bsicos:
q

Cursor: Un indicador del registro que se est insertando, modificando o consultando en una tabla relacional, entendiendo sta en su sentido ms amplio (una tabla de la base de datos o la tabla resultado de una consulta). Conjunto de Datos [Dataset]: Una coleccin de datos obtenido de una base de datos. Un dataset puede ser algo ms que los datos incluidos en una tabla; podra ser el resultado de una consulta que contenga datos provenientes de ms de una tabla.

Bases de Datos Locales


El modelo ms sencillo de aplicacin que accede a bases de datos es aqul en el cual se accede a bases de datos locales, tambin denominadas bases de datos de escritorio La base de datos reside en una sola mquina (generalmente la misma en la que se ejecuta la aplicacin), y slo puede tener acceso a la misma un nico usuario. Ejemplos de este modelo son dBase, Paradox, Approach o Access.

Bases de Datos Cliente/Servidor


En este caso, un gestor de bases de datos (DBMS) mantiene la base de datos. El
file:///D|/Manuales/databases/introduction.html (1 of 2) [27/02/2003 16:24:23]

C++ Builder

almacenamiento y gestin del acceso a los datos los realiza el gestor (el servidor). Los gestores de bases de datos relacionales tambin se conocen como servidores SQL, por ser ste el lenguaje que se utiliza para acceder a los datos. Oracle, IBM DB2, InterBase y SQL Server entran dentro de esta categora. Las aplicaciones de los usuarios (los clientes) hacen peticiones al servidor utilizando algn protocolo predefinido, CLI [Call-Level-Interface] en ingls, que puede ser un estndar (ODBC, JDBC o BDE) o especfico de la base de datos que utilicemos. Como es lgico, varios usuarios situados en distintos puestos de trabajo de una red pueden compartir el mismo servidor SQL, que ser el responsable de mantener la "acidez" de las transacciones [Atomicity-Consistency-Isolation-Durability].

Arquitecturas multicapa
q

Las aplicaciones que acceden a bases de datos locales corresponden a una arquitectura de una sola capa: las aplicaciones conectan directamente con la base de datos. El modelo cliente/servidor corresponde a una arquitectura con dos capas: el servidor SQL por un lado y las aplicaciones que se conectan como clientes del servidor por otro. Tambin existen arquitecturas multicapa con ms de dos capas: las aplicaciones se conectan a servidores de aplicaciones, que son los que acceden a los servidores de bases de datos. En este caso se suele hacer uso de middleware: CORBA, DCOM, DataSnap (=MIDAS)...

Fernando Berzal Galiano

file:///D|/Manuales/databases/introduction.html (2 of 2) [27/02/2003 16:24:23]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


BDE

El Motor de Bases de Datos de Borland


Para permitir el acceso a bases de datos locales y servidores SQL, C++ Builder proporciona el Borland Database Engine (BDE), que no es ms que una coleccin de DLLs. El BDE es un CLI [Call-Level Interface] que hace de intermediario entre las aplicaciones y las bases de datos a las que se accede, de forma que stas sean independientes de la base de datos que se utilice.

El BDE necesita un "alias" para acceder a una base de datos particular. Un alias de BDE establece el conjunto de parmetros que se requieren para establecer una conexin con una base de datos, tales como el controlador [driver] empleado y la localizacin de la base de datos. Los alias se definen con ayuda del BDE Administrator (que se encuentra en el Panel de Control de Windows). Ejemplo

file:///D|/Manuales/databases/bde.html (1 of 3) [27/02/2003 16:24:23]

C++ Builder

Crear una aplicacin nueva. Guardar el proyecto con el nombre BDEje, y el formulario con el nombre Ppal.cpp. q Aadir un componente TTable (en la pgina Data Access) al formulario. q Ver qu valores se pueden seleccionar para la propiedad DataBaseName, los alias BDE disponibles en la mquina.
q

Configuracin del driver para InterBase


q

ENABLE BCD para poder trabajar con nmeros decimales con una precisin especificada (si no hay que utilizar datos de tipo entero o real!!). ENABLE SCHEMA CACHE ahorra tiempo y ancho de banda:
r r r r

ENABLE SCHEMA CACHE = TRUE SCHEMA CACHE DIR = ... (destino de scache.ini & *.scf) SCHEMA CACHE SIZE = 32 SCHEMA CACHE TIME = -1

DRIVER FLAGS = 4608


r

4092: isc_commit_retaining (para confirmar las transacciones implcitas) + COMMIT RETAIN = TRUE para transacciones explcitas. 512: Nivel de aislamiento superior para las transacciones implcitas (lecturas repetibles). NOTA: El nivel de lecturas repetibles no es adecuado para las aplicaciones que tienen que estar pendientes de las actualizaciones realizadas en otros puestos.

WAIT ON LOCKS: Esperar a que un registro est disponible? Uso de TCP/IP como protocolo de comunicacin con el servidor (de forma que no hace falta instalar el cliente y las utilidades de administracin de InterBase en todos los puestos):
r

Aadir la entrada "gds_db 3050/tcp" al fichero services de Windows (subdirectorio system32\drivers\etc)

Alias (parmetro SERVER NAME):

file:///D|/Manuales/databases/bde.html (2 of 3) [27/02/2003 16:24:23]

C++ Builder

r r

NetBEUI: //host/db TCP/IP: host:/db

Fernando Berzal Galiano

file:///D|/Manuales/databases/bde.html (3 of 3) [27/02/2003 16:24:23]

C++ Builder

Curso de C++ Builder Acceso a Bases de Datos


Componentes de acceso a Bases de Datos

Los componentes de la VCL para el acceso a bases de datos se dividen en categoras siguiendo el modelo MVC (Model-View-Controller):
q

Controles de acceso a datos (visuales). Conjuntos de datos (no visuales). El componente TDataSource (enlace entre los anteriores)

El asistente
Aunque podemos crear nuestras aplicaciones de bases de datos directamente a partir de los componentes de bases de datos, C++ Builder nos ofrece un "potente" asistente para generar formularios sencillos que accedan a bases de datos. Para utilizar el asistente hay que seguir los siguientes pasos: 1. Llamar al asistente como si fusemos a aadir a nuestro proyecto un formulario ms (con "File/New..."), seleccionando "Database Form Wizard" de la pestaa "Business":

file:///D|/Manuales/databases/components.html (1 of 16) [27/02/2003 16:24:25]

C++ Builder

Tambin se puede llamar al asistente directamente desde la opcin Form Wizard del men Database. 2. Seleccionar el tipo de formulario que deseemos (simple o maestro/detalle) y cmo queremos generarlo (mediante tablas o consultas). Para comenzar, optaremos por un formulario simple construido con una tabla (TTable):

3. Seleccionamos la tabla a la cual deseamos acceder. En este caso, seleccionamos la base de datos de
file:///D|/Manuales/databases/components.html (2 of 16) [27/02/2003 16:24:25]

C++ Builder

demostracin que aparece bajo el alias de BCDEMOS y, dentro de ella, la tabla BIOLIFE.DB:

4. Una vez seleccionada la tabla, hemos de indicar qu campos incluiremos en nuestro formulario. Seleccionamos todos (>>) menos la longitud en pulgadas, LENGTH_IN (<):

5. Ahora podemos escoger la disposicin de los controles en el formulario: horizontal, vertical o en una rejilla. Probaremos inicialmente con la disposicin horizontal de los controles en el formulario.

file:///D|/Manuales/databases/components.html (3 of 16) [27/02/2003 16:24:25]

C++ Builder

6. Finalmente, le indicamos al asistente que cree un formulario acompaado por un mdulo de datos independiente (para separar los objetos que modelizan los conjuntos de datos de los controles que constituyen la vista de esos conjuntos de datos):

7. El resultado obtenido es el siguiente:

file:///D|/Manuales/databases/components.html (4 of 16) [27/02/2003 16:24:25]

C++ Builder

El formulario de la imagen est bien aunque an necesita algunos retoques. Por ejemplo, los campos de tipo MEMO (textos) o BLOB (imagen en el ejemplo) no deben mostrarse en una simple caja de edicin. Por desgracia, al indicarle al asistente que pusiese los campos horizontalmente, ha puesto todos los campos de la tabla como si se pudiesen editar con un simple TDBEdit.

Disposicin vertical de los controles


5. Para evitar el error que se produca anteriormente (el uso indiscriminado de cajas de edicin incluso para las imgenes), podemos optar por disponer los campos verticalmente (tal como se hace desde tiempos del dBase):

6. Hemos de indicar, adems, si queremos que las etiquetas que indican los nombres de los campos aparezcan a la izquierda o encima de los controles que nos permiten editarlos. Seleccionamos la primera de las opciones:
file:///D|/Manuales/databases/components.html (5 of 16) [27/02/2003 16:24:25]

C++ Builder

7. Como en el ejemplo anterior, le indicamos al asistente que cree un formulario acompaado por un mdulo de datos independiente:

8. ... y el resultado que obtenemos es el siguiente:

file:///D|/Manuales/databases/components.html (6 of 16) [27/02/2003 16:24:25]

C++ Builder

Este formulario est algo mejor que el inicial y, para que se vea correctamente la imagen, slo hemos de poner a true la propiedad Stretch del control que nos la muestra (el nico TDBImage del formulario) y ajustar un poco el tamao de los distintos controles.

Formularios maestro/detalle
Utilicemos ahora el asistente para algo un poco ms complejo: 1. Creamos ahora un formulario maestro/detalle (master/detail) con objetos de tipo TTable para modelizar los conjuntos de datos:

file:///D|/Manuales/databases/components.html (7 of 16) [27/02/2003 16:24:25]

C++ Builder

2. Seleccionamos la tabla CLIENTS.DBF de la base de datos BCDEMOS como tabla maestra del formulario, una tabla que contiene informacin acerca de los clientes de una empresa:

3. Escogemos los campos que nos interese mostrar y los ordenamos utilizando los botones que aparecen debajo de la lista de campos seleccionados:

file:///D|/Manuales/databases/components.html (8 of 16) [27/02/2003 16:24:25]

C++ Builder

4. Indicamos que los campo de la tabla maestro los dispondremos verticalmente (para evitar que nos pase lo de antes con las imgenes y los textos):

file:///D|/Manuales/databases/components.html (9 of 16) [27/02/2003 16:24:25]

C++ Builder

5. Seleccionamos la tabla detalle, que ser la tabla HOLDINGS.DBF de la base de datos BCDEMOS (tabla que contiene las inversiones en bolsa de nuestros clientes):

6. Escogemos todos sus campos:

file:///D|/Manuales/databases/components.html (10 of 16) [27/02/2003 16:24:25]

C++ Builder

7. Y seleccionamos una rejilla para visualizarlos ya que, usualmente, las tablas detalle siempre se muestran en rejillas:

8. Para completar nuestro formulario maestro/detalle hemos de especificar cmo se reliza la reunin entre las tablas CLIENTS.DBF y HOLDINGS.DBF, a travs del ndice existente sobre la columna ACCT_NBR:

file:///D|/Manuales/databases/components.html (11 of 16) [27/02/2003 16:24:25]

C++ Builder

9. Como siempre, le indicamos al asistente que cree un formulario acompaado por un mdulo de datos independiente:

file:///D|/Manuales/databases/components.html (12 of 16) [27/02/2003 16:24:25]

C++ Builder

10. Voil! Ya tenemos listo un formulario maestro/detalle y, con unos cuantos retoques, la presentacin ser la adecuada para incluirlo en alguna de nuestras aplicaciones:

file:///D|/Manuales/databases/components.html (13 of 16) [27/02/2003 16:24:25]

C++ Builder

Ejercicios prcticos q Tipo del Formulario: maestro/detalle con objetos TTable. q Tabla maestra: Alias BCDEMOS, tabla customer.db. q Campos de la tabla maestra: CustNo, Company, Addr1, City, State, Country, Phone (en ese orden). q Disposicin de los campos de la tabla maestra: Horizontally. q Tabla detalle: Alias BCDEMOS, tabla orders.db. q Campos de la tabla detalle: CustNo, OrderNo, SaleDate, TaxRate, ItemsTotal (en ese orden). q Disposicin de los campos de la tabla detalle: In a Grid. q Definir la reunin (join) seleccionando el ndice CustNo: join CustNo -> CustNo.

q q q

Tipo del Formulario: maestro/detalle con objetos TTable. Tabla maestra: Alias BCDEMOS, tabla employee.db. Tabla detalle: Alias BCDEMOS, tabla orders.db. Tipo del Formulario: maestro/detalle con objetos TTable. Tabla maestra: Alias BCDEMOS, tabla orders.db. Tabla detalle: Alias BCDEMOS, tabla items.db. Tipo del Formulario: maestro/detalle con objetos TTable. Tabla maestra: Alias BCDEMOS, tabla vendors.db. Tabla detalle: Alias BCDEMOS, tabla parts.db. Tipo del Formulario: maestro/detalle con objetos TTable. Tabla maestra: Alias BCDEMOS, tabla event.db. Tabla detalle: Alias BCDEMOS, tabla reservat.db. Tipo del Formulario: maestro/detalle con objetos TTable. Tabla maestra: Alias BCDEMOS, tabla industry.db. Tabla detalle: Alias BCDEMOS, tabla master.db. Tipo del Formulario: maestro/detalle con objetos TTable. Tabla maestra: Alias BCDEMOS, tabla master.db. Tabla detalle: Alias BCDEMOS, tabla holdings.db.

q q q

q q q

q q q

q q q

q q q

Limitaciones del asistente


Como hemos visto, el asistente nos permite crear rpidamente formularios que nos permiten gestionar conjuntos de datos. No obstante, cualquier aplicacin real requerir formularios ms complejos que los vistos hasta ahora y tendremos que olvidarnos del asistente y crearlos nosotros mismos. Ejercicios para los cuales el asistente se queda corto

file:///D|/Manuales/databases/components.html (14 of 16) [27/02/2003 16:24:25]

C++ Builder

Mostrar la relacin entre los lugares en que se celebran actividades (venues.db) y los clientes que acuden a cada recinto (custoly.db). Cada evento (event.db) tiene un lugar de celebracin (venues.db) y una serie de reservas (reservat.db) realizadas por clientes (custoly.db). Mostrar los pedidos de cada cliente (orders.db como detalle de customer.db) indicando los detalles de los pedidos (items.db) y el proveedor de cada peza (relacin entre items.db y parts.db, que adems est relacionada con vendors.db). Mostrar las inversiones de los clientes (relacin entre holdings.dbf y clients.dbf) indicando el nombre de las empresas en las que se invierte (almacenado en master.dbf), no slo su smbolo. Mostrar el total de inversiones (holdings.dbf) de cada cliente (clients.dbf) o el importe total de lo que ha ganado cada proveedor (vendors.db) con los pedidos realizados hasta el momento (orders.db).

Bases de datos de demostracin


Base de datos de inversiones en bolsa

Base de datos de reserva de entradas

Base de datos de pedidos

file:///D|/Manuales/databases/components.html (15 of 16) [27/02/2003 16:24:25]

C++ Builder

NOTA: Las tablas ANIMALS.DBF, BIOLIFE.DB y COUNTRY.DB completan el conjunto de bases de datos incluidas como ejemplo en la distribucin del C++Builder.

Fernando Berzal Galiano

file:///D|/Manuales/databases/components.html (16 of 16) [27/02/2003 16:24:25]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


Controles de acceso a datos

Todos ellos tienen un control homlogo estndar en la paleta de componentes. Se diferencian de los controles estndar en que estn enlazados a datos (son componentes data-aware). Dicho enlace se establece mediante un DataSource. Estos componentes trabajan con los datos seleccionados por las propiedades DataSource y, en su caso, DataField: Propiedad DataSource DataField Descripcin Indica el datasource del que se obtienen y al que se envan los datos. Es el campo o columna del datasource al que accede cada control.

A continuacin, presentaremos los distintos controles de datos del C++ Builder Controles orientados a conjuntos de datos Control Descripcin Rejilla de datos: Muestra un DataSource con aspecto de tabla. Mediante la TDBGrid propiedad Columns se pueden especificar qu campos del conjunto de datos se pueden ver en la rejilla y cules son sus propiedades. Rejilla que permite incluir controles: Como un TDBGrid, aunque cada fila es en TDBCtrlGrid realidad un panel en el que se pueden colocar controles de datos "replicables". Control de navegacin: Sirve para controlar el cursor, as como la insercin, edicin y borrado de datos. La propiedad VisibleButtons se utiliza para TDBNavigator seleccionar qu botones podr pulsar el usuario. Por su parte, la propiedad Hints permite especificar mensajes de ayuda para cada botn (que habr que traducir). Permite construir grficos a partir de un conjunto de datos. La propiedad TDBChart SeriesList se emplea para seleccionar qu datos deseamos representar y cmo Controles orientados a campos Control Descripcin Como el componente estndar TLabel, pero enlazado a datos. Muestra el valor de TDBText un campo, el cual no se puede editar. Igual que las etiquetas normales, no consume recursos en Windows. TDBEdit Presenta un cuadro de edicin para un campo concreto. Anlogo a TEdit.

file:///D|/Manuales/databases/controls.html (1 of 6) [27/02/2003 16:24:25]

C++ Builder

TDBMemo

Caja de edicin con mltiples lneas. Ideal para textos sin formato. Se emplea en campos que slo permiten dos valores diferentes. Con las propiedades ValueChecked y ValueUnchecked se establecen listas de valores para TDBCheckBox que el TDBCheckBox est activado o desactivado. Dichas listas se especifican mediante una serie de valores separados por punto y coma. Se utiliza para campos que slo permiten varios valores. En la propiedad Items se TDBRadioGroup fijan los identificadores que el usuario ve en el grupo de botones. En la propiedad Values se indican los valores que en realidad se almacenan en la base de datos. Establece una lista de posibles valores para un campo. En la propiedad Items se TDBListBox fijan los valores permitidos, que son fijos. TComboBox enlazado a datos. Igual que en el control TDBListBox, las distintas TDBComboBox posibilidades se colocan en la propiedad Items. Ideal para claves externas: Como TDBListBox, aunque la lista de valores permitidos no la establece el programador. Los valores de la lista se obtienen a partir de los valores de un campo de otro conjunto de datos. El DataSource que se TDBLookupListBox consulta se establece con la propiedad ListSource. El campo que se muestra en la lista de valores viene dado por la propiedad ListField. La propiedad KeyField indica el campo cuyos valores se almacenan en la base de datos. TDBLookupComboBox Igual que TDBLookupListBox, aunque la lista aparece como un TComboBox. Igual que TDBMemo, con la capacidad adicional de dar formato al texto del TDBRichEdit campo (en formato RTF). Para mostrar imgenes contenidas en una base de datos (en formato BMP o TDBImage WMF). El comportamiento de todos los controles anteriores ante modificaciones se puede alterar con las propiedades AutoEdit y ReadOnly.

Bases de datos con fechas


Se puede adaptar TDateTimePicker (pgina Win32 de la paleta de componentes) para que funcione con un TDataSource especificando sus eventos OnStateChange, OnDataChange y OnUpdateData. Tambin es necesario personalizar el evento OnExit del componente TDateTimePicker. Ejemplo class TFormDate : public TForm { ... private: bool FCambiando; ... };
void __fastcall TFormDate::DataSourceDataChange(TObject *Sender, TField *Field) { if (! FCambiando) try { FCambiando = True;
file:///D|/Manuales/databases/controls.html (2 of 6) [27/02/2003 16:24:25]

C++ Builder

DateTimePicker->DateTime = Table->FieldValues["HireDate"]; } __finally { FCambiando = False; } } void __fastcall TFormDate::DataSourceUpdateData(TObject *Sender) { Table->FieldValues["HireDate"] = DateTimePicker->DateTime; } void __fastcall TFormDate::DateTimePickerChange(TObject *Sender) { if (! FCambiando) try { FCambiando = True; DataSource->Edit(); } __finally { FCambiando = False; } } void __fastcall TFormDate::DateTimePickerExit(TObject *Sender) { Table->UpdateRecord(); }

Uso de rejillas
La tecla 'Insert' permite aadir tuplas, mientras que la combinacin 'Control+Supr' se utiliza para eliminarlas. Por defectro, aparece un mensaje en ingls que se puede personalizar interceptando el evento BeforeDelete del conjunto de datos asociado: Ejemplo de personalizacin de los mensajes mostrados al usuario void __fastcall ...::TableBeforeDelete(TDataSet *DataSet) { if ( MessageDlg ( "Desea eliminar la tupla actual?", mtConfirmation, TMsgDlgButtons()<<mbYes<<mbNo, 0) != mrYes ) Abort(); }

Interceptando el evento OnDrawColumnCell se puede personalizar la presentacin de las celdas: cambiar el color, el tipo de letra e incluso mostrar imgenes o checkboxes sin tener que recurrir al componente TDBCtrlGrid. Personalizacin del color de un campo determinado (segn el cumplimiento de alguna condicin)

file:///D|/Manuales/databases/controls.html (3 of 6) [27/02/2003 16:24:25]

C++ Builder

void __fastcall TFormXXX::DBGridDrawColumnCell (TObject *Sender, const TRect Rect, int DataCol, TColumn *TColumn, TGridDrawState State) { TDBGrid *grid = static_cast<TDBGrid*>(Sender); if (tbParts->FieldValues["OnOrder"] >= tbParts->FieldValues["OnHand"]) grid->Canvas->Font->Color = clRed; grid->DefaultDrawColumnCell(Rect, DataCol, Column, State); }

Propiedades del tipo de letra void __fastcall TFormXXX::DBGridDrawColumnCell (TObject *Sender, const TRect& Rect, int DataCol, TColumn *Column, TGridDrawState State) { TDBGrid *grid = static_cast<TDBGrid*>(Sender); TFontStyles FS;
switch case case case } (grid->DataSource->DataSet->UpdateStatus()) { usModified: FS << fsBold; break; usInserted: FS << fsItalic; break; usDeleted: FS << fsStrikeOut; break;

grid->Canvas->Font->Style = FS; grid->DefaultDrawColumnCell(Rect, DataCol, Column, State); }

Imgenes en vez de texto void __fastcall TFormXXX::DBGridDrawColumnCell (TObject *Sender, const TRect Rect, int DataCol, TColumn *TColumn, TGridDrawState State) { TDBGrid *grid = static_cast<TDBGrid*>(Sender);
if (Column->FieldName != "") grid->DefaultDrawColumnCell(Rect, DataCol, Column, State); else if (tbEmpleados->FieldValues["Salary"] >= 150000) grid->Canvas->StretchDraw(Rect, CaraAlegre->Picture->Graphic); else grid->Canvas->StretchDraw(Rect, CaraTriste->Picture->Graphic); }

CheckBoxes (aunque es ms cmodo y flexible utilizar TDBCtrlGrid)

file:///D|/Manuales/databases/controls.html (4 of 6) [27/02/2003 16:24:25]

C++ Builder

void __fastcall TFormXXX::DBGridDrawColumnCell (TObject *Sender, const TRect Rect, int DataCol, TColumn *TColumn, TGridDrawState State) { if (CompareText(Column->FieldName, "ACTIVO") == 0) { UINT check = 0; if (Table1->FieldValues["ACTIVO"]) check = DFCS_CHECKED; DBGrid->Canvas->FillRect(Rect); DrawFrameControl(DBGrid1->Canvas->Handle, (RECT*) &Rect, DFC_BUTTON, DFCS_BUTTONCHECK | check); } else DBGrid->DefaultDrawColumnCell(Rect, DataCol, Column, State); }

Podemos seleccionar la columna por la que se ordenan los datos usando la propiedad IndexFieldNames del conjunto de datos. Esta propiedad la podemos establecer dinmicamente como respuesta al evento OnTitleClick. Ordenacin dinmica de un conjunto de datos void __fastcall TFormXXX::DBGridTitleClick(TColumn *Column) { try { if (Column->Field->FieldKind == fkLookup) Table->IndexFieldNames = Column->Field->KeyFields; else Table->IndexFieldNames = Column->FieldName; } catch(Exception&) { } }

Pistas y trucos
q

BARRAS DE NAVEGACIN: Para que siempre se realice un "Append" (al final) en lugar de "Insert" (antes de la fila activa) cuando aadimos nuevos datos (pulsando la tecla Insert), se puede responder al evento OnBeforeAction del TDBNavigator de la siguiente forma: Append en vez de Insert

file:///D|/Manuales/databases/controls.html (5 of 6) [27/02/2003 16:24:25]

C++ Builder

void __fastcall TFormXXX::DBNavigatorBeforeAction(TObject *Sender,TNavigateBtn Button) { if (Button==nbInsert) { static_cast<TDBNavigator*>(Sender)->DataSource->DataSet->Append(); SysUtils::Abort(); } }

Durante el diseo de formularios podemos arrastrar campos desde el editor de campos del conjunto de datos sobre el que estemos trabajando. De esta forma se aade automticamente un TDBEdit acompaado por una etiqueta TLabel (con su propiedad FocusControl apuntando al TDBEdit).

Fernando Berzal Galiano

file:///D|/Manuales/databases/controls.html (6 of 6) [27/02/2003 16:24:25]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


TDataSet

Conjuntos de datos
TDataSet es la clase superior de la jerarqua de clases definida en C++Builder para definir conjuntos de datos. TTable, TQuery y TStoredProc son casos particulares de conjuntos de datos. De hecho, la mayora de las propiedades, mtodos y eventos que se utilizan en estas clases estn definidas realmente en TDataSet, en TBDEDataSet o en TDBDataSet:

Propiedades
Propiedad Active Bof CachedUpdates CanModify DataSource DatabaseName Eof Descripcin Abre el conjunto de datos cuando se establece a true y lo cierra cuando se fija a false. Devuelve true si el cursor est en el primer registro del conjunto de datos. Cuando est a true, las actualizaciones se mantienen en la cach de la mquina del cliente hasta que el programador los enve al servidor. Cuando est a false, todos los cambios realizador en los conjuntos de datos se pasan automticamente a la base de datos. Determina si el usuario puede editar el conjunto de datos o no. El componente TDataSource asociado. El nombre de la base de datos con la que se est trabajando. Devuelve true cuando el cursor est llega al final del conjunto de datos.

file:///D|/Manuales/databases/tdataset.html (1 of 8) [27/02/2003 16:24:26]

C++ Builder

FieldCount Fields FieldValues Found Modified RecNo RecordCount State UpdatesPending

Es el nmero de columnas o campos del conjunto de datos. Columnas del conjunto de datos: array de objetos de tipo TField. Devuelve el valor de un campo especificado en el registro actual. Indica si una operacin de bsqueda ha tenido xito o no. Indica si el registro actual ha sido modificado. El nmero de registro actual en el dataset. Devuelve el nmero de registros en el dataset. Devuelve el estado actual del conjunto de datos. Cuando est a true, el buffer del conjunto de datos contiene modificaciones de los datos que an no han sido enviadas a la base de datos.

Estados

vg: Post graba una nueva fila si el estado es dsInsert, actualiza la actual si es dsEdit

Mtodos
Mtodo Append() AppendRecord() ApplyUpdates() Cancel() CancelUpdates() ClearFields() Descripcin Crea un registro vaco y lo aade al final del conjunto de datos. Aade un registro especificado al final del conjunto de datos. Enva a la base de datos cualquier actualizacin en cach que estuviese pendiente. La escritura no se realiza realmente hasta que se invoca al mtodo CommitUpdates(). Cancela cualquier modificacin en el registro actual si no ha sido enviada con Post(). Cancela cualquier actualizacin en cach que estuviese pendiente. Vaca el contenido de todos los campos del registro actual.

file:///D|/Manuales/databases/tdataset.html (2 of 8) [27/02/2003 16:24:26]

C++ Builder

CommitUpdates() Close() Delete() DisableControls() Edit() EnableControls() FetchAll() FieldByName() First() GetFieldNames() Insert() InsertRecord() Last() Locate() Lookup() MoveBy() Next() Open() Post() Prior() Refresh() RevertRecord() SetFields() UpdateStatus()

Se indica a la base de datos que realice las actualizaciones que estaban en cach y se vaca el buffer de actualizaciones en cach. Cierra el conjunto de datos. Elimina el registro actual. Desactiva los controles de datos asociados al conjunto de datos (muy til para evitar el parpadeo de los controles visuales). Permite la edicin del registro actual. Activa los controles de datos asociados al conjunto de datos. Obtiene todos los registros desde la posicin actual del cursor hasta el final del conjunto de datos y los almacena localmente. Devuelve un campo TField dado su nombre. Mueve el cursor al primer registro. Recupera la lista con los nombres de los campos del conjunto de datos. Inserta un registro en blanco y pone el conjunto de datos en modo de edicin. Inserta un registro en el conjunto de datos con los datos que se le indiquen y los enva con Post(). Sita el cursor en el ltimo registro. Bsqueda de un registro en particular. Localiza un registro por el medio ms rpido posible y devuelve el dato contenido en el mismo (se usan ndices si es posible). Mueve el cursor un nmero determinado de filas. Mueve el cursor al siguiente registro. Abre el conjunto de datos. Escribe los datos modificados de un registro en el conjunto de datos (los enva a la base de datos o al buffer de actualizaciones en cach). Mueve el cursor al registro anterior. Actualiza el contenido del registro actual leyndolo de la base de datos. Cuando se utiliza la cach, este mtodo ignora los cambios hechos previamente que todava no han sido enviados a la base de datos. Establece los valores para todos los campos de un registro. Devuelve el estado actual cuando las actualizaciones en cach se activan.

Eventos
Evento AfterCancel AfterClose AfterDelete AfterEdit AfterInsert AfterOpen
file:///D|/Manuales/databases/tdataset.html (3 of 8) [27/02/2003 16:24:26]

Descripcin (cundo se genera?) Despus de cancelar las modificaciones. Cuando se cierra un conjunto de datos Despus de que un registro se haya eliminado. Despus de que se ha modificado un registro. Despus de insertar un registro. Despus de abrir un conjunto de datos.

C++ Builder

AfterPost BeforeCancel BeforeClose BeforeDelete BeforeEdit BeforeInsert BeforeOpen BeforePost OnDeleteError OnEditError OnNewRecord OnPostError OnUpdateError OnUpdateRecord EJEMPLOS DE USO DE EVENTOS

Despus de enviar los cambios de un registro. Antes de que se cancelen los cambios. Antes de que se cierre un conjunto de datos. Antes de eliminar un registro. Antes de entrar en modo edicin. Antes de que se inserte un registro. Antes de abrir el conjunto de datos. Antes de enviar las modificaciones. Cuando ocurre algn error al eliminar una tupla. Cuando ocurre algn error al editar una tupla. Siempre que se aade un nuevo registro. Cuando ocurre un error al enviar los cambios. Cuando ocurre un error al actualizar los datos. Cuando se actualiza el registro en la BD.

Introduccin de datos Asignacin de valores por omisin en el evento OnNewRecord utilizando FieldValues

void __fastcall TDataModuleXXX::TableNewRecord(TDataSet *DataSet) { DataSet->FieldValues["Date"] = Date(); }

Validaciones a nivel de registros Comprobaciones como respuesta al evento BeforePost, con la posibilidad de generar una excepcin (DatabaseError)

file:///D|/Manuales/databases/tdataset.html (4 of 8) [27/02/2003 16:24:26]

C++ Builder

void __fastcall TDataModulePersonal::tbEmpleadosBeforePost(TDataSet *DataSet) { if (Date() - tbEmpleadosHireDate->Value < 365 && tbEmpleadosSalary->Value > TopeSalarial) DatabaseError("Este es un enchufado!", 0); }

Eliminacin en cascada Eliminar las lneas detalle de una relacin master/detail interceptando el evento BeforeDelete
void __fastcall TDataModulePedidos::tbPedidosBeforeDelete(TDataSet *DataSet) { tbLineas->First(); if (! tbLineas->Eof) if (MessageDlg("Eliminar detalles?",mtConfirmation, TMsgDlgButtons()<<mbYes<<mbNo, 0)==mrYes) { do { tbLineas->Delete(); } while (! tbLineas->Eof); } else { Abort(); } }

Gestin de errores Eventos de deteccin de errores: OnEditError, OnPostError, OnDeleteError

Posible solucin ante un error de bloqueo no concedido

file:///D|/Manuales/databases/tdataset.html (5 of 8) [27/02/2003 16:24:26]

C++ Builder

void __fastcall TDataModuleXXX::TableEditError (TDataSet *DataSet, EDatabaseError *E, TDataAction &Action) { // Consultar al usuario if ( MessageDlg ( E->Message, mtWarning, TMsgDlgButton() << mbRetry << mbAbort, 0) == mrRetry ) { // Esperar entre 1 y 2 segundos antes de reintentar Sleep(1000 + random(1000)); Action = daRetry; } else { // Abortar Action = daAbort; } }

Cdigos de error BDE void __fastcall TDataModuleXXX::TablePostError (TDataSet *TDataSet, EDatabaseError *E, TDataAction &Action) { AnsiString S; EDBEngineError *Err = dynamic_cast<EDBEngineError*>(E);
if (Err) { for (int i = 0; i < Err->ErrorCount; i++) { if (i > 0) AppendStr(S, '\n'); TDBError *E = Err->Errors[i]; AppendStr(S, Format( "%.4x (%d): %s", ARRAYOFCONST((E->ErrorCode, E>NativeError,E->Message)))); } DatabaseError(S, 0); } }

Mensajes de error personalizados

file:///D|/Manuales/databases/tdataset.html (6 of 8) [27/02/2003 16:24:26]

C++ Builder

int GetBDEError(EDatabaseError *E) { EDBEngineError *Err = dynamic_cast<EDBEngineError*>(E); if (Err) for (int I = 0; I < Err->ErrorCount; I++) { TDBError *dbe = Err->Errors[I]; if (dbe->NativeError == 0) return dbe->ErrorCode; } return -1; } // Relaciones maestro/detalle void __fastcall TDataModulePedidos::tbPedidosDeleteError (TDataSet *TDataSet, EDatabaseError *E, TDataAction &Action) { if (GetBDEError(E) == DBIERR_DETAILRECORDSEXIST) if ( MessageDlg( "Eliminar tambin las lneas de detalles?", mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrYes) { tbLineas->First(); while (! tbLineas->Eof) tbLineas->Delete(); // Reintentar el borrado en la tabla de pedidos Action = daRetry; } else // Fallar sin mostrar otro mensaje Action = daAbort; } // Evento OnPostError para cualquier tabla void __fastcall TDataModuleXXX::PostError (TDataSet *DataSet, EDatabaseError *E, TDataAction &Action) { TTable *T = static_cast<TTable*>(DataSet); switch (GetBDEError(E)) { case DBIERR_KEYVIOL: DatabaseErrorFmt("Clave repetida en la tabla %s", ARRAYOFCONST((T->TableName)), 0); break; case DBIERR_FOREIGNKEYERR: DatabaseErrorFmt("Error en clave externa. Tabla: %s",

file:///D|/Manuales/databases/tdataset.html (7 of 8) [27/02/2003 16:24:26]

C++ Builder

ARRAYOFCONST((T->TableName)), 0); break; } }

Fernando Berzal Galiano

file:///D|/Manuales/databases/tdataset.html (8 of 8) [27/02/2003 16:24:26]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


El componente TDataSource

TDataSource
El componente TDataSource ofrece un mecanismo para enganchar los conjuntos de datos (Table, TQuery y TStoredProc, por ejemplo) con los controles visuales que muestran los datos (TDBGrid, TDBEdit, TDBListBox, etc.). TDataSource se encarga de toda la comunicacin necesaria entre ellos. Para cambiar el conjunto de datos enlazado a un componente de tipo TDataSource (ya sea ste una tabla o una consulta), solamente hay que modificar su propiedad DataSet. La propiedad AutoEdit del componente TDataSource determina si se invoca automticamente al mtodo Edit del conjunto de datos asociado cuando un control (un TDBEdit, por ejemplo) recibe el foco.

Implementacin de componentes "data-aware"


Para crear nuestros propios componentes de forma que se puedan enlazar a un conjunto de datos hemos de automatizar el intercambio de mensajes con los componentes TDataSource. El cdigo comn a todos los controles de datos est recogido en TDataLink (y en su descendiente TFieldDataLink), de forma que podemos utilizarlo para hacer nuestros componentes "data-aware".

file:///D|/Manuales/databases/tdatasource.html (1 of 2) [27/02/2003 16:24:27]

C++ Builder

Fernando Berzal Galiano

file:///D|/Manuales/databases/tdatasource.html (2 of 2) [27/02/2003 16:24:27]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


Cursores

Cursores
Ejercicios q Navegar por un conjunto de datos utilizando First, Prior, Next, Last, MoveBy, BOF, EOF, IsEmpty y RecordCount. q Comprobar el efecto de DisableControls y EnableControls.

Marcadores (TBookmarkStr)
TBookmarkStr BM = Table->Bookmark; try { // Mover la fila activa } __finally { // Regresar a la posicin inicial Table->Bookmark = BM; }

Iteradores
Clase auxiliar para el recorrido secuencial de un conjunto de datos

file:///D|/Manuales/databases/cursor.html (1 of 2) [27/02/2003 16:24:27]

C++ Builder

class TDataSetIterator { private: TBookmarkStr BM; TDataSet* dataset; public: TDataSetIterator(TDataSet* ds) : dataset(ds) { Screen->Cursor = crHourGlass; ds->DisableControls(); BM = ds->Bookmark; ds->First(); } ~TDataSetIterator() { dataset->Bookmark = BM; dataset->EnableControls(); Screen->Cursor = crDefault; } }; ... TDataSetIterator dsi(Table); while (! Table->Eof) { // Hacer algo con la fila activa... Table->Next(); }

Fernando Berzal Galiano

file:///D|/Manuales/databases/cursor.html (2 of 2) [27/02/2003 16:24:27]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


Actualizaciones en cach

Actualizaciones en cach
Las actualizaciones en cach son un recurso del BDE para mejorar el rendimiento de las transacciones en entornos cliente/servidor. Los conjuntos de datos de C++ Builder vienen equipados con una propiedad, CachedUpdates, que decide si los cambios efectuados en el conjunto de datos son grabados inmediatamente en la base de datos o si se almacenan en la memoria del ordenador cliente y se envan en bloque al servidor a peticin del programa cliente. Cuando la propiedad CachedUpdates est a true, los cambios en los registros no se escriben en la base de datos. En su lugar, se escriben en un buffer de la mquina local. Los registros se mantienen en la cach hasta que se llama al mtodo ApplyUpdates(). Para confirmar los cambios se ha de llamar a CommitUpdates(). Para anular los cambios almacenados en cach se puede usar el mtodo CancelUpdates(). Tambin se pueden anular las modificaciones hechas en un registro con el mtodo RevertRecord().

file:///D|/Manuales/databases/cache.html (1 of 2) [27/02/2003 16:24:27]

C++ Builder

StartTransaction(); // this = la base de datos sobre la que estemos trabajando try { for (int i = 0; i <= DataSets_size; i++) DataSets[i]->ApplyUpdates(); // Pueden fallar Commit(); } catch(Exception&) { Rollback(); throw; // Propagar la excepcin } for (int i = 0; i <= DataSets_size; i++) DataSets[i]->CommitUpdates(); // Nunca fallan

Una alternativa es forzar el vaciado de los buffers escribiendo:


void __fastcall TDataModuleXXX::TableAfterPost(TObject *Sender) { static_cast<TDBDataSet*>(Sender)->FlushBuffers(); }

Ventajas
q

Disminuye el nmero de paquetes enviados por la red (se reduce el trfico de red). Los registros de la base de datos slo se bloquean cuando se hace el volcado de la cach (transacciones ms cortas). Ms fcil mantener la atomicidad de las transacciones (se permite hacer commit o rollback de varios cambios a la vez).

Desventajas
q

Varios usuarios pueden trabajar con el mismo registro simultneamente (al no existir bloqueos).

Fernando Berzal Galiano

file:///D|/Manuales/databases/cache.html (2 of 2) [27/02/2003 16:24:27]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


TTable

El componente TTable facilita el acceso ms simple y rpido a una tabla. Entre sus mltiples propiedades y mtodos destacan:
q

Propiedades: DatabaseName, TableName, ReadOnly Mtodos: Open&Close, GotoCurrent

Relaciones maestro/detalle
Para construir una relacin maestro/detalle en C++ Builder basta con indicar el DataSource de la tabla maestro en la propiedad MasterSource de la tabla detalle y establecer la condicin de la reunin (join) mediante la propiedad MasterFields. Adems, hay que especificar IndexName o IndexFieldNames para establecer un orden en la tabla detalle (y para que C++Builder lo haga eficientemente!). Ejercicio q Crear un mdulo de datos (DataModule) que contenga dos tablas (clientes y pedidos, por ejemplo) y sus correspondientes DataSources.
q Establecer la propiedad MasterSource en la tabla detalle para que apunte al DataSource de la tabla maestra. Fijar las propiedades necesarias para especificar correctamente la relacin maestro/detalle (vg: reunin CustNoCustNo usando como ndice CustNo).

q Crear un formulario que contenga dos componentes TDBGrid enlazados a las tablas del mdulo de datos (a sus DataSources para ser ms precisos). Para ello es necesario realizar el #include correspondiente.

Bsquedas
Una necesidad bastante comn en cualquier aplicacin de bases de datos es la de seleccionar un conjunto de registros que cumplan una condicin.

Filtros
Para realizar bsquedas se pueden utilizar tablas con filtros. Un filtro se puede construir usando la
file:///D|/Manuales/databases/ttable.html (1 of 6) [27/02/2003 16:24:28]

C++ Builder

propiedad Filter (con FilterOptions) o el evento OnFilterRecord. La propiedad Filtered indica si el filtro est activo. Un conjunto de datos filtrado puede recorrerse usando los mtodos FindFirst(), FindNext(), FindPrior() y FindLast(). Medite antes de decidirse a utilizar OnFilterRecord. Este tipo de filtro se aplica en el cliente, lo cual implica que la aplicacin debe bajarse a travs de la red incluso los registros que no satisfacen el filtro.
void __fastcall TFormX::Filtrar(TObject *Sender) { Set<TFieldType, ftUnknown, ftDataSet> TiposConComillas; AnsiString Operador, Valor; TiposConComillas < ftString < ftDate < ftTime < ftDateTime; Operador = Sender == miIgual ? "=" : Sender == miMayorIgual ? ">=" : Sender == miMenorIgual ? "<=" : "<>"; // Extraer el nombre del campo AnsiString Campo = DBGrid->SelectedField->FieldName; // Extraer y dar formato al valor seleccionado if (TiposConComillas.Contains(DBGrid->SelectedField->DataType)) Valor = QuotedStr(DBGrid->SelectedField->AsString); else { Valor = DBGrid->SelectedField->AsString; for (int i = 1; i <= Valor.Length(); i++) if (Valor[i] == DecimalSeparator) Valor[i] = '.'; } // Combinar la nueva condicin con las anteriores if (Table->Filter == "") Table->Filter = Format("[%s] %s %s", ARRAYOFCONST((Campo, Operador, Valor))); else Table->Filter = Format("%s AND [%s] %s %s", ARRAYOFCONST((Table1->Filter, Campo, Operador, Valor))); // Activar directamente el filtro miActivarFiltro->Checked = True; Table->Filtered = True; Table->Refresh(); } void __fastcall TFormX::miActivarFiltroClick(TObject *Sender) { miActivarFiltro->Checked = ! miActivarFiltro->Checked; // Activar o desactivar en dependencia del estado de la opcin del men. Table->Filtered = miActivarFiltro->Checked;

file:///D|/Manuales/databases/ttable.html (2 of 6) [27/02/2003 16:24:28]

C++ Builder

Table->Refresh(); } void __fastcall TFormX::miEliminarFiltroClick(TObject *Sender) { miActivarFiltro->Checked = False; Table->Filtered = False; Table->Filter = ""; Table->Refresh(); }

NB: Los filtros tambin son aplicables a componentes de tipo TQuery

ndices
Se pueden hacer bsquedas usando el ndice activo de una tabla (establecido por IndexName o IndexFieldNames) usando los mtodos FindKey y FindNearest. Alternativamente se pueden utilizan las combinaciones SetKey+GotoKey (en vez de FindKey) y SetKey+GotoNearest (sustituyendo a FindNearest)
void __fastcall TFormDatos.ButtonClick(TObject *Sender) { Table->SetKey(); // FormSearch => dilogo del tipo OK/Cancel con TDBEdits if (FormSearch->ShowModal() == mrOk) Table->GotoNearest(); else Table->Cancel(); }

Rangos
Tambin se puede limitar el conjunto de registros de un conjunto de datos utilizando rangos mediante los mtodos SetRange y CancelRange. Un rango es una restriccin de las filas visibles de una tabla en la que se muestran slo aqullas tuplas en las cuales los valores de ciertas columnas se encuentran entre dos valores dados. Debe existir un ndice sobre esas columnas.

file:///D|/Manuales/databases/ttable.html (3 of 6) [27/02/2003 16:24:28]

C++ Builder

void __fasctcall TFormAgenda::TabControlChange(TObject *Sender) { AnsiString Letra; Letra = TabControl->Tabs->Strings[TabControl1->TabIndex]; if (TabControl->TabIndex == 0) // Si es la pestaa con el asterisco mostramos todas las filas. Table->CancelRange(); else // Activamos el rango correspondiente Table->SetRange(ARRAYOFCONST((Letra)),ARRAYOFCONST((Letra + "zzz"))); // Actualizamos los controles asociados Table->Refresh(); }

Locate & Lookup


Los mtodos Locate y Lookup amplan las posibilidades de los mtodos de bsqueda con ndices. El primero intenta encontrar un registro con los valores deseados (usando ndices si los hay); mientras que el segundo se utiliza para buscar el valor de una columna utilizando como clave una diferente (por ejemplo, para buscar el nombre de un empleado conociendo su cdigo personal o, al revs, para encontrar el cdigo de un empleado del que conocemos su nombre).
AnsiString TDataModulePersonal::ObtenerNombre(int Codigo) { return VarToStr(tbClientes->Lookup("Cdigo", Codigo, "Nombre")); } int TDataModulePersonal::ObtenerCodigo(const AnsiString Apellido, const AnsiString Nombre) { Variant V = tbEmpleados->Lookup( "Apellido;Nombre", VarArrayOf(ARRAYOFCONST((Apellido, Nombre))), "Cdigo"); if (VarIsNull(V)) DatabaseError("Empleado no encontrado", 0); return V; } AnsiString TDataModulePersonal::NombreDeEmpleado(int Codigo) { Variant V = tbEmpleados->Lookup("Codigo", Codigo, "Nombre;Apellido"); if (VarIsNull(V)) DatabaseError("Empleado no encontrado", 0);
file:///D|/Manuales/databases/ttable.html (4 of 6) [27/02/2003 16:24:28]

C++ Builder

return V.GetElement(0) + " " + V.GetElement(1); }

Actualizaciones
Actualizacin programada

TableDetail->Edit(); try { // Asignaciones a campos... TableDetailFecha->Value = Date(); // == TableDetail->FieldByName("Fecha")->AsDateTime = Date(); // == TableDetail->FieldValues["Fecha"] = Date(); TableDetailConcepto->Clear(); TableDetail->Fields->Fields[x]->Assign(TableMaster->Fields>Fields[x]); // Post TableDetail->Post(); } catch (Exception&) { TableDetail->Cancel(); throw; }

Insercin de datos

AnsiString RandomString (int Longitud) { char* Vocales = "AEIOU"; char LastChar = 'A'; AnsiString Rslt; Rslt.SetLength(Longitud); for (int i = 1; i <= Longitud; i++) { LastChar = strchr("AEIOUNS", LastChar) ? random(26) + 'A' : Vocales[random(5)]; Rslt[i] = LastChar; } return Rslt;
file:///D|/Manuales/databases/ttable.html (5 of 6) [27/02/2003 16:24:28]

C++ Builder

} void CrearDatosSinteticos (TTable *Tabla, int registros) { int intentos = 3; int longitud = Tabla->FieldByName("Cadena")->Size; randomize(); while (registros > 0) try { 1) Tabla->Append(); Tabla->FieldValues["Cadena"] = RandomString(longitud); Tabla->FieldValues["Entero"] = random(MAXINT); 2) Tabla->AppendRecord( ARRAYOFCONST ( RandomString(longitud), random(MAXINT) ) )); Tabla->Post(); // NOTA: Sera ms eficiente si se agrupasen // distintas inserciones en una nica transaccin intentos = 3; registros--; } catch(Exception&) { intentos--; if (intentos == 0) throw; } }

Refresco de los datos


El contenido actual de la fila activa se puede obtener llamando de forma consecutiva a Edit y Cancel (lo que es ms eficiente que llamar a Refresh sobre el conjunto completo de datos)

Table->Edit(); Table->Cancel();

Fernando Berzal Galiano

file:///D|/Manuales/databases/ttable.html (6 of 6) [27/02/2003 16:24:28]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


TQuery

El componente TQuery permite realizar consultas en SQL. En los siguientes apartados se describen sus propiedades y mtodos bsicos:

La consulta SQL
La propiedad SQL es de tipo TStringList (un lista de cadenas de caracteres) y contiene la sentencia SQL que ha de ejecutarse sobre la base de datos indicada mediante la propiedad DatabaseName. Ejemplo:
q q q q

Cambiar la tabla de clientes por una consulta. Enlazarla con la base de datos BCDEMOS (propiedad DatabaseName). Enlazar el DataSource que tena la tabla a la nueva consulta. En la propiedad SQL de la consulta, teclear: select * from customer where CustNo > 1300

Otra propiedad bastante interesante del componente TQuery es LiveRequest, que permite que una consulta sea actualizable (es decir, que podamos editar su conjunto de datos sin tener que preocuparnos de cmo almacenar los cambios en la base de datos). Por desgracia, no todas las consultas son actualizables.

Ejecucin de sentencias SQL


Para ejecutar en tiempo de diseo la sentencia SQL correspondiente a una consulta (un SELECT) basta con poner su propiedad Active a true (lo que equivale a invocar al mtodo Open()). En tiempo de ejecucin, se puede usar Open() para ejecutar una consulta (SELECT), o ExecSQL() para ejecutar una sentencia SQL de tipo INSERT, UPDATE o DELETE.

Sentencias SQL con parmetros


En las sentencias SQL se pueden utilizar parmetros. Los parmetros son variables que se escriben en la sentencia SQL precedidos de : (dos puntos). El valor de tales parmetros se puede establecer
file:///D|/Manuales/databases/tquery.html (1 of 4) [27/02/2003 16:24:28]

C++ Builder

accediente a la propiedad Params del componente TQuery o mediante el mtodo ParamByName. En tiempo de diseo: Preparar una consulta SQL con:
select * from customer where CustNo > :ValorMinimo

Editar la propiedad Params estableciendo el parmetro ValorMinimo como un integer con valor 1300. En tiempo de ejecucin: { query->SQL->Clear(); query->SQL->Add( "select * from customer where CustNo > :ValorMinimo"); query->ParamByName("ValorMinimo")->AsInteger = 1300; query->Open(); }

En los parmetros tambin se pueden utilizar comodines:


Query->ParamByName("id")->AsString = Edit->Text + "%";

Los mtodos Prepare() y UnPrepare() sirven para ejecutar consultas preparadas, que sern ms eficientes si se ejecutan mltiples veces siempre que nuestra base de datos permita este tipo de consultas optimizadas. La propiedad Prepared nos indica si una consulta ha sido preparada o no. Preparacin inicial de una consulta if (! Query->Prepared) Query->Prepare();
Query->Open();

Liberacin de recursos Query->Close();


if (Query->Prepared) Query->UnPrepare();

Consultas dependientes [linked queries]


Mediante consultas tambin se pueden establecer relaciones maestro/detalle. Para ello hemos de dejar
file:///D|/Manuales/databases/tquery.html (2 of 4) [27/02/2003 16:24:28]

C++ Builder

un parmetro de la consulta detalle asociado a una columna del conjunto de datos que hace de maestro, SIN especificar su tipo. Para enlazar la consulta basta entonces establecer su propiedad DataSource para que apunte a la tabla maestra. Este tipo de consultas NO son actualizables, por lo que usualmente preferiremos utilizar tablas (TTables).

Consultas heterogneas
El motor de bases de datos de Borland (BDE) permite incluso realizar consultas que involucren tablas almacenadas en distintas bases de datos. Para ello, en la consulta SQL hay que indicar las tablas utilizando la notacin :ALIAS:tabla, donde ALIAS es el alias BDE de la base de datos donde se encuentra la tabla tabla.

Actualizaciones (insert, update & delete)


int __fastcall ejecutarSQL(const AnsiString ADatabase, const AnsiString Instruccion) { std::auto_ptr query(new TQuery(NULL)); query->DatabaseName = ADatabase; query->SQL->Text = Instruccion; query->ExecSQL(); return query->RowsAffected; }

Datos sintticos
insert into TablaAleatoria(Entero, Cadena) values (:Ent, :Cad) void RellenarTabla(TQuery *Query, int CantRegistros) { randomize(); Query->Prepare(); try { int Intentos = 3; while (CantRegistros > 0) try { Query->ParamByName("ENT")->AsInteger = random(MAXINT); Query->ParamByName("CAD")->AsString = RandomString(35); Query->ExecSQL(); Intentos = 3; CantRegistros--; } catch(Exception&) { if (--Intentos == 0) throw;

file:///D|/Manuales/databases/tquery.html (3 of 4) [27/02/2003 16:24:28]

C++ Builder

} } __finally { Query->UnPrepare(); } }

Fernando Berzal Galiano

file:///D|/Manuales/databases/tquery.html (4 of 4) [27/02/2003 16:24:28]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


TStoredProc

El componente TStoredProc representa un procedimiento almacenado en un servidor de bases de datos. El esquema de utilizacin de procedimientos almacenados es:
q

Indicar su nombre en la propiedad StoredProcName. Establecer sus parmetros (igual que en una consulta TQuery). Preparar su ejecucin con el mtodo Prepare(). Invocarlo tantas veces como sea necesario con ExecProc(). Llamar al mtodo UnPrepare() cuando ya no se vaya a ejecutar ms veces el procedimiento almacenado.

Procedimientos almacenados que devuelven valores


create procedure EstadisticasProducto (CodProd int) returns ( TotalPedidos int, CantidadTotal int, TotalVentas int, TotalClientes int ) as declare variable Precio int; begin select Precio from Articulos where Codigo = :CodProd into :Precio; select count(Numero), count(distinct RefCliente) from Pedidos where :CodProd
file:///D|/Manuales/databases/tstoredproc.html (1 of 5) [27/02/2003 16:24:28]

C++ Builder

in ( select RefArticulo from Detalles where RefPedido = Numero ) into :TotalPedidos, :TotalClientes; select sum(Cantidad), sum(Cantidad*:Precio*(100-Descuento)/100) from Detalles where Detalles.RefArticulo = :CodProd into :CantidadTotal, :TotalVentas; end ^ void __fastcall ...::EstadisticasProducto(TObject *Sender) { AnsiString S; if ( InputQuery("Informacin", "Cdigo del producto", S) && Trim(S) != "" ) { TStoredProc *sp = DataModuleProductos->spEstadisticas; sp->ParamByName("CodProd")->AsString = S; sp->ExecProc(); ShowMessage( Format( "Pedidos: %d\nClientes: %d\nCantidad: %d\nTotal: %m", ARRAYOFCONST((sp->ParamByName("TotalPedidos")>AsInteger, sp->ParamByName("TotalClientes")>AsInteger, sp->ParamByName("CantidadTotal")>AsInteger, sp->ParamByName("TotalVentas")>AsFloat)))); } }

Procedimientos almacenados que devuelven conjuntos de datos

file:///D|/Manuales/databases/tstoredproc.html (2 of 5) [27/02/2003 16:24:28]

C++ Builder

Definimos una base de datos (en InterBase) para almacenar una jerarqua de conceptos (como las categoras de un ndice en Internet tipo Yahoo!):
create domain TID as INTEGER; create domain TDESCRIPTION as VARCHAR(128); create table CATEGORY ( ID TID not null, description TDESCRIPTION, primary key (ID) ); create table HIERARCHY ( SUPER TID not null references CATEGORY, SUB TID not null references CATEGORY, primary key (SUPER,SUB) );

Creamos sendos procedimientos almacenado recursivos que nos devuelven todas las categoras por debajo (o por encima) de una categora dada en la jerarquia:
create procedure DESCENDANTS (super integer) returns (sub integer) as begin FOR SELECT sub FROM HIERARCHY WHERE SUPER = :super INTO :sub DO BEGIN if (sub is not null) then begin SUSPEND; for select * from DESCENDANTS(:sub) into :sub do begin if (sub is not null) then SUSPEND; end end END end ^ create procedure ANCESTORS (sub integer)
file:///D|/Manuales/databases/tstoredproc.html (3 of 5) [27/02/2003 16:24:28]

C++ Builder

returns (super integer) as begin FOR SELECT id FROM HIERARCHY WHERE SUB = :sub INTO :super DO BEGIN if (super is not null) then begin SUSPEND; for select * from ANCESTORS(:super) into :super do begin if (super is not null) then SUSPEND; end end END end ^ set term ;^

Para utilizar los procedimientos almacenados anteriores, se puede escribir alguna de las siguientes consultas parametrizadas en la propiedad SQL de un TQuery:
select distinct * from descendants(:id) select distinct * from ancestors(:id)

Ejecucin de un procedimiento almacenado en una hebra independiente

file:///D|/Manuales/databases/tstoredproc.html (4 of 5) [27/02/2003 16:24:28]

C++ Builder

class TSPThread : public TThread { protected: void __fastcall Execute(); public: __fastcall TSPThread(); }; __fastcall TSPThread::TSPThread():TThread(True) // Crear hebra "suspendida" { FreeOnTerminate = True; Resume(); // Ejecutar la hebra } // // // // DataModuleSPThread es un mdulo de datos con tres componentes: - SessionSPThread (de tipo TSession), - DatabaseSPThread (de tipo TDatabase), y - StoredProcSPThread (de tipo TStoredProc).

void __fastcall TSPThread::Execute() { DataModuleSPThread->DatabaseSPThread->Open(); try { DataModuleSPThread->StoredProcSPThread->ExecProc(); } __finally { DataModuleSPThread->SessionSPThread->Close(); } } // Ejecucin void __fastcall TForm1::Btn1Click(TObject *Sender) { new TSPThread; }

Fernando Berzal Galiano

file:///D|/Manuales/databases/tstoredproc.html (5 of 5) [27/02/2003 16:24:28]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


TField

Acceso a las columnas de un conjunto de datos


La clase TField representa un campo (una columna) en un conjunto de datos. Por medio de esta clase pueden establecer los atributos de un campo (tipo, tamao, ndice, si es un campo calculado o de bsqueda, si es obligatorio...), y tambin se puede acceder a su valor a travs de propiedades como AsString o AsInteger. TField es una clase base de la que se derivan otras muchas. Sus descendientes incluyen a TStringField, TIntegerField, TFloatField y TDateField, entre otros muchos.

Nuevos en C++Builder 4:

file:///D|/Manuales/databases/tfield.html (1 of 7) [27/02/2003 16:24:29]

C++ Builder

Acceso a los valores de los campos


Para recuperar o establecer el valor de un campo podemos usar:
q

Un objeto TField creado con el editor de campos [Fields Editor]. La propiedad Fields de TDataSet.

__property TFields* TDataSet::Fields; __property int TFields::Count; __property TField* TFields::Fields[int Index];
q

El mtodo FieldByName() de TDataSet.

TField* __fastcall TDataSet::FieldByName(const AnsiString Nombre);

Ejemplo

file:///D|/Manuales/databases/tfield.html (2 of 7) [27/02/2003 16:24:29]

C++ Builder

TablaApellidos->Value = "Prez Martn"; Tabla->Fields->Fields[0]->Value = "Prez Martn"; Tabla->FieldByName("Apellidos")->Value = "Prez Martn";

El Editor de Campos [Fields Editor]


Desde el men contextual de cualquier descendiente de TDataSet (vg: TTable o TQuery) se permite el acceso al "Fields Editor" en tiempo de diseo. De esta forma se pueden especificar aquellos campos que se quieren incluir en el conjunto de datos y sus propiedades. Ejemplo q Seleccionar del men contextual (botn derecho del ratn) de cualquier TDataSet la opcin Fields Editor. q Seleccionar Add Fields en el men del Fields Editor. q Aadir los campos que deseemos utilizar. q Ver las propiedades de los campos en el Inspector de Objetos (p.ej. seleccionndolos en el Fields Editor).

Propiedades interesantes de TField


Propiedad FieldName DisplayLabel Value IsNull DisplayFormat EditMask CustomConstraint ConstraintErrorMessage Descripcin Nombre de la columna en la BD. Texto descriptivo empleado por TDBGrid. Valor en la fila activa. Indica si el valor es nulo. Personalizacin de la visualizacin. Control de la edicin del campo. Restriccin en el valor del campo. Mensaje de error asociado.

file:///D|/Manuales/databases/tfield.html (3 of 7) [27/02/2003 16:24:29]

C++ Builder

ReadOnly

Campo de slo lectura

Los eventos de TField


Evento OnChange OnValidate OnGetText OnSetText Descripcin Cuando cambia el valor del campo. Validacin a nivel de campos. Al visualizar valores. Al editar valores.

Uso de TField
Visualizacion personalizada
Definiendo la respuesta al evento GetText Seleccionar un campo de tipo entero y hacer que se visualice con nmeros romanos. void __fastcall ...::tbFieldGetText (TField *Sender, AnsiString &Text, bool DisplayText) { static AnsiString Unidades[10] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; static AnsiString Decenas[10] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; static AnsiString Centenas[10] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; static AnsiString Miles[4] = {"", "M", "MM", "MMM"};
if (Sender->AsInteger > 3999) { Text = "Infinitum"; // Hay que ser consecuentes con el lenguaje } else { int i = Sender->AsInteger; Text = Miles[i / 1000]

file:///D|/Manuales/databases/tfield.html (4 of 7) [27/02/2003 16:24:29]

C++ Builder

+ Centenas[i / 100 % 10] + Decenas[i / 10 % 10] + Unidades[i % 10]; } }

Restricciones a nivel de campos


1. Definiendo la respuesta al evento SetText: Forzar que las iniciales de los nombres sean siempre letras maysculas void __fastcall ...::tbFieldSetText(TField *Sender, const AnsiString Text) { int i; AnsiString S = Text;
for ( i=1; i<=S.Length(); i++) if ( i==1 || S[i-1]==' ') CharUpperBuff(&S[i], 1); Sender->AsString = S; }

2. Utilizando el evento OnValidate: Un nombre propio no puede incluir dgitos ni otros simbolos

file:///D|/Manuales/databases/tfield.html (5 of 7) [27/02/2003 16:24:29]

C++ Builder

void __fastcall ...::tbFieldValidate(TField *Sender) { AnsiString S = Sender->AsString; for (int i = S.Length(); i > 0; i--) if (S[i] != ' ' && !IsCharAlpha(S[i])) DatabaseError("Carcter no permitido en nombre propio", 0); }

3. Controlando el valor que puede tomar un campo mediante sus propiedades EditMask y CustomConstraint. Cuando se utiliza esta ltima, lo normal es definir tambin ConstraintErrorMessage para que el usuario sepa por qu no puede darle determinados valores a un campo. Valores no nulos CustomConstraint = value is not null Cdigo postal EditMask = !99999;1;_ Telfono o fax EditMask = !999 99 99 99;0;_ Direccin de correo electrnico CustomConstraint = value is null or value='' or value like '%_@%_.%_'

Campos calculados
Se crean con New field (Calculated) desde el men contextual del editor de campos y se manejan a travs del evento OnCalcFields, que se produce cada vez que se cambia o se modifica la fila activa del conjunto de datos (si est a true la propiedad AutoCalcFields del conjunto de datos).

file:///D|/Manuales/databases/tfield.html (6 of 7) [27/02/2003 16:24:29]

C++ Builder

Campos de bsqueda [lookup fields]


Se pueden crear con la opcin New field (Lookup) del men contextual del editor de campos. Se definen mediante las propiedades KeyFields, LookupDataset, LookupKeyFields y LookupResultField. Mediante LookupCache se pueden cargar los valores permitidos en la propiedad LookupList, la cual se puede actualizar llamando a RefreshLookupList.

BLOBs: TBlobField
Los campos de tipo BLOB [Binary Large OBject] en una base de datos se pueden utilizar para almacenar ficheros completos, imgenes, sonidos o cualquier otro tipo de informacin digitalizada. El contenido de este tipo de campos se puede modificar invocando al mtodo LoadFromFile, mientras que su complementario (SaveToFile) nos permite recuperar la informacin almacenada en la base de datos. Imgenes en formato JPG (jpeg.hpp) void __fastcall ...::DataSourceImagenDataChange(TObject *Sender, TField *Field) { if (tbImagenesFoto->IsNull) Image->Picture->Graphic = NULL; else { std::auto_ptr BS(new TBlobStream(tbImagenesFoto, bmRead)); auto_ptr Graphic(new TJPEGImage); Graphic->LoadFromStream(BS.get()); Image->Picture->Graphic = Graphic.get(); } }

Fernando Berzal Galiano

file:///D|/Manuales/databases/tfield.html (7 of 7) [27/02/2003 16:24:29]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


TSession

El componente TSession gestiona una sesin de la base de datos (un conjunto de conexiones desde una misma aplicacin). Cada vez que se inicia una aplicacin que accede a bases de datos a travs del motor de bases de datos de Borland, el BDE establece un objeto de tipo TSession global llamado Session con el cual se puede acceder a las propiedades de la sesin actual. En principio, no hay que crear un objeto TSession propio salvo que se est construyendo una aplicacin multihebra. Este componente incluye algunos mtodos de inters:

Gestin de alias BDE


AddAlias(), AddStandardAlias(), ModifyAlias(), DeleteAlias() y SaveConfigFile() son mtodos que pueden usarse para gestionar alias BDE en tiempo de ejecucin.
void __fastcall TSession::AddAlias (const AnsiString Nombre, const AnsiString Ctrldor, TStrings *Lista); void __fastcall TSession::AddStandardAlias (const AnsiString Nombre, const AnsiString Dir, const AnsiString Ctrldor); void __fastcall TSession::ModifyAlias (const AnsiString Alias, TStrings *Parametros); void __fastcall TSession::DeleteAlias (const AnsiString Alias); void __fastcall TSession::SaveConfigFile();

Acceso al catlogo
GetAliasNames(), GetDatabaseNames(), GetDriverNames(), GetTableNames() y GetStoredProcNames() se pueden utilizar para conseguir informacin acerca de las bases de datos disponibles en el sistema.
void __fastcall TSession::GetDriverNames (TStrings *Lista);
file:///D|/Manuales/databases/tsession.html (1 of 2) [27/02/2003 16:24:29]

C++ Builder

void __fastcall TSession::GetDriverParams (const AnsiString Controlador, TStrings *Lista); void __fastcall TSession::GetDatabaseNames (TStrings *Lista); void __fastcall TSession::GetAliasNames (TStrings *Lista); AnsiString __fastcall TSession::GetAliasDriverName (const AnsiString Alias); void __fastcall TSession::GetAliasParams (const AnsiString Alias, TStrings *Lista); void __fastcall TSession::GetTableNames (const AnsiString Alias, const AnsiString Patron, bool Extensiones, bool TablasDeSistema, TStrings *Lista); void __fastcall TSession::GetStoredProcNames (const AnsiString Alias, TStrings *Lista);

Ejemplo:

Session->GetDatabaseNames(DBNamesComboBox->Items);

Fernando Berzal Galiano

file:///D|/Manuales/databases/tsession.html (2 of 2) [27/02/2003 16:24:29]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


TDatabase

El componente TDatabase permite controlar las conexiones a una base de datos. Aunque su uso no es estrictamente necesario, hay ciertas operaciones para las que resulta imprescindible:

Conexiones persistentes con bases de datos


La propiedad KeepConnections de TDatabase se utiliza para controlar cmo se manejan las conexiones con las bases de datos cuando se cierra un dataset. Si KeepConnections est a false, cuando se cierra el ltimo dataset, la conexin con la base de datos se pierde y habr que reiniciarla la prxima vez que se abra otro dataset, lo que consumir una cantidad considerable de tiempo y, si no hacemos nada para evitarlo, volver a solicitar la clave de acceso del usuario.

Establecimiento de la conexin [Login]


El componente TDatabase tambin permite controlar el login de una forma automtica:
q

Estableciendo la propiedad LoginPrompt a false y fijando explcitamente los parmetros de la conexin. Desde el cdigo

file:///D|/Manuales/databases/tdatabase.html (1 of 4) [27/02/2003 16:24:30]

C++ Builder

Database->AliasName = "Oracle"; Database->DatabaseName = "MiDB"; Database->Params->Values["user name"] = "scott"; Database->Params->Values["password"] = "tiger"; Table->DatabaseName = Database->DatabaseName; Table->TableName = "CUSTOMER"; Table->Open();

Desde el inspector de objetos En el editor de listas asociado a la propiedad Params:


USER NAME=scott PASSWORD=tiger

Interceptando el evento OnLogin, el cual se genera cada vez que se ha de establecer una conexin cuando la propiedad LoginPrompt est a true.
void __fastcall ...::DatabaseLogin (TDatabase *Database, TStrings *LoginParams) { LoginParams->Values["user name"] = "scott"; LoginParams->Values["password"] = "tiger"; }

Schema cache
void __fastcall ...::DatabaseLogin (TDatabase *Database, TStrings *LoginParams) { ... // Schema cache AnsiString S; S.SetLength(255); int L = GetTempPath(255, S.c_str()); if (S.IsPathDelimiter(L)) L--;

file:///D|/Manuales/databases/tdatabase.html (2 of 4) [27/02/2003 16:24:30]

C++ Builder

S.SetLength(L); Database1->Params->Values["ENABLE SCHEMA CACHE"] = "TRUE"; Database1->Params->Values["SCHEMA CACHE DIR"] = S; }

Control de Transacciones
Otro uso ms del componente TDatabase (puede que el ms importante) es el control explcito de las transacciones con la base de datos. Una transaccin es una coleccin de operaciones sobre la base de datos (inserciones, modificaciones o eliminaciones de registros) que ha de realizarse de forma atmica. Una transaccin con la base de datos se inicia explcitamente llamando al mtodo StartTransaction(). Las modificaciones realizadas sobre la base de datos no se harn efectivas hasta que se invoque al mtodo Commit(). Si se quiere cancelar la transaccin en curso hay que recurrir al mtodo Rollback(), lo cual har que las operaciones efectuadas en la transaccin sean ignoradas. Mediante la propiedad TransIsolation se puede establecer la el nivel de aislamiento entre distintas transacciones. El nivel tiRepeatableRead (lecturas repetibles) ser siempre el deseable, aunque con determinados servidores SQL slo se llega a tiCommitedRead ("lecturas comprometidas") y las bases de datos de escritorio (tipo Paradox, dBase o Access) slo permiten tiDirtyRead. Una transferencia bancaria TLocateOptions Opt;
// Iniciar la transaccin Database->StartTransaction(); try { if (! Table->Locate("Cliente", cliente1, Opt)) DatabaseError("No existe el primer cliente", 0); Table->Edit(); Table->FieldValues["Saldo"] -= importe; Table->Post(); if (! Table->Locate("Cliente", cliente2, Opt)) DatabaseError("No existe el segundo cliente", 0);
file:///D|/Manuales/databases/tdatabase.html (3 of 4) [27/02/2003 16:24:30]

C++ Builder

Table->Edit(); Table->FieldValues["Saldo"] += importe; Table->Post(); // Confirmar la transaccin Database->Commit(); } catch(Exception&) { // Cancelar la transaccin Database->Rollback(); Table->Refresh(); throw; }

Cancelar los cambios realizados desde el ultimo commit/rollback


void CancelarCambios (TDatabase* ADatabase) { ADatabase->Rollback(); for (int i = ADatabase->DataSetCount - 1; i >= 0; i--) ADatabase->DataSets[i]->Refresh(); }

Fernando Berzal Galiano

file:///D|/Manuales/databases/tdatabase.html (4 of 4) [27/02/2003 16:24:30]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


Un ejemplo completo

Database Desktop
Es una herramienta incluida en los entornos de desarrollo de Borland/Inprise (Delphi, C++Builder y JBuilder) que permite crear, visualizar, consultar y ordenar tablas almacenadas en distintos formatos (como Paradox o dBase).

Visualizacin de tablas
Visualizar el contenido de las tablas BCDEMOS:holdings.dbf (en formato dBase) y BCDEMOS:vendors.db (en formato Paradox).

Creacin de tablas
Crear una tabla Paradox llamada AGENDA.DB con los siguientes campos:
q q q q q

NOMBRE (alpha, 64 caracteres) EMAIL (alpha, 32 caracteres) DIRECCIN (memo) FOTO (graphic) NACIMIENTO (date)

BDE Administrator
Panel de control de Windows Es la utilidad que permite gestionar los alias del motor de bases de datos de Borland.
file:///D|/Manuales/databases/examples/agenda.html (1 of 3) [27/02/2003 16:24:30]

C++ Builder

Creacin de alias
Creamos un nuevo alias de tipo STANDARD (el usado para tablas Paradox y dBase) y lo denominamos AGENDA. En su propiedad PATH ponemos la ruta al directorio donde hemos almacenado anteriormente la tabla AGENDA.DB. NOTA: La creacin de alias la prodramos haber realizado desde la opcin Alias Manager del Database Desktop e incluso desde el cdigo de nuestra aplicacin.

C++Builder
Desarrollo de la aplicacin
Creamos un proyecto llamado Agenda y su formulario principal lo guardamos con el nombre FormAgenda. Creamos un mdulo de datos que contendr un componente TTable denominado TableAgenda con su TDataSource asociado (dsAgenda). Tenemos que establecer las propiedades DatabaseName y TableName del componente TTable, as como la propiedad DataSet del TDataSource. Al mdulo de datos lo llamamos dmAgenda y la unidad correspondiente la guardamos como DataAgenda. Con el "Fields Editor" del men contextual de TableAgenda creamos los cinco componentes TField correspondientes a las cinco columnas de nuestra tabla. Aadimos al formulario principal los componentes necesarios para poder manejar nuestra agenda. Para que los componentes del mdulo de datos sean visibles desde el formulario hemos de aadir el #include correspondiente en el fichero .cpp del formulario. En la propiedad DataSource de todos los componentes data-aware seleccionaremos dmAgenda->dsAgenda. Hemos de llamar al mtodo Open de nuestra tabla cuando se produce el evento OnActivate del formulario. De la misma forma interceptamos el evento OnDeactivate del formulario e invocamos al mtodo Close de la tabla. Esto es equivalente a mantener la propiedad Active del conjunto de datos a true (aunque es preferible porque no tiene sentido mantener conexiones abiertas cuando no se estn utilizando). Para introducir fotos en nuestra base de datos podemos utilizar el componente
file:///D|/Manuales/databases/examples/agenda.html (2 of 3) [27/02/2003 16:24:30]

C++ Builder

OpenPictureDialog, un botn que lo llame y el mtodo LoadFromFile de TGraphicField. Tambin podemos utilizar el portapapeles de Windows para poner la imagen. NOTA: El conjunto de datos debe estar en modo edicin para poder establecer el valor de la imagen. Para evitar que los mensajes asociados al TDBNavigator aparezcan en ingls debemos interceptar el evento BeforeAction de este componente. As mismo, podemos traducir las pistas asociadas a los distintos botones del TDBNavigator (propiedad Hints) y permitir su visualizacin (ShowHints). Sera aconsejable establecer las validaciones oportunas a nivel de campos para que se slo se puedan introducir direcciones de correo electrnico vlidas. As mismo, deberamos tratar mejor la introduccin de fechas (para lo cual lo ideal es crear un componente derivado de TDateTimePicker). Para permitir bsquedas en nuestro conjunto de datos podemos utilizar filtros NOTA: Se podra crear un cuadro de dilogo genrico que nos permita realizar bsquedas sobre cualquier conjunto de datos. Para ello, nuestro dilogo TDBDlgSearch debera tener una propiedad DataSet (definida utilizando la palabra reservada __property) as como mtodos que permitan realizar la bsqueda (vg: find, findNext y findPrior), los cuales devolvern un valor booleano segn la bsqueda se haya realizado con xito o no. Tambin podramos permitir la impresin de fichas con los datos de nuestra tabla. Para ello tendramos que utilizar un TQuickReport o acceder directamente al canvas de la impresora (TPrinter). Finalmente, una vez que tengamos nuestra aplicacin terminada, podramos distribuirla generando un programa de instalacin con, por ejemplo, el InstallShield Express for C++Builder...

Fernando Berzal Galiano

file:///D|/Manuales/databases/examples/agenda.html (3 of 3) [27/02/2003 16:24:30]

C++ Builder

Curso de C++ Builder Acceso a bases de datos


SQL

SQL es el lenguaje que se utiliza usualmente para consultar y gestionar bases de datos relacionales. Los orgenes de SQL se remontan a 1974, cuando Chamberlin y Boyce publicaron el primer artculo de SEQUEL, que despus se convertira en SQL ("SEQUEL: A structured English query language", Proceedings of the ACM SIGFIDET Workshop, May 1974, pp. 249264), que estaba basado en un trabajo de E.F. Codd ("A relational model of data for large shared data banks". Commun. ACM, 13:6, 1974, pp. 377387). En 1978, el ANSI comenz a estandarizar un lenguaje de definicin de datos El comit tcnico X3H2 del ANSI reconoci la importancia del modelo relacional y, en cooperacin con el grupo correspondiente de ISO, desarroll la primera especificacin de SQL en 1986. El SQL-86 no inclua la integridad referencial, que fue aadida en el SQL-89. No obstante, los estndares SQL-86 y SQL-89 no eran adecuados para aplicaciones reales y en 1992 apareci el SQL-92 (ANSI X3.135-1992, ISO/IEC 9075:1992), el estndar actualmente utilizado por la mayor parte de las bases de datos. Una cuarta generacin de SQL, el SQL3, an est por conseguir su estandarizacin de hecho.

Visin general
El concepto fundamental de SQL es el de tabla, con una o ms columnas que tienen un nombre y un tipo (numrico, cadena, fecha...). Los datos se almacenan como filas en las tablas (tuplas). Algunos de los datos pueden ser desconocidos o inaplicables, y SQL utiliza 'null' para representar este hecho. Las bases de datos SQL son autodescriptivas: las tablas del catlogo (cuya implementacin depende del DBMS) almacenan informacin acerca de las tablas de la base de datos (metadatos). Las restricciones de integridad se utilizan para forzar el cumplimiento de determinadas condiciones ('business rules', integridad referencial...) y su violacin produce excepciones que bloquean la ejecucin de las sentencias que las ocasionan. Los disparadores [triggers] especifican acciones que el DBMS ha de realizar cada vez que se produce algn evento determinado y los procedimientos almacenados sirven para encapsular conjuntos de sentencias SQL.

DML: Lenguaje de manipulacin de datos


SELECT

SELECT [DISTINCT] lista-select | *


file:///D|/Manuales/databases/sql.html (1 of 13) [27/02/2003 16:24:31]

C++ Builder

FROM tabla, tabla . . . WHERE condicin GROUP BY columnas HAVING condicin ORDER BY columnas

Las consultas a la base de datos se realizan en SQL mediante la sentencia SELECT:

1. Recuperar todas las filas de la(s) tabla(s) especificada en FROM. Cuando se indica ms de una, se devuelve su producto cartesiano. 2. La clasula WHERE, cuando est presente, elimina las tuplas que no satisfacen la condicin. 3. La clasula GROUP BY, si existe, agrupa las tuplas que tienen los mismos valores en todas las columnas especificadas. 4. Si existe una clasula HAVING, los grupos resultantes de GROUP BY que no satisfagan la condicin se eliminan. 5. La lista de columnas separadas por comas que aparece en el SELECT determina las columnas que se devuelven (* devuelve todas). 6. DISTINCT, cuando aparece, elimina duplicados. 7. La clasula ORDER BY sirve para ordenar los valores devueltos por una consulta. Ejemplo: Visualizar todos los vuelos que tengan como origen o destino Granada

SELECT * FROM VUELOS WHERE ORIGEN='GRANADA' OR DESTINO='GRANADA'

Clasula IN Expresa la pertenencia del valor de una columna a un determinado conjunto de valores. Ejemplo: Seleccionar aquellos vuelos que tengan como origen Madrid, Barcelona o Sevilla.

SELECT * FROM VUELOS WHERE ORIGEN IN ('MADRID','BARCELONA','SEVILLA')

o tambin

SELECT *

file:///D|/Manuales/databases/sql.html (2 of 13) [27/02/2003 16:24:31]

C++ Builder

FROM VUELOS WHERE ORIGEN='MADRID' OR ORIGEN='BARCELONA' OR ORIGEN='SEVILLA'

Ejemplo: Visualizar todos los vuelos existentes excepto aquellos que llegan a Londres o a Copenhague.

SELECT * FROM VUELOS WHERE DESTINO NOT IN ('LONDRES','COPENHAGUE')

Clasula BETWEEN Sirve para establecer o expresar un rango de valores (valores extremos incluidos). Ejemplo: Recuperar todos los vuelos que salgan entre las 6 y las 12 de la maana

SELECT * FROM VUELOS WHERE HORA_SALIDA BETWEEN '06.00.00' AND '12.00.00'

equivale a

SELECT * FROM VUELOS WHERE HORA_SALIDA >= '06.00.00' AND HORA_SALIDA <= '12.00.00'

Ejemplo: La columna NUM_VUELO representa los vuelos con 6 caracteres. Los dos primeros caracteres indican la compaa a la que pertenece cada vuelo (vgt: IB Iberia, BA British Airways) y los cuatro siguientes corresponden al nmero de vuelo. Bajo estas condiciones, recuprense todos los vuelos que no pertenecen a IBERIA.

SELECT * FROM VUELOS WHERE NUM_VUELO NOT BETWEEN 'IB0000' AND 'IB9999'

Clasula LIKE Sirve para especificar, con la ayuda de metasmbolos (comodines), cadenas de caracteres que comparten ciertos caracteres: '%' equivale a una cadena de caracteres de longitud comprendida entre 0 y n (el '*' en MS-DOS) y '_' equivale a un nico carcter (igual que '?' en MS-DOS).
file:///D|/Manuales/databases/sql.html (3 of 13) [27/02/2003 16:24:31]

C++ Builder

Ejemplo: Recuperar todos los vuelos de Iberia.

SELECT * FROM VUELOS WHERE NUM_VUELO LIKE 'IB%'

SELECT * FROM VUELOS WHERE NUM_VUELOS LIKE 'IB____'

Expresiones aritmticas Pueden ser utilizadas tanto en la lista de columnas que sigue a SELECT como en la clasula WHERE. Ejemplo: Visualizar la longitud y la envergadura de todos los aviones expresando las magnitudes en pies en vez de en metros y la velocidad de crucero en mph (en lugar de Km/h).

SELECT LONGITUD*3.28, ENVERGADURA*3.28, VELOCIDAD_CRUCERO/1.6 FROM AVIONES

Funciones de agregacin Son funciones que operan con todas las filas que cumplen la condicion expuesta en la clasula WHERE. Su resultado es un nico valor. Pueden especificarse detrs de SELECT o en la clasula HAVING (nunca dentro de WHERE).
q

f(expresin) aplica una funcin (MIN,MAX,AVG,SUM,COUNT) a una expresin aritmtica en la cual debe participar, al menos, una columna. COUNT(*) cuenta el nmero de filas de una tabla.

Ejemplo: Nmero de vuelos incluidos en nuestra base de datos.

SELECT COUNT(*) FROM VUELOS

Clasula GROUP BY-HAVING Sirve para dividir una tabla en grupos de filas que comparten caractersticas comunes.

file:///D|/Manuales/databases/sql.html (4 of 13) [27/02/2003 16:24:31]

C++ Builder

Ejemplo: Primera salida y nmero de vuelos diarios para cada destino

SELECT DESTINO, MIN(HORA_SALIDA), COUNT(*) FROM VUELOS GROUP BY DESTINO

Notas:
q

q q

GROUP BY crea una serie de subtablas compuestas por las filas que comparten el mismo valor en la(s) columna(s) de agrupamiento (la columna DESTINO en el ejemplo) y las funciones de agregacin se aplican a cada subtabla de forma independiente. No se puede poner en GROUP BY una columnaque no se haya incluido en la sentencia SELECT. La clasula HAVING permite elegir aquellos grupos que se quieren visualizar y no interfiere en la agrupacin realizada por GROUP BY.

Ejemplo: Visualizar los destinos que tengan ms de dos vuelos.

SELECT DESTINO FROM VUELOS GROUP BY DESTINO HAVING COUNT(*) > 2

Ejemplo: Visualizar los vuelos de Iberia que tengan plazas libres.

SELECT NUM_VUELO, CAPACIDAD-COUNT(*) FROM RESERVAS WHERE NUM_VUELO LIKE 'IB%' GROUP BY NUM_VUELO HAVING COUNT(*)<CAPACIDAD

Valores nulos
q q

q q

Cualquier operacin aritmtica sobre un campo nulo nos devolver como resultado un valor nulo. Las funciones de agregacin ignoran los campos nulos, exceptuando la funcin COUNT. Es decir, AVG(x) no siempre ser igual a SUM(x)/COUNT(*). Dos valores nulos no son iguales ni son distintos, sino indeterminados. La expresin booleana colA=colB es falsa en cuanto colA o colB sean nulos, mientras que colA<>colB ser cierta si slo una de las dos columnas es nula (ser falsa cuando ambas sean nulas). Las columnas sobre las que haya definido un ndice nico (UNIQUE) slo pueden incluir un valor nulo (en este caso s se consideran iguales dos valores nulos). Dependiendo del sistema gestor de bases de datos, los valores nulos son mayores o menores que cualquier otro valor cuando se devuelve un conjunto de datos ordenado. DISTINCT no elimina los valores nulos repetidos. GROUP BY agrupa todos los valores nulos en un nico grupo.

file:///D|/Manuales/databases/sql.html (5 of 13) [27/02/2003 16:24:31]

C++ Builder
q

La expresin IS NULL (e IS NOT NULL) sirve en una consulta para devolver las tuplas cuyo valor para la columna indicada sea nulo (o no). Ejemplo: Visualizar las tuplas de T cuyo valor para la columna X es nulo:

SELECT * FROM T WHERE X IS NULL

Subconsultas Responden a la siguiente sintaxis:

SELECT ... FROM ... WHERE columna concatenador (SELECT ...)

El concatenador puede ser un operador de comparacin (<,>,=,<>,<=,>=) o la clasula IN. En el primer caso, la subconsulta ha de devolver un nico valor. Ejemplo: Plazas libres que hay en cada vuelo MADRID-LONDRES del da 20/02/2001.

SELECT * FROM RESERVAS WHERE FECHA_SALIDA='20.02.2001' AND NUM_VUELO IN ( SELECT NUM_VUELO FROM VUELOS WHERE ORIGEN='MADRID' AND DESTINO='LONDRES')

ANY y ALL se usan para poder utilizar operadores de comparacion con subconsultas que nos devuelvan ms de un valor como resultado:

SELECT ... FROM ... WHERE columna operador {ANY/ALL} (subconsulta)

Nota: =ANY equivale a IN. La subconsulta puede estar correlacionada con la consulta exterior: Ejemplo: Reservas cuyo nmero de plazas libres sea mayor que la media para ese mismo vuelo.
file:///D|/Manuales/databases/sql.html (6 of 13) [27/02/2003 16:24:31]

C++ Builder

SELECT * FROM RESERVAS A WHERE PLAZAS_LIBRES > (SELECT AVG(PLAZAS_LIBRES) FROM RESERVAS WHERE NUM_VUELO=A.NUM_VUELO)

A es un alias, un sobrenombre que se le da a una tabla y que debe ser nico para toda la consulta. EXISTS y NOT EXISTS se emplean para comprobar la existencia o ausencia del valor devuelto por una subconsulta: Ejemplo: Obtener los vuelos con reservas efectuadas en los cuales an quedan plzas libres, ordenando el resultado de mayor a menor nmero de plazas libres de mayor a menor. Ordenar por destino para igual nmero de plazas libres:

SELECT NUM_VUELO, DESTINO, SUM(PLAZAS-LIBRES) FROM VUELOS WHERE EXISTS (SELECT * FROM RESERVAS WHERE RESERVAS.NUM_VUELO=VUELOS.NUM_VUELO) GROUP BY NUM_VUELO ORDER BY 3 DESC, DESTINO, NUM_VUELO

Peculiaridades Algunos gestores de bases de datos incluyen extensiones no estndar como, por ejemplo, mecanismos para limitar el tamao de una consulta (que siempre se puede hacer mediante procedimientos almacenados):

q q q

IBM DB2: fetch first ... rows only Oracle: ... and rownum <= valor SQL Server: ... top valor [percent]

INSERT
La sentencia INSERT se utiliza para insertar tuplas en una tabla.

INSERT INTO tabla VALUES (valor, ...)

file:///D|/Manuales/databases/sql.html (7 of 13) [27/02/2003 16:24:31]

C++ Builder

INSERT INTO tabla SELECT ...

UPDATE

UPDATE tabla SET columna=valor, ... [WHERE condicin]

La sentencia UPDATE sirve para actualizar datos. Una clasula opcional WHERE selecciona los datos que han de modificarse. Cuando esta clasula se omite, se modifican todas las tuplas de la tabla.

DELETE

DELETE FROM tabla [WHERE condicin]

DELETE permite eliminar tuplas. Igual que UPDATE, incluye una clasula WHERE opcional.

DDL: Lenguaje de definicin de datos


El sublenguaje de definicin de datos de SQL se utiliza para crear, modificar y eliminar tablas, vistas, triggers, procedimientos almacenados, etctera. Por desgracia, no est estandarizado suficientemente por el momento y muchos detalles dependen de la base de datos que utilicemos. CREATE TABLE sirve para crear tablas, ALTER TABLE para modificarlas y DROP TABLE para eliminarlas. Se pueden definir restricciones sobre las columnas de una tabla: NOT NULL prohbe que se inserten valores nulos en una columna, UNIQUE prohbe que existan valores duplicados en una columna y CHECK restringe los valores que puede tomar una columna. Tambin se pueden definir restricciones a nivel de tabla: CHECK puede involucrar a varias columnas; las claves primarias (PRIMARY KEY) aseguran que los valores de las columnas especificadas son nicos y no nulos; finalmente, las claves externas (REFERENCES) sirven para especificar restricciones de integridad referencial (esto es, cada tupla de la tabla ha de referenciar a una tupla existente en otra tabla con los mismos valores para las columnas incluidas en la clave externa). Los tipos de datos permitidos para las columnas de las tablas varan segn el servidor que utilicemos. La siguiente tabla recoge algunos de los ms usuales: Servidor SQL estndar Cadenas Enteros Reales Nmeros Fechas Otros date time timestamp

file:///D|/Manuales/databases/sql.html (8 of 13) [27/02/2003 16:24:31]

C++ Builder

IBM DB2

char(n) varchar(n) char(n) varchar(n) char(n) varchar[2](n)

integer smallint

real=float double

InterBase

float integer=int double smallint precision

Oracle

SQL Server

int char[(n)] smallint varchar[(n)] tinyint

float[(n)] real

date [var]graphic(n) decimal(p,s) time blob,clob,dbclob timestamp numeric(p,d) blob decimal(p,d) date rowid, long [raw] number(p,s) blob, clob... date [var]binary[(n)] numeric[(p[,d])] decimal[(p[,d])] money, text, image... datetime

Las mayores diferencias suelen aparecer al manejar fechas. Por ejemplo, si queremos obtener la hora actual utilizaremos la palabra reservada "Now" en InterBase, "sysdate" en Oracle o la funcin "getdate()" en SQL Server. Aparte de los tipos de datos estndar el usuario tambin puede definir sus propios tipos: Servidor IBM DB2 InterBase Oracle Mecanismo create distinct type ... Definicin de dominios con create domain (*) create type ... Procedimiento almacenado sp_addtype (*) Creacin de reglas: create rule SQL Server Asociacin de reglas con tipos de datos: sp_bindrule Valor por defecto: create default & sp_binddefault (*) reconocidos automticamente por C++Builder

Generadores
Las distintas bases de datos ofrecen distintos mecanismos para asignar enteros diferentes a cada tupla (sin garantizar la secuencialidad de los valores): Servidor Mecanismo q Definicin de generadores con create generator q Valor establecido con set generator Generadores q Eliminacin con delete from rdb$generators where rdb$generator_name='...' q Uso con gen_id (id, incremento) q Definicin: create_sequence id increment by valor start with valor Secuencias q Uso: id.CurrVal & id.NextVal
q

Nombre

InterBase

Oracle

SQL Server Identidades

Definicin de columnas con el atributo identity (valor_inicial,incremento)

file:///D|/Manuales/databases/sql.html (9 of 13) [27/02/2003 16:24:31]

C++ Builder

Uso de generadores con C++Builder El uso correcto de generadores en C++Builder consiste en crear un procedimiento almacenado en el servidor que devuelva un valor entero e invocar a dicho procedimiento interceptanto el evento OnNewRecord o BeforePost de la tabla en la aplicacin cliente. En el servidor (InterBase):
create procedure nextID returns (cod integer) as begin cod = gen_id(ID); end ^

En el cliente (aplicacin C++Builder):


TStoredProc *spNextID void __fastcall T...::Table...BeforePost(TDataSet *DataSet) { spNextID->ExecProc(); Table...ID->Value = spNextID->ParamByName("COD")->AsInteger; }

Tambin podemos ahorrarnos trabajo y asignar la clave primaria en el trigger si la tabla no tiene columnas con valores default, existe un ndice nico, o casi nico, sobre alguna columna alternativa a la clave primaria que utilizaremos como criterio de ordenacin para la navegacin, o el valor de la clave primaria no nos importa realmente en nuestra aplicacin, como sucede con las claves artificiales. En un trigger (InterBase):
set term ^; create trigger BItabla for tabla active before insert as begin Codigo = gen_id(generador, 1); end ^

Detalles de InterBase

file:///D|/Manuales/databases/sql.html (10 of 13) [27/02/2003 16:24:31]

C++ Builder

Restricciones Valores nulos no permitidos: not null Valores por defecto: default Restricciones: check Identificacin de las restricciones: constraint Clave primaria: primary key Clave candidata: unique Clave externa: references | foreign key Acciones referenciales: (on delete|on update) (no action|cascade|set default) Columnas calculadas: computed by ndices create [unique] [asc|desc] index ... on ... alter index ... (active|inactive) set statistics index ... Consultas Valores nulos: is [not] null Sinnimos para las columnas: ... as ... Funciones de agregacin: count, sum, min, max, avg Subconsultas: in, exists Cadenas Operador like (comodines % y _) Concatenacin: || Funciones: upper, lower, trim, substring

Procedimientos almacenados y triggers en InterBase

create procedure nombre [ ( ParmetrosDeEntrada ) ] [ returns ( ParmetrosDeSalida ) ] as CuerpoDeProcedimiento create trigger nombre for tabla [active | inactive] {before | after} {delete | insert | update} [position prioridad] as CuerpoDeProcedimiento CuerpoDeProcedimiento ::= declaracin* begin ... end Declaracin de variables declare variable id tipo
file:///D|/Manuales/databases/sql.html (11 of 13) [27/02/2003 16:24:31]

C++ Builder

NB: Al usarse, los identificadores de variables van precedidos de ':' Asignacin variable = expresin Ejecucin de un procedimiento almacenado NB: No se pueden pasar expresiones como parmetros execute procedure nombre [(ParsEntrada)] [returning_values ParsSalida] select * from nombre [(ParsEntrada)], si se usa suspend dentro de un bucle Estructuras condicionales if (condicin) then instruccin [else instruccin] Bucles while (condicin) do instruccin Instrucciones SQL: insert, update, delete & singleton select vg: select columna from tabla where condicin into :variable Iteradores sobre consultas (con cursores en Oracle o SQL Server) for select into variables do instruccin Instruccin compuesta begin instruccin* end Lanzamiento de excepciones exception id Captura de excepciones (al final de un bloque begin...end) when exception id do instruccin when sqlcode n do instruccin when gdscode n do instruccin Instrucciones de control exit suspend

(similar a los iteradores del lenguaje CLU)

Variables especiales new & old (igual que en Oracle) Excepciones

file:///D|/Manuales/databases/sql.html (12 of 13) [27/02/2003 16:24:31]

C++ Builder

create exception id "mensaje" Alertas InterBase: C++Builder: componentes) UDFs User Defined Functions: DLLs + declare external function post_event mensaje Componente TIBEventAlerter (pgina Samples de la paleta de

Fernando Berzal Galiano

file:///D|/Manuales/databases/sql.html (13 of 13) [27/02/2003 16:24:31]

C++ Builder

Curso de C++ Builder Enlaces interesantes

En espaol
q

Calling Dr. Marteens


"La Cara Oculta de C++Builder" en PDF, un libro en espaol acerca del desarrollo de aplicaciones de gestin con C++Builder. Ejemplos y trucos para sacarle el mximo partido a la VCL (en Delphi y C++Builder). Muy recomendable.

Club Builder
Tutoriales, ejemplos, trucos y componentes shareware para C++Builder.

En ingls
q

Bytamin-C: The C++Builder Developer Site!


Componentes, ejemplos, artculos, trucos, noticias, enlaces y prcticamente cualquier cosa que est relacionada con C++Builder.

Borland C++Builder
La pgina oficial del C++Builder en Inprise.

The Bits
Pgina britnica con informacin, componentes y tutoriales para C++Builder.

BCBDEV.COM
Ms artculos, utilidades, ejemplos, FAQs y pistas sobre C++Builder.

Delphi Super Page


Montones de recursos para Delphi y C++Builder: componentes shareware y freeware, informacin tcnica, herramientas, etc.

file:///D|/Manuales/links/index.html (1 of 2) [27/02/2003 16:24:32]

C++ Builder

Otros sitios de inters


q

Publicaciones
r r r

C++Builder Developer's Journal C++Builder Informant Dr. Dobb's Journal

Productos relacionados
r r

Delphi InterBase

Programacin
r r r

ACCU (Association of C & C++ Users) Mathtools.net (portal tcnico para cientficos e ingenieros) Patrones de diseo (porque no todo se disea con el ratn)

Pgina principal Fernando Berzal Galiano

file:///D|/Manuales/links/index.html (2 of 2) [27/02/2003 16:24:32]

C++ Builder - ndice

Curso de C++ Builder ndice del curso

1. Introduccin 2. El IDE de C++ Builder


2.1. Una visin general del IDE de C++ Builder 2.2. Un estudio detallado del IDE de C++ Builder 2.3. El sistema de ayuda 2.4. Compilacin, ejecucin y depuracin de programas 2.5. El almacn de objetos 2.6. Ejercicios: Ejemplos de aplicaciones simples y de consola

3. Componentes en C++ Builder


3.1. Pginas de componentes. 3.2. Propiedades, mtodos y gestores de eventos. 3.3. Componentes visuales y no visuales.

4. La VCL de C++ Builder


file:///D|/Manuales/toc.html (1 of 5) [27/02/2003 16:24:32]

C++ Builder - ndice

4.1. Un paseo por la VCL. 4.2. Clases de formularios y aplicaciones. 4.3. Clases de componentes. 4.4. Restricciones al uso de la VCL en C++ Builder. 4.5. Ejercicios: Pizarra, Controles de edicin y Editor.

5. Programacin Orientada a Objetos en C++


5.1. El Paradigma de la POO en C++. 5.2. Creacin y Destruccin de Objetos. 5.3. Encapsulamiento. 5.4. Constructores y Destructores (Inicializacin de Clases I). 5.5. Herencia. 5.5.1. Herencia de Constructores y Destructores (Inicializacin de Clases II). 5.5.2. Clases Abstractas. 5.5.3. Herencia Mltiple. 5.6. Abstraccin. 5.6.1. Restricciones de acceso en C++. 5.6.2. Propiedades Virtuales. 5.7. Polimorfismo. 5.7.1. Sobrecarga de funciones..
file:///D|/Manuales/toc.html (2 of 5) [27/02/2003 16:24:32]

C++ Builder - ndice

5.7.2. Polimorfismo en las clases y mtodos virtuales..

6. Tratamiento de excepciones
6.1. Lanzamiento de excepciones. 6.2. Especificacin de excepciones. 6.3. Captura de excepciones. 6.4. Excepciones no tratadas. 6.5. Excepciones de la VCL.

7. Programacin con hebras


7.1 Introduccin 7.2 La clase TThread 7.3 Ejecucin de hebras 7.4 Coordinacin entre hebras 7.4.1 Uso de recursos compartidos 7.4.2 Sincronizacin entre hebras 7.5 Ejemplos (ZIP)

8. Acceso a bases de datos

file:///D|/Manuales/toc.html (3 of 5) [27/02/2003 16:24:32]

C++ Builder - ndice

8.1 Introduccin 8.2 El motor de bases de datos de Borland (BDE) 8.3 Componentes de acceso a bases de datos 8.4 Controles de acceso a datos 8.5 El componente TDataSource 8.6 Conjuntos de datos 8.6.1 TDataSet y sus derivados 8.6.2 Cursores 8.6.3 Actualizaciones en cach 8.6.4 El componente TTable: Tablas 8.6.5 El componente TQuery: Consultas SQL 8.6.6 El componente TStoredProc: Procedimientos almacenados 8.6.7 El componente TField: Acceso a los campos 8.7 Sesiones y conexiones 8.7.1 El componente TSession 8.7.2 El componente TDatabase 8.8 Herramientas y utilidades 8.8 Ejemplos y ejercicios Apndice: SQL

Enlaces interesantes

file:///D|/Manuales/toc.html (4 of 5) [27/02/2003 16:24:32]

C++ Builder - ndice

Volver

file:///D|/Manuales/toc.html (5 of 5) [27/02/2003 16:24:32]

C++ Builder - Apndices

Curso de C++ Builder Apndices

Listado de propiedades, mtodos y eventos de:

Aplicaciones

Formularios

Componentes

Estructura y configuracin de un proyecto de C++ Builder.

La paleta de componentes

Lista completa de mens

Pgina principal Francisco Cortijo Bon

file:///D|/Manuales/appendix/index.html [27/02/2003 16:24:32]

OOP - Ejemplo 1

Curso de C++ Builder Ejemplo 1

Corresponde al final de la seccin 5.2.5, antes de POLIMORFISMO.

EJEMPLO.CPP
//--------------------------------------------------------------------#include <vcl.h> #pragma hdrstop USERES("Ejemplo.res"); USEFORM("Ppal.cpp", PpalFrm); USEUNIT("ObjGraf.cpp"); //--------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TPpalFrm), &PpalFrm); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } //---------------------------------------------------------------------

PPAL.H
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (1 of 8) [27/02/2003 16:24:33]

OOP - Ejemplo 1

//----------------------------------------------------------------------#ifndef PpalH #define PpalH //----------------------------------------------------------------------#include #include #include #include #include <Classes.hpp> <Controls.hpp> <StdCtrls.hpp> <Forms.hpp> <ExtCtrls.hpp>

#include "ObjGraf.h" #include <Buttons.hpp> //----------------------------------------------------------------------class TPpalFrm : public TForm{__published: // IDE-managed Components TPaintBox *PaintBox; TBitBtn *BotonSalir; void __fastcall FormCreate(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); void __fastcall PaintBoxPaint(TObject *Sender); void __fastcall BotonSalirClick(TObject *Sender); private: // User declarations

public: // User declarations __fastcall TPpalFrm(TComponent* Owner); }; //----------------------------------------------------------------------extern PACKAGE TPpalFrm *PpalFrm; //----------------------------------------------------------------------#endif

PPAL.CPP
//----------------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "Ppal.h"

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (2 of 8) [27/02/2003 16:24:33]

OOP - Ejemplo 1

//----------------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TPpalFrm *PpalFrm; // Punteros a objetos de las clases derivadas. TCirculo *Cir1, *Cir2; TCuadrado *Cuad1, *Cuad2; //----------------------------------------------------------------------__fastcall TPpalFrm::TPpalFrm(TComponent* Owner): TForm(Owner) { } //----------------------------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Cir1 = new TCirculo (PaintBox, clBlack, 100, 100, Cir2 = new TCirculo (PaintBox, clGreen, 210, 40, Cuad1 = new TCuadrado (PaintBox, clRed, 200, 150, Cuad2 = new TCuadrado (PaintBox, clYellow, 120, 70, }

30); 20); 45); 25);

//----------------------------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { delete Cir1; delete Cir2; delete Cuad1; delete Cuad2; } //----------------------------------------------------------------------void __fastcall TPpalFrm::PaintBoxPaint(TObject *Sender) { Cir1->Mostrar(); Cir2->Mostrar(); Cuad1->Mostrar(); Cuad2->Mostrar(); } //----------------------------------------------------------------------void __fastcall TPpalFrm::BotonSalirClick(TObject *Sender) { Application->Terminate(); } //-----------------------------------------------------------------------

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (3 of 8) [27/02/2003 16:24:33]

OOP - Ejemplo 1

OBJGRAF.H
//----------------------------------------------------------------------#ifndef ObjGrafH #define ObjGrafH //*************************************************/ // Definicion de la clase base TObjGraf //*************************************************/ class TObjGraf { private: int FX; int FY; // Puede acceder SOLO los objetos de esta clase. // OJO: Se ha cambiado el nombre a // los miembros X e Y por FX y FY. (int _X); (int _Y); GetAncho (void) = 0; // Metodo virtual puro GetAlto (void) = 0; // Metodo virtual puro

void SetX void SetY virtual int virtual int protected:

// Pueden acceder los objetos de esta clase y // sus descendientes. FColor; *PaintBox; // OJO: Se ha cambiado Color por FColor

TColor TPaintBox public:

// Pueden usarlas todas.

// Constructor de objetos TObjGraf TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0); // Otros metodos virtual void Mostrar (void) = 0; // Metodo virtual puro // NUEVAS FORMAS DE ACCESO AL DECLARAR PRIVATE LOS MIEMBROS FX y FY. __property __property __property __property __property int int TColor int int X Y Color Ancho Alto = = = = = {read=FX, write=SetX }; {read=FY, write=SetY }; {read=FColor, write=FColor}; {read=GetAncho }; {read=GetAlto };

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (4 of 8) [27/02/2003 16:24:33]

OOP - Ejemplo 1

}; //*************************************************/ // Definicion de la clase derivada TCirculo. // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { protected: // Pueden acceder los objetos de esta clase y // sus descendientes.

int Radio; inline int GetAncho inline int GetAlto public: // Metodo constructor TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1); void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf }; //*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf { protected: // Pueden acceder los objetos de esta clase y // sus descendientes. (void) {return(Radio*2);} (void) {return(Radio*2);}

int Lado; inline int GetAncho inline int GetAlto public: // Metodos // Constructores y destructores TCuadrado (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Lado=1); void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf };
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (5 of 8) [27/02/2003 16:24:33]

(void) {return(Lado);} (void) {return(Lado);}

OOP - Ejemplo 1

//----------------------------------------------------------------------#endif

OBJGRAF.CPP
//----------------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "ObjGraf.h" //----------------------------------------------------------------------#pragma package(smart_init) /*****************************************************/ // Metodos asociados a la clase base TObjGraf /*****************************************************/ TObjGraf :: TObjGraf (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y) { PaintBox = _PaintBox; FColor = _Color; // MUY IMPORTANTE: Estas tres lineas han cambiado: FX = _X; // No se puede llamar a los metodos virtuales puros FY = _Y; // (GEtAncho, GetAlto) para fijar el valor de una // propiedad virtual (Alto, Ancho) desde un // constructor de la clase base. } // Funciones de escritura de las propiedades virtuales X e Y void TObjGraf :: SetX (int _X) { if (_X < 0) FX = 0; else if (_X > (PaintBox->Width - Ancho)) FX = PaintBox->Width - Ancho; else FX = _X; } void TObjGraf :: SetY (int _Y) { if (_Y < 0) FY = 0; else
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (6 of 8) [27/02/2003 16:24:33]

OOP - Ejemplo 1

if (_Y > (PaintBox->Height - Alto)) FY = PaintBox->Height - Alto; else FY = _Y; } /*****************************************************/ // Metodos asociados a la clase derivada TCirculo. // TCirculo deriva de la clase base TObjGraf. /*****************************************************/ TCirculo :: TCirculo (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Radio) : TObjGraf (_PaintBox, _Color, _X, _Y) { Radio = _Radio; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCirculo :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } /*****************************************************/ // Metodos asociados a la clase derivada TCuadrado. // TCuadrado deriva de la clase base TObjGraf. /*****************************************************/ TCuadrado :: TCuadrado (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Lado) : TObjGraf (_PaintBox, _Color, _X, _Y) { Lado = _Lado; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCuadrado :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Rectangle(X, Y, X+Lado, Y+Lado); }

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (7 of 8) [27/02/2003 16:24:33]

OOP - Ejemplo 1

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo1.html (8 of 8) [27/02/2003 16:24:33]

OOP - Ejemplo 2

Curso de C++ Builder Ejemplo 2


Corresponde al final de la seccin 5. En este ejemplo se muestra el POLIMORFISMO (Polimorfismo de clases y mtodos virtuales).

EJEMPLO.CPP
//----------------------------------------------------------------------

#include <vcl.h> #pragma hdrstop USERES("Ejemplo2.res"); USEFORM("Ppal.cpp", PpalFrm); USEUNIT("ObjGraf.cpp"); //---------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TPpalFrm), &PpalFrm); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } //----------------------------------------------------------------------

PPAL.H
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (1 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

//---------------------------------------------------------------------#ifndef PpalH #define PpalH //---------------------------------------------------------------------#include #include #include #include #include <Classes.hpp> <Controls.hpp> <StdCtrls.hpp> <Forms.hpp> <ExtCtrls.hpp>

#include "ObjGraf.h" #include <Buttons.hpp> //---------------------------------------------------------------------class TPpalFrm : public TForm { __published: // IDE-managed Components TPaintBox *PaintBox; TBitBtn *BotonSalir; void __fastcall FormCreate(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); void __fastcall PaintBoxPaint(TObject *Sender); void __fastcall BotonSalirClick(TObject *Sender); private: // User declarations

TObjGraf **Objs; public: // User declarations __fastcall TPpalFrm(TComponent* Owner); }; //---------------------------------------------------------------------extern PACKAGE TPpalFrm *PpalFrm; //---------------------------------------------------------------------#endif

PPAL.CPP
//---------------------------------------------------------------------#include <vcl.h>
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (2 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

#pragma hdrstop #include "Ppal.h" //---------------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TPpalFrm *PpalFrm; //---------------------------------------------------------------------__fastcall TPpalFrm::TPpalFrm(TComponent* Owner) : TForm(Owner) { }

//---------------------------------------------------------------------void __fastcall TPpalFrm::FormCreate(TObject *Sender) { Objs = new TObjGraf * [4]; Objs[0] Objs[1] Objs[2] Objs[3] } //---------------------------------------------------------------------void __fastcall TPpalFrm::FormDestroy(TObject *Sender) { for (int i=0; i<4; i++) delete Objs[i]; delete []Objs; } //---------------------------------------------------------------------void __fastcall TPpalFrm::PaintBoxPaint(TObject *Sender) { for (int i=0; i<4; i++) Objs[i]->Mostrar(); } //---------------------------------------------------------------------void __fastcall TPpalFrm::BotonSalirClick(TObject *Sender) { Application->Terminate(); } = = = = new new new new TCirculo TCuadrado TCirculo TPelota (PaintBox, (PaintBox, (PaintBox, (PaintBox, clBlack, clRed, clGreen, clYellow, 100, 100, 30); 200, 150, 45); 210, 40, 20); 120, 70, 25);

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (3 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

//----------------------------------------------------------------------

OBJGRAF.H
//---------------------------------------------------------------------#ifndef ObjGrafH #define ObjGrafH //*************************************************/ // Definicion de la clase base TObjGraf //*************************************************/ class TObjGraf { private: int FX; int FY; void SetX void SetY virtual int virtual int protected: TColor TPaintBox public: // Constructores de objetos TObjGraf TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0); TObjGraf (TObjGraf *ObjGraf); // Otros metodos virtual void Mostrar (void) = 0; // Metodo virtual puro // NUEVAS FORMAS DE ACCESO AL DECLARAR PRIVATE LOS MIEMBROS FX y FY. __property __property __property __property __property int int TColor int int X Y Color Ancho Alto = = = = = {read=FX, write=SetX }; {read=FY, write=SetY }; {read=FColor, write=FColor}; {read=GetAncho }; {read=GetAlto }; FColor; *PaintBox; (int _X); (int _Y); GetAncho (void) = 0; // Metodo virtual puro GetAlto (void) = 0; // Metodo virtual puro

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (4 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

};

//*************************************************/ // Definicion de la clase derivada TCirculo. // Deriva de la clase base TObjGraf //*************************************************/ class TCirculo : public TObjGraf { private: int FRadio; inline int GetAncho inline int GetAlto public: // Constructores TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1); // Otros metodos void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf __property int Radio = }; {read=FRadio, write=FRadio}; (void) {return(FRadio*2);} (void) {return(FRadio*2);}

//*************************************************/ // Definicion de la clase derivada TPelota. // TPelota deriva de la clase TCirculo, que a su // vez deriva de la clase base TObjGraf //*************************************************/ // Tipo definido por enumeracion para la direccion de TPelota // La codificacion es: /* NO 10 \ \ O 8 ---/ / 9 SO */
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (5 of 10) [27/02/2003 16:24:34]

N 2 | | | | 1 S

NE 6 / / ---- 4 E \ \ 5 SE

OOP - Ejemplo 2

enum TDireccion {S=1, N=2, E=4, O=8, SE=5, NE=6, SO=9, NO=10}; class TPelota: public TCirculo { private: int FDirX; int FDirY; int FVelocidad; void TDireccion public : // Constructores TPelota (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Radio=1, TDireccion _Direccion=SE, int _Velocidad=5); // Otros metodos void Mostrar (void); void Borrar (void); void Mover (void); __property int Velocidad = {read = FVelocidad, write=FVelocidad}; __property TDireccion Direccion = {read = GetDireccion, write=SetDireccion}; }; SetDireccion (TDireccion _Direccion); GetDireccion (void);

//*************************************************/ // Definicion de la clase derivada TCuadrado. // Deriva de la clase base TObjGraf //*************************************************/ class TCuadrado : public TObjGraf {private: inline int GetAncho inline int GetAlto public: // Constructores TCuadrado (TPaintBox *_PaintBox, TColor _Color=clBlack, int _X=0, int _Y=0, int _Lado=1); // Otros metodos int FLado;

(void) {return(FLado);} (void) {return(FLado);}

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (6 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

void Mostrar (void); // Instanciacion del metodo virtual puro de // la clase TObjGraf __property int Lado = }; //---------------------------------------------------------------------#endif {read=FLado, write=FLado};

OBJGRAF.CPP
//---------------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "ObjGraf.h" //---------------------------------------------------------------------#pragma package(smart_init)

/*****************************************************/ // Metodos asociados a la clase base TObjGraf /*****************************************************/ // Constructores TObjGraf :: TObjGraf (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y) { PaintBox = _PaintBox; FColor = _Color; FX = _X; FY = _Y; } TObjGraf :: TObjGraf (TObjGraf *ObjGraf) { PaintBox = ObjGraf->PaintBox; FColor = ObjGraf->Color; FX = ObjGraf->FX; FY = ObjGraf->FY; } // Funciones de escritura de las propiedades virtuales X e Y

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (7 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

void TObjGraf :: SetX (int _X) { if (_X < 0) FX = 0; else if (_X > (PaintBox->Width - Ancho)) FX = PaintBox->Width - Ancho; else FX = _X; } void TObjGraf :: SetY (int _Y) { if (_Y < 0) FY = 0; else if (_Y > (PaintBox->Height - Alto)) FY = PaintBox->Height - Alto; else FY = _Y; }

/*****************************************************/ // Metodos asociados a la clase derivada TCirculo. // TCirculo deriva de la clase base TObjGraf. /*****************************************************/ TCirculo :: TCirculo (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Radio) : TObjGraf (_PaintBox, _Color, _X, _Y) { Radio = _Radio; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCirculo :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); }

/*****************************************************/ // Metodos asociados a la clase derivada TPelota. // TPelota deriva de la clase TCirculo, que a su // vez deriva de la clase base TObjGraf /*****************************************************/ TPelota :: TPelota (TPaintBox *_PaintBox, TColor _Color,
file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (8 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

int _X, int _Y, int _Radio, TDireccion _Direccion, int _Velocidad) : TCirculo (_PaintBox, _Color, _X, _Y, _Radio) { Direccion = _Direccion; Velocidad = _Velocidad; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TPelota :: Mostrar (void) { PaintBox->Canvas->Pen->Color = clBlack; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); } // Otras funcione propias de TPelota void TPelota :: Borrar (void) { PaintBox->Canvas->Pen->Color = PaintBox->Color; PaintBox->Canvas->Brush->Color = PaintBox->Color; PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2); }

void TPelota :: Mover (void) { Borrar (); X += FDirX * Velocidad; Y += FDirY * Velocidad; Mostrar (); } void TPelota :: SetDireccion (TDireccion _Dir) { FDirY = (_Dir & 1) ? +1 : ((_Dir & 2) ? -1 : 0); FDirX = (_Dir & 4) ? +1 : ((_Dir & 8) ? -1 : 0); } TDireccion TPelota :: GetDireccion (void) { TDireccion _Dir; _Dir = (TDireccion) ((FDirY == +1) ? 1 : ((FDirY == -1 ) ? 2 : 0)); _Dir = (TDireccion) (_Dir + (FDirX == +1) ? 4 : ((FDirX == -1 ) ? 8 :0)); return (_Dir); } /*****************************************************/

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (9 of 10) [27/02/2003 16:24:34]

OOP - Ejemplo 2

// Metodos asociados a la clase derivada TCuadrado. // TCuadrado deriva de la clase base TObjGraf. /*****************************************************/ TCuadrado :: TCuadrado (TPaintBox *_PaintBox, TColor _Color, int _X, int _Y, int _Lado) : TObjGraf (_PaintBox, _Color, _X, _Y) { Lado = _Lado; } // Instanciacion del metodo virtual puro de la clase TObjGraf void TCuadrado :: Mostrar (void) { PaintBox->Canvas->Pen->Color = Color; PaintBox->Canvas->Brush->Color = Color; PaintBox->Canvas->Rectangle(X, Y, X+Lado, Y+Lado); }

Atrs Francisco Cortijo Bon

file:///D|/Manuales/intro/ejemplos/oop/Ejemplo2.html (10 of 10) [27/02/2003 16:24:34]

Estructura y configuracin de un proyecto de C++ Builder: MAIN.CPP

Curso de C++ Builder Estructura y configuracin de un proyecto


Fichero "main.cpp"
//----------------------------------------------------------------#include <vcl.h> #pragma hdrstop #include "main.h" //----------------------------------------------------------------#pragma package(smart_init) #pragma resource "*.dfm" TMainForm *MainForm; //----------------------------------------------------------------__fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner) { } //----------------------------------------------------------------void __fastcall TMainForm::ExitButtonClick(TObject *Sender) { Application->Terminate(); } //----------------------------------------------------------------void __fastcall TMainForm::FormCreate(TObject *Sender) { MainForm->Caption = "Primer programa con C++ Builder"; if (MainForm->Color == clBtnFace) MainForm->Color = clWhite; CheckBox->Checked = false; RadioButton1->Hide(); RadioButton2->Hide();

file:///D|/Manuales/appendix/project/main_cpp.html (1 of 3) [27/02/2003 16:24:34]

Estructura y configuracin de un proyecto de C++ Builder: MAIN.CPP

} //----------------------------------------------------------------void __fastcall TMainForm::CheckBoxClick(TObject *Sender) { if (CheckBox->Checked == true) { RadioButton1->Show(); RadioButton2->Show(); RadioButton1->Checked = true; OKButton->Enabled = true; } else { RadioButton1->Hide(); RadioButton2->Hide(); OKButton->Enabled = false; LabelOutput->Caption = ""; } } //----------------------------------------------------------------void __fastcall TMainForm::OKButtonClick(TObject *Sender) { if (RadioButton1->Checked) if (Edit->Text == "") LabelOutput->Caption desconocido/a"; else LabelOutput->Caption >Text; } else { if (Edit->Text == "") LabelOutput->Caption desconocido/a"; else LabelOutput->Caption >Text; } { = "Escogi Opcin 1, Sr/Sra.

= "Escogi Opcin 1, Sr/Sra. " + Edit-

= "Escogi Opcin 2, Sr/Sra.

= "Escogi Opcin 2, Sr/Sra. " + Edit-

} //-----------------------------------------------------------------

Atrs
file:///D|/Manuales/appendix/project/main_cpp.html (2 of 3) [27/02/2003 16:24:34]

Estructura y configuracin de un proyecto de C++ Builder: MAIN.CPP

Francisco Cortijo Bon

file:///D|/Manuales/appendix/project/main_cpp.html (3 of 3) [27/02/2003 16:24:34]

Estructura y configuracin de un proyecto de C++ Builder: MAIN.H

Curso de C++ Builder Estructura y configuracin de un proyecto


Fichero "main.h"
//----------------------------------------------------------------#ifndef mainH #define mainH //----------------------------------------------------------------#include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //----------------------------------------------------------------class TMainForm : public TForm { __published: // IDE-managed Components TLabel *LabelEdit; TEdit *Edit; TRadioButton *RadioButton1; TRadioButton *RadioButton2; TCheckBox *CheckBox; TButton *ExitButton; TButton *OKButton; TLabel *LabelOutput; void __fastcall ExitButtonClick(TObject *Sender); void __fastcall FormCreate(TObject *Sender); void __fastcall CheckBoxClick(TObject *Sender); void __fastcall OKButtonClick(TObject *Sender); private: // User declarations public: // User declarations __fastcall TMainForm(TComponent* Owner); }; //----------------------------------------------------------------extern PACKAGE TMainForm *MainForm; //----------------------------------------------------------------#endif
file:///D|/Manuales/appendix/project/main_h.html (1 of 2) [27/02/2003 16:24:34]

Estructura y configuracin de un proyecto de C++ Builder: MAIN.H

//-----------------------------------------------------------------

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/project/main_h.html (2 of 2) [27/02/2003 16:24:34]

Estructura y configuracin de un proyecto de C++ Builder: INICIAL.CPP

Curso de C++ Builder Estructura y configuracin de un proyecto


Fichero "Inicial.cpp"
//----------------------------------------------------------------#include <vcl.h> #pragma hdrstop USERES("Inicial.res"); USEFORM("main.cpp", MainForm); //----------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TMainForm), &MainForm); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } //-----------------------------------------------------------------

Atrs Francisco Cortijo Bon


file:///D|/Manuales/appendix/project/inicial_cpp.html [27/02/2003 16:24:35]

Estructura y configuracin de un proyecto de C++ Builder: INICIAL.BPR

Curso de C++ Builder Estructura y configuracin de un proyecto


Fichero "Inicial.bpr"
# -------------------------------------------------------------------------!if !$d(BCB) BCB = $(MAKEDIR)\.. !endif # -------------------------------------------------------------------------# IDE SECTION # -------------------------------------------------------------------------# The following section of the project makefile is managed by the BCB IDE. # It is recommended to use the IDE to change any of the values in this # section. # -------------------------------------------------------------------------VERSION = BCB.04.04 # -------------------------------------------------------------------------PROJECT = Inicial.exe OBJFILES = Inicial.obj main.obj RESFILES = Inicial.res RESDEPEN = $(RESFILES) main.dfm LIBFILES = IDLGENFILES = IDLFILES = LIBRARIES = SPARELIBS = Vcl40.lib PACKAGES = Vcl40.bpi Vclx40.bpi vcljpg40.bpi Vclmid40.bpi Vcldb40.bpi bcbsmp40.bpi \ ibsmp40.bpi vcldbx40.bpi Qrpt40.bpi TeeUI40.bpi teedb40.bpi tee40.bpi Dss40.bpi \ NMFast40.bpi Inetdb40.bpi Inet40.bpi dclocx40.bpi DEFFILE = # -------------------------------------------------------------------------PATHCPP = .;
file:///D|/Manuales/appendix/project/inicial_bpr.html (1 of 5) [27/02/2003 16:24:35]

Estructura y configuracin de un proyecto de C++ Builder: INICIAL.BPR

PATHPAS = .; PATHASM = .; PATHRC = .; DEBUGLIBPATH = $(BCB)\lib\debug RELEASELIBPATH = $(BCB)\lib\release USERDEFINES = SYSDEFINES = _RTLDLL;NO_STRICT;USEPACKAGES # -------------------------------------------------------------------------CFLAG1 = -I$(BCB)\include;$(BCB)\include\vcl -Od -Hc H=$(BCB)\lib\vcl40.csm -w -Ve -r- \ -a8 -k -y -v -vi- -c -b- -w-par -w-inl -Vx -tW -tWM \ -D$(SYSDEFINES);$(USERDEFINES) IDLCFLAGS = -I$(BCB)\include -I$(BCB)\include\vcl -src_suffixcpp PFLAGS = -U$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) \ -I$(BCB)\include;$(BCB)\include\vcl -$YD -$W -$O- -v -JPHNE -M RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zd LFLAGS = -L$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) -aa -Tpe -x -Gn -v # -------------------------------------------------------------------------ALLOBJ = c0w32.obj Memmgr.Lib $(PACKAGES) sysinit.obj $(OBJFILES) ALLRES = $(RESFILES) ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib # -------------------------------------------------------------------------!ifdef IDEOPTIONS [Version Info] IncludeVerInfo=0 AutoIncBuild=0 MajorVer=1 MinorVer=0 Release=0 Build=0 Debug=0 PreRelease=0 Special=0 Private=0 DLL=0 Locale=3082 CodePage=1252 [Version Info Keys] CompanyName= FileDescription= FileVersion=1.0.0.0 InternalName= LegalCopyright= LegalTrademarks= OriginalFilename= ProductName= ProductVersion=1.0.0.0
file:///D|/Manuales/appendix/project/inicial_bpr.html (2 of 5) [27/02/2003 16:24:35]

Estructura y configuracin de un proyecto de C++ Builder: INICIAL.BPR

Comments= [HistoryLists\hlIncludePath] Count=1 Item0=$(BCB)\include;$(BCB)\include\vcl [HistoryLists\hlLibraryPath] Count=1 Item0=$(BCB)\lib\obj;$(BCB)\lib [HistoryLists\hlDebugSourcePath] Count=1 Item0=$(BCB)\source\vcl [Debugging] DebugSourceDirs=$(BCB)\source\vcl [Parameters] RunParams= HostApplication= RemoteHost= RemotePath= RemoteDebug=0 [Compiler] InMemoryExe=0 ShowInfoMsgs=0 [CORBA] AddServerUnit=1 AddClientUnit=1 PrecompiledHeaders=1 !endif # -------------------------------------------------------------------------# MAKE SECTION # -------------------------------------------------------------------------# This section of the project file is not used by the BCB IDE. It is for # the benefit of building from the command-line using the MAKE utility. # -------------------------------------------------------------------------.autodepend # -------------------------------------------------------------------------!if !$d(BCC32) BCC32 = bcc32 !endif !if !$d(CPP32) CPP32 = cpp32 !endif
file:///D|/Manuales/appendix/project/inicial_bpr.html (3 of 5) [27/02/2003 16:24:35]

Estructura y configuracin de un proyecto de C++ Builder: INICIAL.BPR

!if !$d(DCC32) DCC32 = dcc32 !endif !if !$d(TASM32) TASM32 = tasm32 !endif !if !$d(LINKER) LINKER = ilink32 !endif !if !$d(BRCC32) BRCC32 = brcc32 !endif !if !$d(IDL2CPP) IDL2CPP = idl2cpp !endif # -------------------------------------------------------------------------!if $d(PATHCPP) .PATH.CPP = $(PATHCPP) .PATH.C = $(PATHCPP) !endif !if $d(PATHPAS) .PATH.PAS = $(PATHPAS) !endif !if $d(PATHASM) .PATH.ASM = $(PATHASM) !endif !if $d(PATHRC) .PATH.RC = $(PATHRC) !endif # -------------------------------------------------------------------------$(PROJECT): $(IDLGENFILES) $(OBJFILES) $(RESDEPEN) $(DEFFILE) $(BCB)\BIN\$(LINKER) @&&! $(LFLAGS) + $(ALLOBJ), + $(PROJECT),, + $(ALLLIB), + $(DEFFILE), + $(ALLRES) ! # -------------------------------------------------------------------------.pas.hpp: $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }

file:///D|/Manuales/appendix/project/inicial_bpr.html (4 of 5) [27/02/2003 16:24:35]

Estructura y configuracin de un proyecto de C++ Builder: INICIAL.BPR

.pas.obj: $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } .cpp.obj: $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< } .c.obj: $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< } .c.i: $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< } .cpp.i: $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< } .asm.obj: $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ .rc.res: $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< # --------------------------------------------------------------------------

Atrs Francisco Cortijo Bon

file:///D|/Manuales/appendix/project/inicial_bpr.html (5 of 5) [27/02/2003 16:24:35]

You might also like