Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

44
Casa abierta al tiempo UNIVERSIDAD AUTONOMA METROPOLITANA - IZTAPALAPA - 2,' CPJI 1'" DESARROLLADO : CRUZ GOMEZ HUMBERTO NAVARRO GUTIERREZ MARCO A. RAMOS PENAGOS ALEJANDRO Y ""-.A México, D.F. Abril de 1995

Transcript of Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Page 1: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Casa abierta al tiempo

UNIVERSIDAD AUTONOMA METROPOLITANA - IZTAPALAPA -

2,' CPJI

1'" DESARROLLADO : CRUZ GOMEZ HUMBERTO

NAVARRO GUTIERREZ MARCO A. RAMOS PENAGOS ALEJANDRO

Y ""-.A México, D.F. Abril de 1995

Page 2: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Reporte del Proyecto de Investigación II

INDICE

INTRODUCCION A LA PROGRAMACION EN WINDOWS . . . . . . . . . . . . . . . . . . . . . . . . . 1

PROGRAMANDO CON EVENTOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

COMPARTIENDO RECURSOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

WINDOWS. OBJETOS Y C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

PROGRAMACION EN WINDOWS CON OBJETOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

OBJETIVODELSISTE MA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

MENUPRINCIP AL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

DESCRIPCION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

CARACTERISTICAS TECNICAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

BIT MAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

MENU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

DIALOG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

ACCELERATORS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

ARCHIVOSDBF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

LA ESTRUCTURA DE ARCHIVOS DBASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

LOS DATOS EN DBASE I1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

EL ENCABEZADO (HEADER) EN DBASE I1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

ESTRUCTURAS DE INDICES EN DBASE I1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

LOS DATOS EN DBASE I11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

EL ENCABEZADO (HEADER) EN DBASE I11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

DIFERENCIAS ENTRE ARCHIVOS DE DBASE I1 & DBASE I11 . . . . . . . . . . . . . . . . . . . 13

ANALISIS DE ARCHIVOS DBASE CREADOR POR LA UTILERIA CLIPPER DBU . . . . 13

MODULO DE IMPRESION

INTRODUCCION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

CARACTERISTICAS TECNICAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Page 3: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Reporte del Provecto de Investigación II

ANALISIS DEL PROGRAMA PRINCIPAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

DONDE COMIENZA LA APLICACION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

USANDO EVENTOS Y MENSAJES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

DISPOSITIVOS DE SALIDAS Y VENTANAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

EL DEVICE CONTEXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

ATRIBUTOS DEL DEVICE CONTEXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

ACCESANDO AL DEVICE CONTEXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

DESPLEGANDO L A S CAPACIDADES DEL DEVICE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

MODULOSDEGRAFICACION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

GRAFICA DE BARRAS EN 2 DIMENSIONES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

CREANDO UNA GRAFICA DE BARRAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

DESPLEGANDO LA GRAFICA DE BARRAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

ESCRIBIENDO EL TITULO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

DESPLEGANDO ETIQUETAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

DIBUJANDOUNAB ARRA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

ESTRUCTURA PRINCIPAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

GRAFICA DE BARRAS EN 3 DIMENSIONES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

AÑADIENDO LA TERCERA DIMENSION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

EL FONDO (BACKDROP) EN TRES DIMENSIONES . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

LOS TOQUES FINALES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

GRAFICADEPIE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

DIBUJANDOUNSLICE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

DESPLEGANDO UNA LEYENDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

BIBLIOGRAFIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Page 4: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Rem& del Provecto . . I

INTRODUCCION A LA PROGRAMACI~N EN WINDOWS

La programación en Windows representa un cambio substancial para la mayoría

de los programadores gráficos de PC. Windows es la extensión del DOS, así que los programadores pueden tener una consistensia con menÚs, ventanas, interfaz gráficas, acciones con el mouse y cajas de diálogos. Windows hace posible ejecutar múltiples procesos simultáneos y tomar ventaja de toda la memoria disponible en la PC. Windows

demanda un nuevo estilo de programación, que a primera instancia puede parecer

bastante complicado, pero que entendiendo la filosofia de la programación orientada a

objetos, y el entorno de Windows, hacen de esta algo agradable de programar.

Windows ofrece mas de 600 funciones a través del API (Application Programmers

Interface). Esta extensa libreria nos brinda un entorno inmenso de programación. Este estilo, difiere un poco de lo que estamos acostumbrados a programar.

La programación en Windows es diferente por tres básicas razones:

1 .- Los programas estan organizados en eventos. 2.- Los recursos de la computadora están compartidas entre aplicaciones. 3.- Los programas no manipulan directamente los dispositivos (como la pantalla).

0 PROGRAMANDO CON EVENTOS

En DOS, los programas son usualmente escritos como una secuencia de pasos

agrupados en funciones. La programación en Windows, sin embargo, esta organizada

alrededor de eventos o mensajes. Un evento ocurre cuando algo dentro de Windows

cambia. Mensajes son usados para informar que un evento ha sucedido o esta cerca de ocurrir. Por ejemplo, Windows manda un mensaje llamado WM-LBUTTONDOWN

cada vez que se presiona el botón izquierdo del mouse. Un programa, entonces puede ser escrito para responder a un mensaje como WM-LBUTTONDOWN.

Una aplicación Windows divide el código, tal que responda a varios mensajes internos manejados por Windows. Por ejemplo, el mensaje WM-LBUTTONDOWN es enviado

cuando el botón izquierdo del mouse es presionado, y WM-LBUTTONUP es enviado cuando el botón es liberado. Internamente, los mensajes son simples valores enteros (constantes) que corresponden a los eventos. Las constantes de los mensajes de Windows, son definidos en el encabezado WIND0WS.H

1

Page 5: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Rep- del Prov- . .,

0 COMPARTIENDO RECURSOS

Porque en Windows, múltiples programas pueden ser ejecutados virtualmente al mismo tiempo, los programas en Windows deben compartir los recursos de la

computadora, tales como la memoria, el disco, drives, pantallas e impresoras. La compartición de recursos se da de la siguiente forma: pedir permiso para accesar a un dispositivo antes de usarlo, y liberarlo tan pronto como se finalice el trabajo con este.

0 WINDOWS, OBJETOS y C++

Por diseño, Windows está orientado a objetos. Todos los elementos de interface, tales como las ventanas, las barras de scrolls, las cajas de diálogos, etc. estan organizados

como objetos. Por ejemplo, un botón OK en una caja de diálogo puede invocar una función que verifique la entrada del usuario y la copie a un conjunto de variables.

Como programador de C++, probablemente sea confortable el hecho de que Windows organiza la interface del usuario en elementos dentro de objetos. Sin embargo,

Windows no está escrito en un lenguaje orientado a objetos. Consecuentemente, Windows tiene todos los clásicos signos de objetos, sin la sintaxis, tal como C++

PROGRAMACIÓN EN WINDOWS CON OBJETOS EN WINDOWS

Para explorar las características orientadas a objetos de C++ mientras se programa en Windows, se necesitará interactuar alrededor de las funciones de Windows. Se pueden desarrollar funciones propias, sin embargo para este proyecto, por comodidad utilizaremos las funciones Windows (OWL), las cuáles están incluidas con el

com pilador.

OWL maneja bastantes puntos de la programación en Windows, y nos da ventaja de las características de la programación orientada a objetos (OOP) de C++.

2

Page 6: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

OBJETIVO DEL SISTEMA El proyecto tiene como finalidad desarrollar un sistema editor de gráficos, que sea

capaz de graficar archivos DBF e información aleatoria introducida por el usuario.

El Sistema, además de graficar la información, proporcionará datos estadísticos de las gráficas tales como medias, varianzas, etc. Contará con una interfaz totalmente bajo

Windows para aprovechar las ventajas de las librerias OWL de C++.

A continuación se describirán en forma técnica los módulos principales que

integran al sistema, así como las herramientas adicionales que se utilizaron para su

diseño.

MENU PRINCIPAL DESCRIPCION

El menú principal del sistema, facilita el acceso a las diferentes opciones de este; todas las opciones del menú principal son activadas por el mouse, y con el uso de

teclas rápidas. Por ejemplo, para activar la opción de Archivo, este responde a la acción del mouse y a la combinación de ALT+A.

CARACTERISTICAS TÉCNICAS

El Menu Principal, fué desarrollado en el Workshop, que es una utileria de C++ para diseñar menús, cajas de diálogos, botones, íconos, etc.

El archivo que se generó en el Workshop es RUTINAS.RES; este archivo contiene

todas los gráficos de interfaz como son los íconos, menus, cajas de diálogos, de herramientas, etc. Se encuentra dividido en cuatro partes, las cuales se detallan a

continuación: - BITMAP

- MENU - DIALOG

- ACCELERATORS

3

Page 7: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Pr- . .,

0 BITMAP En el encabezado de BITMAP se tienen todos los iconos para la generación de los diferentes tipos de gráficas (Barras 2D - 3D, Pie 2D - 3D, etc), así como los íconos de funciones estadísticas con el objeto de que al hacer un clic en el icono, este mande a

llamar a su respectiva función.

En el código correspondiente al encabezado del bitmap, se tienen números cuyas

constantes se encuentran definidas en el archivo 1DENTIF.H. A continuación se

enlistan las constantes con una breve descripción de su acción.

Como se puede ver en la tabla, los iconos para las diferentes acciones se encuentran

duplicados, esto debido a que se necesita un icono (con su respectivo identificador) cuando se presenta en la caja de herramientas, y posteriormente cuando el usuario lo selecciona. Es decir, es el mismo ícono, solamente que en el momento en que es seleccionado, el icono cambia poniéndole sombra para diferenciarlo de los demás, es

por esto que cada icono tiene su doble con sombra.

4

Page 8: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

En el momento que el usuario selecciona un icono, este cambia PRESSED, para

indicar al sistema que ha sido seleccionado (NORMAL ===> PRESSED).

0 M€NU En el encabezado de MENU se tienen todas las definiciones del menú principal del sistema, tales como las de Archivo ---> Abrir, Guardar, Imprimir <---, etc. Estas opciones son las encargadas de :

1. Abrir el archivo .DBF y mandarlo a procesar. 2. Guardar los datos estadísticos generados en la graficación.

3. Capturar datos aleatorios para posteriormente graficarlos. 4. Imprimir las gráficas resultantes.

5. Salir del sistema y regresar al administrador de programas. 6. Mostrar la barra de herramientas que contiene todos los iconos explicados en la

7. Mostrar el menú de ayuda.

sección anterior.

En la siguiente tabla, se muestran los identificadores con sus respectivas acciones.

0 DIALOG En el módulo DIALOG, se encuentran las cajas de diálogos de Capturar, de

AcercaDe, y la caja de Herramientas. En la sección anterior (MENU), se definió como mandar a llamar a estas cajas, en

esta se encuentran el diseño de estas. Estas herramientas fueron diseñadas en el Resource Workshop, para ser llamadas posteriormente por el módulo de MENU.

5

Page 9: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Provecto . .. -

La caja de CAPTURAR, accede a cualquier dispositivo físico y lógico de la PC para

ser leido; así como a los directorios del dispositivo y muestra los diferentes archivos localizados en el directorio. Permite seleccionar el archivo por medio de un botón, así

como su cancelación.

La caja de DIALOG-ACERCA, muestra el logo de la UAM, así como la versión del

sistema.

El DIALOG-TOOLS, es la encargada de contener los iconos (bitmaps) definidos en la seccion BITMAP. Esta caja contiene los espacios para colocar los iconos que acceden a las diferentes acciones.

0 RCCEMRRTORS Esta sección, contiene los FILECOMMANDS, que son las activaciones de teclas

rápidas, así como la activación de la tecla Tab. Las teclas rápidas permiten ejecutar una acción sin el mouse. Por ejemplo, para activar el menú Archivo, se puede realizar con el mouse o con las teclas de A/t+A. La tecla Tab permite pasarse de opción a

opción; por ejemplo, si se encuentra marcado el botón OK, y se requiere pasar al

botón CANCELAR, presione la tecla Tab hasta que el botón requerido se encuentre

marcado.

Las 4 etapas anteriores, como se menciono anteriormente fueron diseñadas en el Resource Workshop. El archivo que los contiene es el RUTINAS.RES. La extensión

RES generada por el Resource, ya se encuentra compilada, por lo que para ligarla con el código fuente de C++, únicamente hay que incluir el archivo RUTINAS.RES en

el project UAMIGRAP.PRJ que contiene todos los archivos necesarios para la compilación del sistema. C++ liga el código que se tiene, con el archivo del Resource

para generar un Único archivo ejecutable.

6

Page 10: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del P- . .,

ARCHIVOS DBF El módulo de lectura de archivos DBF, se encarga de abrir cualquier archivo DBF,

leerlo, procesarlo y generar un archivo de salida en modo texto con los registros

seleccionados en un formato de 2 columnas (x,y) que posteriormente seran mandados a graficar. El módulo le despliega al usuario todos los campos del archivo, y le solicita que

seleccione 2 campos; una vez seleccionados, genera el archivo de salida con todos los registros que incluyen a estos campos.

A continuación se describe la estructuras de los archivos DBF, para un fácil

entendimiento del módulo.

la estructura de archivos dBase Los datos en dBasell o dBaselll son desplegados en arreglos de columnas y

renglones, como en una hoja de calculo. Un ejemplo de este es el que se muestra en la figura 1.

Los datos en un campo (o columna) son del mismo tipo (ASCII, numéricos, lógicos,

etc.). Cada nombre del campo es Único y cada registro tiene un Único número.

los datos en dBase II Los registros de datos comienzan en dBase donde finaliza el encabezado (header). Un byte precede cada registro. El valor de este byte es un espacio en ASCII (20h)

siempre y cuando el registro no haya sido borrado, en caso contrario un asterisco (2Ah) representa este byte. No hay separadores, delimitadores o terminadores

usados en los registros de datos (data records).

0 El encabezado en dBase II (Header) Los archivos en dBase I I consisten de un encabezado (file header) y un conjunto de

registros de datos. Los encabezados proveen información acerca de la estructura de los registros de datos (data records).

A continuación se describen cada uno de los bytes que conforman al archivo.

7

Page 11: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e o w l Provecto . .

8

Page 12: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Provecto . .,

ESTRUCTURA DE INDICES EN JBAS€ II La estructura de indices usadas por dBase II permiten búsquedas secuenciales y

por índices. Cada nodo de la estructura de árbol es completado a 512 bytes. El primer nodo es llamado el ancho del nodo. Este contiene información de la llave de la expresión,

del nodo raiz, del siguiente nodo disponible y del número máximo de llaves por nodo. Otros nodos son utilizados como valores de las llaves y como apuntadores de nodos inferiores.

Los archivos de índices son organizados de la siguiente manera.

9

Page 13: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

0 Todos los otros nodos están organizados en la siguiente manera:

Byte O

Numérico de 8-bits

Este es el número de llaves en este nodo.

Byte 1-51 1

Arreglo de entradas de llaves.

10

Page 14: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Reo- del Prove- . .,

0 Una entrada de llave esta organizada de la siguiente manera:

Byte 0-1

Apuntador al nivel mas bajo.

Byte 2-3

Número del registro

Byte 4-n

Expresión de la llave en ASCII.

dBASE 111 0 los datos en dBase 111

Los registros de datos comienzan en dBase donde finaliza el encabezado (header). Un byte precede cada registro. El valor de este byte es un espacio en ASCII

(20h) siempre y cuando el registro no haya sido borrado, en caso contrario un asterisco

(2Ah) representa este byte. No hay separadores, delimitadores o terminadores usados en los registros de datos (data records).

El encabezado en d6ase 111 (Header) Los archivos en dBase II consisten de un encabezado (file header) y un conjunto

de registros de datos. Los encabezados proveen información acerca de la estructura de los registros de datos (data records).

11

Page 15: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e o m del Prove- . .

12

Page 16: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e o m del Prov- . ..

DIFERENCIAS ENTRE ARCHIVOS DE dBASE II & dBASE 111

ANALISIS DE ARCHIVOS JBASE CREAROS POR LA UTlLERlA DE CLIPPER 5.0 (RBU)

A continuación se muestran los resultados obtenidos al analizar los archivos .DBF

utilizando la utileria DBVIEW del Norton Comander V. 4.0.

Como anteriormente se muestra en el análisis de archivos con formatos de dBase,

las principales partes de estos archivos son :

1 .- Header Size (Tamaño del Encabezado)

2.- Record Size (Tamaño del Registro) 3.- Data (Datos del Archivo)

13

Page 17: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Pro- . ..

En la siguiente tabla se muestran los resultados obtenidos de 4 diferentes

archivos.

Archivo 1

Header Size : 66 bytes

Record Size : 38 bytes

Número de Campos : 1

Archivo 2

Header Size : 98 bytes

Record Size : 21 bytes

Número de Campos : 2

Archivo 3

Header Size : 130 bytes

Record Size : 21 bytes

Número de Campos : 3

Archivo 4

Header Size : 162 bytes

Record Size : 40 bytes

Número de Campos : 4

Como se puede observar de los análisis mostrados anteriormente, el Header Size es directamente proporcional al número de campos con que cuente el archivo, es decir, si el archivo (.DBF) contiene en su estructura 4 campos, independientemente del número de bytes que ocupen los nombres de estos, y del tipo de información que representen (char,

entero, fecha, memo, etc.), el Header Size será siempre de 162 bytes.

Con lo que respecta al Record Size, este representa la sumatoria del tipo de

campos mas 1 byte. Es decir, si contamos con 4 campos en un archivo .DBF de la siguiente forma:

14

Page 18: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Re- del Prov- U . .. P

II NOMBRE I Chad351 11

El Record Size será de 35 + 8 + 40 + 8 = 91 + 1 = 92 bytes. En lo que concierne a la información (data) de los archivos .DBF, esta se

almacena en forma secuencial inmediatamente después de donde termina el Header Size

mas un byte.

Si seguimos con el ejemplo anterior, se tienen 4 Campos (NOMBRE,

MATRICULA, DIRECCION, FECHA-INGRESO), lo que implica un Header Size de 162

bytes, por lo cual la información comenzará en la posición 164 (el byte 164). Como se

indicó, la información se almacena en forma secuencial y en formato ASCII, lo cual facilita el acceso a esta. En caso de que el dato de un campo no cubra el ancho del campo, se completa con caracteres NULOS como se indicó en la descripción de archivos de dBase.

Otro punto interesante a comentar, es que como se indicó en el análisis de las estructuras de archivos dBase, la separación entre campo y campo es de 32 bytes.

Comenzando el primer campo en la posición número 33 (byte 33). Si continuamos con el

ejemplo que se ha estado analizando, el campo NOMBRE, aparecería en la posición

número 33, es decir la 'NI de NOMBRE se encontraría en el byte 33; el campo MATRICULA comenzaría en la posición 65, el campo DlRECClON en la 97, y el campo

FECHA-INGRESO en la posición 129.

Cabe recalcar que cuando se hace referencia a posiciones, es el equivalente a bytes. Es decir, si se indica que el campo DlRECClON comienza en la posición número

97 es equivalente a afirmar que el campo DlRECClON comienza en el byte 97.

En nuestro caso, lo que mas nos interesa es poder tomar la información de los archivos .DBF, que como ya se mencionó se encuentran secuencialmente después del HEADER SIZE. Por lo que si se conoce la longitud de cada campo (RECORD) , el RECORD SIZE y el HEADER SIZE, la lectura e interpretación de los datos se vuelve

relativamente sencilla.

15

Page 19: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

MODULO DE IMPRESION 0 INTRODUCCION

Se podría decir que imprimir dentro de Windows es simple. El driver de la impresora soportada por Windows, o inmersa con el hardware de la impresora, le dan al

programador una gran variedad independiente de acciones sobre la impresora.

En Windows se aplican ciertas reglas especiales para el uso de la impresora. La razón es debido a que son varias las aplicaciones que comparten entre sí la impresora, al igual que otros recursos del sistema. Para manejar las impresoras se utilizan los

controladores de impresora DDL y que, por lo general, se entregan junto con

Windows. A los usuarios no se les proporciona el código objeto de los controladores

de la impresora; sin embargo, en la mayoría de los casos no se necesitarán. La forma

más sencilla de manejar una impresora es considerándola como un objeto,

posiblemente como flujo de datos, en donde se acepten expresiones como la siguiente:

printecobject << “imprimiendo . . . If << end?;

No es complicado construir una clase de impresora que soporte lo anterior, sin

embargo su desventaja es el desempeño no es tan bueno cuando se trata de trabajar con gráficas, como es el caso del Sistema a desarrollar.

CARACTERISTICAS TECNICAS

En diversas aplicaciones de Windows se utilizan las bibliotecas de enlace dinámico

(DLL). Sus beneficios resultan especialmente Útiles cuando se trata de soportar

características ventajosas para aplicaciones a la vez. En vez de poner el código de

soporte en cada programa, Windows permite vincular el código a una aplicación dada

durante la ejecución misma.

Imprimir dentro de Windows es complejo. Se necesita soportar la inicialización de la

impresora (orientación, calidad de DPI, alimentación, etc.), manejar multiples salidas a la impresora, informar al usuario el porcentaje de la impresión, y permitir al usuario interrumpir la impresión. La clase que se describe a continuación, soporta todo lo anterior a excepción del porcentaje de impresión.

16

Page 20: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e m del Prov- . .,

La clase Printer requiere un constructor a la ventana del objeto Printer. Este apuntador es almacenado en una variable private. El constructor Printer usa la función miembro De/eteA//() para la inicialización de la impresora; esta función se

encarga también de inicializar la variable hDC a O. En Windows, todas las salidas a

cualquier dispositivo (pantalla, impresora, plotter, etc.) se realizan a través de un dispositivo de contexto, el cual apunta al dispositivo deseado. Por lo cual, para

imprimir un gráfico a la impresora, se necesita que el hDC sea un apuntador a la

impresora para lograr la salida deseada. Por ejemplo, para mandar una ellipse a la

impresora, la línea que manda la salida a esta sería: Elipse (h DC, x 7, y 7, x2, y2)

Si hDC esta apuntando a la impresora, la línea anterior manda la ellipse a la

impresora; para lograr la salida de la ellipse a pantalla, hay que hacer que hDC apunte a la pantalla. Lo anterior parece simple, sin embargo para acceder al apuntador a la

impresora, se necesitan realizar varias rutinas que accedan al driver de esta, para regresar el apuntador.

La idea general de la impresión del Sistema, es crear un objeto del tipo Printer al principio de la aplicación (usando el comando new), usar este objeto cuando se

necesite, y entonces eliminarlo (usando el comando delete) cuando la ventana principal se cierre. La ventaja del Sistema, es que actua sobre la impresora que se

tenga predeterminada, es decir si se necesita cambiar de impresora, lo Único que hay que hacer es ir al administrador de impresión de Windows, y seleccionar una nueva

impresora, en caso de que esta no se encuentre, basta con darla de alta y

seleccionarla como impresora predeterminada, y automáticamente el Sistema

(UAMIGFWPH) lo reconocerá. A continuación se detallan las principales funciones miembro de la clase Printer.

0 El Constructor de Printer

El constructor de la clase Printer, requiere un apuntador a la ventana que esta siendo creada. Este apuntador es almacenado en una variable private. El constructor manda

a llamar a la función De/eteA//(), la cual se encarga de inicializar a la impresora.

17

Page 21: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e m del Prov- . ..

P

0 La función miembro DeleteAllO

De/eteA// comienza checando si el objeto de la impresora esta imprimiendo un documento (InDocument == TRUE) y detiene el proceso usando la función €núDocurnent() si es necesario. Si el device context de la impresora es valido (hDC >

O ) , este libera el device context actual usando De/eteDC(). De/eteA//() entonces usa la función API de Windows GetProfileString() para leer el profile del archivo WIN.INI, GetProfileString() se e ncaraa de leer la sec ción de

WIN.INI y reoresar todo que s iaue a = (siano igual) en la primera línea en la que

comienzan los device=. Esta línea contiene el nombre de la impresora, el nombre de el archivo donde el driver de la impresora se encuentra (sin la extensión .DRV), y el nombre del dispositivo de salida (por eiemplo LPTl:). Para obtener por separado las 3 características

anteriores, se utiliza la función strtok() utilizando el delimitador de coma (,) para

obtener los parámetros anteriores.

Finalmente el Device Context para la impresora es creado usando CreateDCO,

GetDeviceCapsO es utilizado para determinar si la impresora puede soportar el manejo de bitmaps. La estructura RECT almacenada en rSize es inicializada con las

coordenadas lógicas de la impresora.

0 La función miembro SetupPrinterO

Setupprinter es llamada cuando el usuario quiere configurar el driver de la impresora predeterminada por Windows. AI llamar al driver, se pueden seleccionar parámetros

como la orientación, los fonts instalados, la memoria disponible, etc. Setupprinter()

llama a una función externa (la cual incluye una caja de diálogo externa). El driver de la impresora es requerido para manipular las características de esta. Para accesar a

este driver, se comienza utilizando la función LoadLibraryO para cargar el driver de la

impresora. Este es el nombre del archivo del driver, obtenido usando la función GetProfileString(), con la extensión .DRV. Entonces se utiliza la función GetProcAddressO para encontrar la función DEVICEMODE dentro de este archivo, y

llamar a la función a la dirección obtenida. Esta llamada resulta en la caja de diálogo que esta siendo desplegada, y la información que el usuario introduce en esta, es

automáticamente almacenada por el driver de la impresora. Setupprinter() concluye liberando la libreria.

18

Page 22: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

ReDQde del Prov- . .,

0 La función miembro StartDocument()

StartDocument() utiliza la función Escape() para enviar un SETABORTPROC a la impresora. La función Escape() es utilizada para enviar un STARTDOC a la impresora, el cual manda a la impresora lo que tiene almacenado en el buffer.

0 La función miembro Newpage()

La función Newpage() es utilizada para liberar la hoja actual y comenzar con otra. Esta utiliza la función Escape() con el código NEWFRAME, tal y como se indica a

continuación.

0 La función miembro EndDocumentO

EndDocumentO utiliza el comando de escape ENDDOC para terminar la impresión, tal y como se indica en el siguiente código:

19

Page 23: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Prove- . ., -

A continuación se listan los principales códigos de escape que soporta la función

Escape().

SELECCIONANDO LA IMPRESORA DENTRO DE LA APLICACION

Recuerde que la clase Print utiliza la impresora predeterminada por Windows en el archivo Whlni . Para permitirle al usuario que seleccione a que impresora desea la

salida, hay que leer la lista de impresoras instaladas en el archivo Win.lni. Para regresar una lista de impresoras instaladas, use NULL como segundo parámetro en la función

GetProfileString().

20

Page 24: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Prov- . .,

ANALISIS DEL PROGRAMA PRINCIPAL El codigo principal de UAMIGRAPH, se encuentra en el archivo CONTROLXPP,

el cual es el encargado de mandar a llamar a todas las demás rutinas tanto internas como

externas. A continuación se describen las partes mas relevantes de este módulo.

AI final de CONTROL.CPP podemos encontrar la llamada principal al sistema, la cual consta de las siguientes líneas:

La clase principal la conforma TUserApplication, la cual es una clase derivada de TApplication. Tambien se utiliza la clase Window. La mayoría de las aplicaciones en Windows, utilizan estas dos clases; a continuación se detallan brevemente cada una de estas.

TApplication provee los detalles de la aplicación que Windows necesita; y Window

especifica que el programa desplegará y la interacción del usuario.

También se pueden observar tipos nuevos de variables, estas nuevas definiciones de variables, son macros o tipos definidos en el encabezado WIND0WS.H. La siguiente tabla muestra algunos de estos tipos y explica brevemente que significan.

21

Page 25: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

DONDE COMIENZA LA APLICACION El origen de la aplicación se da en la función WinMain. WinMain instruye a Windows a

crear el objeto TUserApplication, el cual ejecuta la función miembro Run, y regresa un status del objeto al sistema operativo.

La función RUN esconde el secreto del comportamiento de la aplicación. Esta

contiene un bucle While que continuamente pregunta a Windows por el siguiente

mensaje a procesar y enviarlo al manejador (handle). El bucle termina cuando el

mensaje WM-QUIT ocurre.

En muchas formas, WinMain es similar a la función main de C. Como main, WinMain acepta varios argumentos, tales como los primeros dos parámetros, los

cuales son usados por Windows múltiples ocurrencias de un programa. El parámetro IpCmdLine apunta a un comando de línea, y nCmdShow indica a Windows como

inicialmente debe aparecer la ventana.

En realidad, no hay que preocuparse por estos parámetros, ellos son solamente

pasados a traves del objeto constructor TUserApplication. Estos son utilizados para que el objeto de la aplicación pueda manejar el estado actual de Windows. OWL maneja todos estos detalles por nosotros.

22

Page 26: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Prov- . .. -

USANDO €V€NTOS Y M€NSAJES Una importante parte del aprendimiento sobre escribir programas en Windows,

involucra el concepto de event-driven. Windows responde a eventos que nosotros realizamos. Por ejemplo, cuando presionamos el botón izquierdo del mouse, Windows

responde al mensaje WM-LBUTTONDOWN. Por lo tanto, para manipular la acción a este mensaje, lo Único que hay se necesita hacer es sobrecargar las funciones

miembros. WML-ButtonDown (accesible a través de la clase Window), la cual corresponde a este evento.

DISPOSITIVOS DE SALIDA Y VENTANAS Uno de los principales objetivos del GDI es un dispositivo independiente gráfico

programable. El hit es hacer que el código funcione en un display VGA, sin embargo, lo ideal es que funcione también en un display EGA, e incluso en una impresora. Windows se encarga de esto, diseñando las funciones gráficas para trabajar con tipos

devices en lugar que sobre un tipo específico de hardware. Windows soporta cuatro

tipos de devices: pantalla. impresoras y p lotters. bitmaps y a rchivos espec iales conocidos como metafiles,

Sin embargo, no todas las salidas tienen las mismas capacidades. Por ejemplo, un

plotter no soporta operaciones gráficas para plotting pixels o despliegado de bitmaps.

Y algunas impresoras no soportan todos los tipos de gráficas.

E l DEVICE CONTEXC Si analizamos el código de UAMIGFWPH, encontraremos un tipo de variable que

se repite constantemente, este es del tipo device context, el cual tiene como función primaria lo descrito en los párrafos anteriores. Windows mantiene información acerca de un tipo en particular de device, el cual llama

device context, el cual es la liga a la salida a un dispositivo. Actualmente, un device context tiene varios propósitos:

Para el manejo de gráficos utilizadas por la aplicación, tales como estilos de fonts,

rellenos, bordes, etc. Acceso a rutinas de dibujo y capacidades para un tipo específico de dispositivo.

0 Como mediador entre múltiples aplicaciones que quieren accesar al mismo dispositivo. En una pantalla, el device context se asegura de que la aplicación no

23

Page 27: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

dibuje en una zona prohibida. En una impresora, el device context mantiene la

operación de impresión separada en el administrador de impresión.

RTRIBUTOS DE1 DEVICE CONTEXT Un device context contiene todo lo concerniente a lo que se encuentra dibujando,

tales como las funciones que utiliza, el estilo de la línea, el relleno del dibujo y el font

que utiliza. La siguiente tabla lista los atributos incluidos en el device context y sus valoreres por default.

24

Page 28: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

ReDQde del Prove- . .,

P

ACC€SANDO A l DEVICE CONT€XT Un device context se encuentra definido en WIND0WS.H de tipo HDC. La

siguiente instrucción declara un manejador de tipo device context llamado hDC, tal y

como se utiliza en el sistema.

HDC hDC; Para obtener acceso a un device en particular, hay dos formas o técnicas

manejadas por C++. Una es en respuesta al mensaje WM-PAINT, la cual es generada cuando una ventana es actualizada. En este caso, las funciones Beginpaint y EndPaint son utilizadas para obtener y liberar un manejador al video

del device context. Por ejemplo, el siguiente código muestra como estas dos funciones dibujan un rectángulo en la pantalla:

La segunda forma de obtener el device context es es utilizando la función GetDC:

HDC GetDC (HWND HWindow);

Una vez que se ha obtenido el manejador, se pueden mandar todos los gráficos que deseemos. El módulo de impresión de UAMIGRAPH descrito anteriormente, utiliza

esta técnica para mandar la salida de los gráficos a la impresora.

Como se puede observar, todas las rutinas de dibujo en GDI, requeren de un manejador para ser pasado como primer argumento, e ahí la importancia de lo

descrito hasta ahora. Esta es la manera en que Windows se asegura de que se tiene

el permiso para acceder a los dispositivos de salida, y saber que dispositivo utilizar.

Después de utilizar el dispositivo, es necesario liberarlo. Esto se puede lograr

liberando el manejador por medio de la función ReleaseDC.

RealeaseDC (HWindow, hDC);

25

Page 29: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Provecto . . I

El siguiente código, muestra el uso de las funciones GetDC y ReleaseDC para

manejar un rectángulo en respuesta al click izquierdo del mouse.

DESPLEGANDO LAS CAPACIDADES DE1 DEVICE

que soporta por medio de la función GDI GetDeviceCaps.

Se pueden obtener las capacidades o propiedades del device, y las características

int GetDeviceCaps (HDC hDC, int Devicecode);

También se puede utilizar GetDeviceCaps para determinar cuando un device soporta

un tipo particular de operación, tales como una operación de bitmap o el dibujo de una curva.

26

Page 30: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

MODULOS DE GRAFICACION 0 GRAFICA DE BARRAS EN 2 DIMENSIONES

A continuación se describe el módulo de graficación en dos dimensiones, con sus

respectivas clases.

TBarGraph se encarga de los detalles de la impresión de la barra en una ventana.

La definición para la clase TBarGraph y su código se encuentra en los archivos BARGRAPH.H y BARGRAPH.CPP.

Las gráficas de barras creadas, contienen cuatro componentes primarios: un área rectangular, un título, etiquetas en el eje de las X y las Y, y las barras. La clase TBarGraph implementa todo lo que se necesita para inicializar los valores de la

gráfica y dibujarla en la ventana. A continuación se muestra la definición de la clase incluida en BARGRAPH.H

27

Page 31: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

La clase TBarGraph incluye seis variables privadas que almacenan la

información acerca que la gráfica de barras, tales como los valores de los ejes, el título de la gráfica, etc. Algunos de estas variables tienen valores por default que son inicializados en su constructor, sin embargo, todos estos valores pueden ser

modificados. La variable BarValues, es un arreglo de entreros, el cual contiene un

valor por cada barra.

La siguiente tabla, lista cada función en TBarGraph y muestra una pequeña

descripción de su comportamiento.

CREANDO UN GRAFICA DE BARRAS AI utilizar la clase TBarGraph para dibujar una gráfica, se involucran tres pasos a

seguir:

1. Crear e inicializar el objeto TBarGraph. Se puede pasar como parámetro el título de la gráfica al constructor.

2. Colocar las barras en la gráfica llamando a la función TBarGraph::AddBar

3. Llamar a la función TBarGraph::Display para dibujar la gráfica de barras.

Primero se debe de crear el objeto TBarGraph de la siguiente forma: TBarGraph *BarGraph = new TBarGraph('%ráfica de Prueba")

28

Page 32: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

del Prov- . .

La sentencia anterior aloja e inicializa un objeto TBarGraph que es apuntado por BarGraph. El constructor le da el título a la gráfica. Las barras son añadidas de izquierda a derecha, utilizando la función miembro

AddBar; por ejemplo para añadir 3 barras a la gráfica se llamaria a la función de la

siguiente manera:

El primer parámetro a AddBar es el valor de la barra, y el segundo es la etiqueta. Losvalores son almacenados en el arreglo Barvalues y las etiquetas son

almacenadas en el arreglo de caracteres BarLabels. Por lo cual, cada llamada a AddBar incrementa NumBars, el cual tiene a su cargo el número de barras en la

gráfica.

NOTA : El constructor a TBarGraph actualmente acepta dos parametros. El primero es el título, el cual es siempre requerido. El segundo parámetro es opcional.

Este especifica cuantas líneas horizontales son dibujadas en el fondo. Este

valor es almacenado en NumRules; por default el valor es 4, el cual es el

número de líneas a dibujar en caso de que ningún otro valor sea especificado:

D€SPl€GANDO LA GRAFICA D€ BARRAS Para desplegar la gráfica, se llama a la función de Display en TBarGraph.

Normalmente, se debe de llamar a Display en la función Paint.

29

Page 33: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Actualmente la función Display toma tres acciones:

1. Despliega el titulo de la gráfica. 2. Determina el máximo valor de la barra. 3. Llama a Drawchart, el cual dibuja el fondo, las barras y las etiquetas.

€SCRIBI€NDO €1 TITULO Una gráfica puede tener varios tamaños. Para compensar esto, el título de esta, se

ajusta en escala para que se encuentre dentro de las regiones ocupadas por la

gráfica.

El fonts es seleccionado llamando a la función GDI CreateFont. Una petición es

hecha por el tipo de font Roman junto con el alto y el ancho.

Un problema puede ocurrir si el título es demasiado largo, sin embargo. Para no tener

problemas con textos largos, se llama a la función GDI GetTextExtent, para ver que

tan largo es el texto actualmente, tal y como se muestra a continuación: if (LO WORD(GetText€xtent(hDC, Title, strlen(Tit1e))) > (Right-Left*W3)

Si el texto es mas largo que dos tercios del ancho de la gráfica, un nuevo tipo de font es seleccionado llamando a la función CreateFont una vez mas. En este caso, el ancho del texto es seleccionado.

Después que el titulo ha sido creado, la alineación es modificada para centrar el

string, para posteriormente desplegar el título. SetTextAlign (hDC, TA-CENTER I TA-BOTTOM); TextOut (hDC, (Left+Right)/2. Top-2, Title, strlen(Tit1e));

30

Page 34: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e D w del Prove- . .,

La siguiente sentencia en Display determina el máximo valor a ser desplegado en la

gráfica, y guarda este valor en MaxBarValue. Todas las ba rras so n a justadas al

máximo valor. Entonces, la ejecución procede a la función miembro Drawchart, la cual finaliza el dibujo de la gráfica.

DESPLEGRNDO ETIQUETAS Las etiquetas a través del eje de las Y y las líneas horizontales son pintadas en

DrawChart después de que el fondo es pintado. Recuerde, que el número de

etiquetas y las líneas horizontales depende del parámetro NumRules pasados al

constructor TBarGraph.

Como en el título de la gráfica, las etiquetas para el eje de las Y son ajustadas de

acuerdo al tamaño de la gráfica. En este caso, el ancho y la algura del font seleccionado es puesto a un sexto de separación entre las líneas horizontales y los

pixeles verticales. Esta separación es calculada en Drawchart y almacenado en la

variable Offset. Note que cada etiqueda es justificada hacia la derecha. int Offset = (Bottom-Top) / NumRules;

Los strings que aparecen debajo de las barras en el eje de las X, son escritas con el mismo tipo de font. Las etiquetas para las barras, las cuales son especificadas en las

llamadas a AddBar, son almacenadas dentro el arreglo BarLabels. Si una etiqueta no se desea para una barra en particulas, su correspondiente valor en BarLabels es puesto en NULL.

El loop For localizado al final de Drawchart despliega una barra por cada valor en BarValues, una etiqueta.

31

Page 35: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Dl6UJRNDO UNA BARRA Dentro del loop for, se hace la llamada a la función DrawBar, que es la encargada

de desplegar cada barra. Sin embargo, si se examina DrawBar se verá una simple

llamada a la función Rectangle. Esto es para hacer posible que otras aplicaciones utilicen TBarGraph para diferentes tipos de gráficas. Introduciendo el código que actualmente dibuja cada barra en la función virtual DrawBar, se puede sobrecargar

esta en clases derivadas de TBarGraph para dibujar otros tipos de barras. De hecho,

esto es lo que se hace para realizar las gráficas de pie.

La altura de cada barra depende del factor en la escala. Este valor se basa en el valor máximo de la barra a dibujar que se encuentra almacenado en MaxBarValue:

Scale = double(i3ottom - Top) / MaxBarValue;

Para determinar el ancho y el espacio de las barras,.ia idea básica es dividir los ejes

horizontales entre las barras a dibujar. La siguiente fórmula determina el espacio de

separación y almacena el resultado en Offset:

Offset = (Right - LeR) / (NumBars + 7);

32

Page 36: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

ESTRUCTURA P RlNClP Bl

La clase TBarGraphWindow derivada de Window, contiene el código que utiliza

TBarGraph. Esta clase incluye la variable BarGraph, la cual es un apuntador al objeto TBarGraph. El constructor de TBarGraphWindow dinamicamente aloja e inicializa el objeto BarGraph.

A continuación se detallan el manejo de clases utilizadas en este módulo:

La función TBarGraphWindows de Paint llama a la función TBarGraph::Display

para dibujar la gráfica:

33

Page 37: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e D W del Prove- . .

GRAFICA DE BARRAS EN 3 DIMENSIONES La gráfica que se desarrolló anteriormente en 2 dimensiones es bastante

aceptable, sin embargo, con un poco de creatividad se puede realizar una mejor. Esta es una gráfica de barras en 3 dimensiones que es la que a continuación se detalla.

Como Windows no tiene una función que dibuje gráficas en 3 dimensiones.

Desarrollaremos la clase TThreeDBar incluida en los códigos de los archivos 3DBAR.H y 3DBAR.CPP. Como la clase TBarChart, esta nueva clase contiene todas las funcionalidad que se necesita para realizar gráficas de 3 dimensiones.

Como es de esperarse, realizar una gráfica en 3 dimensiones es un poco mas

complicado que una de 2 dimensiones. Para realizar el efecto de 3 dimensiones, se tienen que dibujar cada barra dimensional, crear un fondo en 3 dimensiones, y escribir

el código necesario para las etiquetas de la gráfica. A continuación se muestra la definición de la clase TThreeDBar, la cual posee la mayoria de las funciones a utilizar.

34

Page 38: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

riÑriDlEND0 lfi T€RC€RA DIMENSION Para barras en dos dimensiones, solamente se necesita especificar la locación,

altura y ancho de la barra. Para una barra de tres dimensiones, añadiremos un parámetro de profundidad y color. Como se verá a continuación, para enfatizar la

profundidad de las barras, se añadirá sombra a los lados de las barras con un color mas obscuro que el usado en el frente.

Parte de la ilusión de la profundidad es creado añadiendo polígonos a los lados y

alto de un rectángulo. Estos polígonos son ajustados en un desplazamiento del 25 por

ciento del ancho del frente de la barra. int Depth = (Right - Left) / 4;

La primera llamada a Polygon en ThreeDBar dibuja una cara de la barra en tres

dimensiones. El color de relleno de la barra es pasado a ThreeDBar.

El color de los lados, sin embargo es mas obscuro dividiendo los componentes

del color RGB de la barra in una mitad, y recombinando estos colores en una brocha:

El alto y los lados derechos de la barra de tres dimensiones son desplegados por llamadas a Polygon.

E l FONDO (BACKDROP) EN TRES DIMENSIONES Parte de la complejidad de TThreeeDBar es la de realizar el fondo en tres

dimensiones. La geometria del fondo es similar a la utilizada para dibujar las barras dimencionales. Los panels verticales son pintados coun una brocha gris clara

(LTGRAY-BRUSH) y el piso del fondo con una brocha obscura (GRAY-BRUSH).

35

Page 39: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

Los lados de la parte de atras del fondo es dibujado utilizando la función

Rectangle y los páneles izquierdo y el de abajo son dibujados con la función Polygon. Debido a que estas dos funciones alinean los pixeles en diferente forma, debemos ajustar para la parte de abajo y la derecha del panel dibujando con

Rectangle.

Rectangle (hDC, Left + DOffset, Top - Doffset, Right + DOffset + 7, Bottom - DOffset + 7);

LOS TOQU€S FINALES Aún se necesita añadir el título y las etiquetas de la gráfica. Para esto, usaremos

los fonts por default en lugar de crear fonts dinámicos. En adición, se escribió el

código de tal forma que varios renglones de las barras puedan ser desplegados.

Como resultado, el arreglo Barvalues esta ahora como un arreglo de dos

dimensiones. También, la función GetMax esta provista para buscar en el arreglo Barvalues por el mayor valor de Y.

El código de 3DTEST.CPP, contiene las funciones que realizan los gráficos de barras en tres dimensiones.

36

Page 40: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

R e C . ..

GRAFICA DE PIE Las gráficas de pie, proveen otra tecnica para la graficación de información. A

continuación se muestra la clase TPieChart, la cual contiene todos los detalles para dibujar una gráfica de Pie y una leyenda. El código fuente para TPieChart se

encuentra en los archivos P1E.H y PIE.CPP.

Dl6UJANDO UN SLICE Para dibujar los slice (rebanadas) de la gráfica, se utilizó la función Pie de OWL.

Típicamente cada slice representa la proporción, o porcentaje, de una pieza de información en relación a la gráfica entera.

Para nuestra aplicación, se asume que se tiene una serie de valores de

porcentajes. Cada valor del porcentaje corresponde con un slice en la gráfica, y el total de los slice, representa el 100 por ciento.

Claramente, se quiere que la gráfica de pie ha ser desplegada sea circular. Sin

embargo, si se utiliza el mapping mode MM-TEXT, no se garantiza esto. Sin embargo, uno de los primeros pasos de la clase, es cambiar al mapping mode MM-ISOTROPIC.

SetMap Mode (h DC, MM- IS0 TRO PIC); SetWndowExt (hDC, rect.right, rect. bottom); SetVie wPortt5xt (hDC, rect. righf, recf. bottom);

Entonces, el origen es temporalmente cambiado a la posición que se convertirá el

centro de la gráfica de pie.

SetViewPort (hDC, rect.righü4+ 1 O, rect. bottom/2);

El radio de la gráfica de pie, es calculado para ser un cuarto del ancho de la ventana. Despues, la función miembro PieceOfPie es llamada para cada slice en la

gráfica. Esta función tiene dos responsabilidades: desplegar el slice con el color de fondo apropiado y desplegar un valor de porcentaje a lo largo del slice.

37

Page 41: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

RepQdkdel Pro- . .,

Sin embargo, desplegar el slice se logra con una simple llamada a Pie, se debe de calcular las posiciones iniciales y finales del slice. Estas coordenadas son calculadas como sigue:

StartLocX = Radius * cos(;! * PI * Startpercentage / 100. O); SfartLocY = Radius * sin(2 * PI * Startpercentage / 100.0); EndLocX = Radius * cos(2 * PI * (StartPercenfage + SlicePercentage) / 100. O); EndLocY = Radius * sin(2 * PI * (Sfattfercenfage + SlicePercentage) / 100.0);

El cálculo dentro de las funciones Seno y Coseno conviertes los valores en porcentajes del slice en radianes basados en su radio:

La variable Startpercentage especifica la suma de los porcentajes de los slice. El valor de SlicePercentage es el porcentaje del slice. El resultado de la operación es

pasado a la función miembro Pie para dibujar el slice:

Pie (hDC, -Radius, -Radius, Radius, Radius, StartLocX, StarfLocY, EndLocX, EndLocy);

El color de cada Slice, es almacenado en el arreglo Colors de TPieChart.

Determinando donde desplegar los valores de los porcentajes requiere un cálculo similar. Sin embargo, aqui el radio es extendido a un factor de 1.2. De modo, que para

compensar por las varias posiciones del texto alrededor de la gráfica de pie, el atributo de justificación del texto, se basa en el ángulo en cual el texto es alojado.

D€SPL€GANRO UNA LEWNDA AI final de la clase TPieChart, se encuentra la función Display, la rutina ShowKey

es llamada para desplegar cada slice. La leganda muestra un rectángulo y una etiqueta por cada pie slice, en el lado derecho de la pantalla. La función Rectangle es utilizada para dibujar cuadros rellenos, los cuales son de 16 pixeles en tamaño. Cabe resaltar, que el mapping mode es puesto a MM-TEXT en la función miembro Display

en el momento de realizar los cálculos.

38

Page 42: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

U J

Page 43: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

w

u) w u)

o w

n

a

n a 3 o a P

+ o I

Page 44: Casa abierta al tiempo UNIVERSIDAD AUTONOMA …

ReD- Prov- . ..

BIBLIOGRAFIA

Windows Graphics Programming with Borland C++ Loren Heiny John Wiley & Sons, Inc.

Programming Windows with Borland C++ William Roetzheim PC Magazine

Aplique Turbo C++ Herbert Schildt McGraw -Hill

Borland C++ 3.1 Programación Orientada a Objetos Faison Prentice Hall

Programación Avanzada de Gráficos en C para Windows Adams Mc Graw Hill

Advanced Graphics on VGA and XGA Card Using Borland C++ Ian O. Angel1 & Dimitrios Tsoubelis Halsted Press

39