PROGRAMACIÓN ORIENTADA A OBJETOS MEDIANTE MINGW DEVELOPER STUDIO

Tamaño: px
Comenzar la demostración a partir de la página:

Download "PROGRAMACIÓN ORIENTADA A OBJETOS MEDIANTE MINGW DEVELOPER STUDIO"

Transcripción

1 UNIVERSIDAD PONTIFICIA COMILLAS ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA (ICAI) INGENIERO EN INFORMÁTICA PROYECTO FIN DE CARRERA PROGRAMACIÓN ORIENTADA A OBJETOS MEDIANTE MINGW DEVELOPER STUDIO AUTOR: JACOBO IGLESIAS JATO MADRID, Septiembre de 2008

2 Autorizada la entrega del proyecto del alumno: Jacobo Iglesias Jato EL DIRECTOR DEL PROYECTO Eduardo Alcalde Lancharro Fdo.: Fecha: 05/ 09 / 08 VºBº DEL COORDINADOR DE PROYECTOS Eduardo Alcalde Lancharro Fdo.: Fecha: 12/ 09/ 08

3 El verdadero progreso es el que pone la tecnología al alcance de todos. Henry Ford. ( )

4 Programación Orientada a Objetos en C mediante MinGW Developer AGRADECIMIENTOS A mis padres, por darme la oportunidad de demostrar mi valía y por su gran apoyo económico y emocional durante estos cinco años de carrera. A mis hermanos, por su apoyo incondicional en los buenos y malos momentos. A Jaime, Luis y Nico, porque durante estos años han estado siempre ahí y han hecho de ellos una etapa inolvidable en mi vida. A Alba, por aguantarme y confiar en mí durante todo este tiempo. A Edu, por su apoyo y confianza durante estos últimos años. Al Director del proyecto, Eduardo, por su cercanía e inestimable ayuda a la hora de desarrollar este proyecto. A Santiago Canales, porque sin su apoyo en aquellos primeros momentos difíciles no habría alcanzado la meta. I

5 Programación Orientada a Objetos en C mediante MinGW Developer RESUMEN Se ha realizado un estudio y análisis detallado del compilador de libre difusión (freeware) MinGW Developer Dado que este compilador es freeware, se puede descargar de la red sin ningún coste si bien no trae documentación alguna. Esto es debido a que, al ser gratuito, se facilita su uso y expansión pero carece de documentación o manual de ayuda al usuario. Por esta razón se ha realizado un análisis profundo del compilador en el que se especifican todos los aspectos que faciliten al usuario su utilización como herramienta software de procesamiento de programas en los lenguajes C y C++. En el proyecto se ha llevado a cabo una explicación del entorno de desarrollo del compilador, del proceso de creación de aplicaciones, de la estructura del programa y del proceso de depuración de aplicaciones. Además, se han explicado en detalle los diferentes comandos existentes en el menú de la aplicación así como las diferentes barras que componen la interfaz. El estudio del funcionamiento del compilador en la parte que se corresponde a Orientación a Objetos también ha sido objeto de estudio del proyecto. Para ello se han explicado los diferentes conceptos clave propios de la Programación Orientada a Objetos (POO) así como los principales paradigmas que caracterizan a este enfoque de programación. Para poder llevar a cabo POO en MinGW Developer Studio es preciso emplear el lenguaje de programación C++. Este lenguaje permite programar tanto en estilo procedimental (orientado a algoritmos), como en estilo orientado a objetos, como en ambos a la vez. Por ello, se han estudiado todas las opciones que ofrece este lenguaje en cuanto a Orientación a Objetos así como las opciones que ofrece el compilador para permitir programar empleando el citado lenguaje de programación. II

6 Programación Orientada a Objetos en C mediante MinGW Developer El estudio de las librerías gráficas del compilador para permitir desarrollar interfaces gráficos de usuario (GUI) es otro de los aspectos que se abordan en el proyecto. Para ello, se ha explicado en detalle el proceso de creación de ventanas, así como el manejo de algunos elementos básicos como cuadros de diálogo o menús. Para poder llevar a cabo programación de interfaces gráficas de usuario (GUI) en MinGW Developer Studio es preciso emplear el API de Windows (WinAPI), que es un conjunto de interfaces de programación de aplicaciones (application programming interfaces - API) de Microsoft disponible en los sistemas operativos Microsoft Windows. III

7 Programación Orientada a Objetos en C mediante MinGW Developer ABSTRACT A detailed study and analysis about the freeware compiler MinGW Developer has been carried out in this project. Though this is a freeware compiler, it can be downloaded for free from the Internet without any additional costs but it does not include any documentation. This is due to the fact that being freeware makes its use and expansion easier but it lacks documentation or user help manual. For this reason, an exhaustive compiler analysis has been carried out where all the aspects that make its use as a C and C++ programs processing software tool easier are specified. A detailed explanation about several aspects of the compiler has also been carried out. Aspects such as the development environment, the applications creation process, program structure and applications debugging have been explained in a thorough way. All the different commands and bars that make the interface up have also been described. The running of the compiler in the part related to Object Oriented Programming (OOP) has also been studied. For that reason, all the different basic concepts about OOP have been explained as well as the main programming paradigms that characterize this programming approach. It is necessary to use C++ programming language to carry out OOP in MinGW Developer This language makes possible for users to program in procedural style (algorithm oriented programming) and also in object oriented style, as well as both at the same time. Due to that, all the options that this language offers related to Object Orientation have been studied as well as all the alternatives that this compiler offers to allow programming using the aforementioned programming language. The study of the compiler s graphic libraries that make graphical user interfaces (GUI) development possible is another aspect that has been tackled IV

8 Programación Orientada a Objetos en C mediante MinGW Developer in the project. Therefore, the windows creation process as well as the use of some basic elements such as dialog boxes or menus has also been explained in detail. To carry out graphical user interfaces (GUI) programming in MinGW Developer Studio it is necessary to use Windows API (WinAPI), which is a group of Microsoft s application programming interfaces available in all Microsoft Windows operative systems. V

9 Programación Orientada a Objetos en C mediante MinGW Developer ÍNDICE PARTE I: Estudio del compilador Entorno de desarrollo de MinGW Developer Studio Iniciar MinGW Developer Studio Descarga e instalación de MinGW Developer Studio Iniciar MinGW Developer Studio Crear una aplicación en lenguaje de programación C Estructura del entorno de desarrollo de MinGW Developer Studio Zonas principales Zona de workspace Zona de edición Zona de salida Barras de tareas Menú principal Barra de herramientas Depuración de programas (Debugging) Menú Debug PARTE II: Funcionamiento del compilador en la parte que corresponde a Orientación a Objetos (C++) Introducción Creación de aplicaciones C++ en MinGW Developer Studio Opciones de MinGW Developer Studio relacionadas con C Programación Orientada a Objetos (POO) en C Clase Constructor y destructor Creación de objetos Especificadores de acceso Ficheros de cabecera y espacio de nombres Ejemplo de aplicación orientada a objetos mediante MinGW Developer Studio VI

10 Programación Orientada a Objetos en C mediante MinGW Developer 3.7. Operadores de entrada/salida Modificadores Variable reservada this Métodos inline Clases y métodos friend Paradigmas de programación Encapsulamiento Ocultación Abstracción Herencia Herencia múltiple Polimorfismo Implementación de los métodos virtuales Métodos virtuales puros Clases abstractas Destructores virtuales PARTE III: Estudio de las librerías gráficas del compilador para permitir desarrollar interfaces gráficas de usuario (GUI) Introducción API de Windows (WinAPI) Introducción Características de la programación en Windows Independencia de la máquina Recursos Ventanas Eventos Controles Creación de proyectos WinAPI en MinGW Developer Componentes de una ventana Notación húngara Estructura de un programa Windows GUI VII

11 Programación Orientada a Objetos en C mediante MinGW Developer Cabeceras Prototipos Función de entrada WinMain Parámetros de entrada de WinMain Función WinMain típica Declaración Inicialización Bucle de mensajes Definición de funciones El procedimiento de ventana Sintaxis Prototipo de procedimiento de ventana Implementación de procedimiento de ventana simple Ejemplo GUI mediante MinGW Developer Studio Menús y cuadros de diálogo Menús Función MessageBox Ejemplo completo de menús y cuadros de mensaje Cuadros de diálogo Procedimiento de diálogo Paso de parámetros a un cuadro de diálogo Ejemplo completo de cuadros de diálogo Creación de recursos mediante el editor de recursos PARTE IV: Valoración y conclusiones Valoración económica y planificación Valoración económica Coste de tecnología Coste de implantación Planificación del proyecto Conclusiones Bibliografía VIII

12 PARTE I: Estudio del compilador - 1 -

13 Capítulo 1 Entorno de desarrollo de MinGW Developer Studio - 2 -

14 CAPÍTULO 1. Entorno de desarrollo de MinGW Developer El compilador MinGW Developer Studio es de libre difusión (freeware), esto es, puede descargarse de forma gratuita desde la página web de Parinya ( en las siguientes versiones: Nombre Fichero Tamaño (MB) Sistema Operativo Versión Fecha de creación Contenido 26 Windows 2.05 MinGWStudioFullSetup- 2_05.exe Entorno de desarrollo y compilador. Entorno de desarrollo y compilador. Incluye 125 Windows 2.05 MinGWStudioFullSetupPlus- 2_05.exe además las librerías wxwidgets para crear entornos gráficos. 2 Linux 2.06 Mingw-devstudio_linux tar.gz Entorno de desarrollo y compilador. Además, en caso de descargarse para el sistema operativo Windows Vista es necesario llevar a cabo los siguientes pasos: Después de instalar el compilador se debe editar la variable de entorno PATH. Esto se hace en Panel de control Sistema Configuración avanzada del sistema Propiedades del sistema Opciones avanzadas Variables de entorno

15 Añadir a la variables de entorno PATH los siguientes directorios: C:\MinGWStudio;C:\MinGWStudio\MinGW\bin;C:\MinGWStudio\MinGW\lib\gcc\mingw32\

16 Capítulo 2 Iniciar MinGW Developer Studio - 5 -

17 CAPÍTULO 2. Iniciar MinGW Developer Antes de explicar el inicio del entorno de desarrollo de MinGW Developer Studio se explicarán los pasos que hay que dar a la hora de descargar e instalar el software Descarga e instalación de MinGW Developer Para descargar el programa se accede a la página Web de Parinya ( En el apartado Download aparecen una serie de versiones del software que se pueden descargar. La versión que se recomienda descargar es la número 3 de MS-Windows por ser la más completa y la que incluye todas las herramientas disponibles para el software. Se descarga, por tanto, el fichero MinGWStudioFullSetupPlus-2_05.exe. Una vez descargado el fichero de instalación, se ejecuta y aparece un asistente de descarga del software llamado Simtel Downloader

18 Una vez que el asistente de descarga alcanza el 100% de progreso aparece el asistente de instalación de MinGW Developer Se pulsa el botón Next y se siguen los pasos del asistente en los que se solicitará la aceptación de los términos de licencia, la selección de los componentes a instalar y el directorio de instalación. Una vez instalado el software tras pulsar el botón Install aparece una ventana de confirmación de instalación donde aparecen marcadas por defecto las opciones Show Readme para ver los créditos del software y Run MinGW Developer Studio 2.05 para - 7 -

19 ejecutar la aplicación. Se desactivan las opciones que no interesen y se pulsa el botón Finish. En este momento el software ya estará instalado Iniciar MinGW Developer Para iniciar el entorno de desarrollo de MinGW Developer Studio se hace lo siguiente: i. En el escritorio de Windows, se sitúa el puntero del ratón en el menú Inicio, en la esquina inferior izquierda, y se pulsa el botón izquierdo del ratón. ii. Se elige la opción Todos los programas o Programas (Menú Inicio clásico) en el menú Inicio. iii. En el siguiente menú, se encontrará la opción MinGW Developer Studio, y se sitúa sobre ella el ratón. iv. Se elige la opción MinGW Developer Studio en el menú

20 v. Transcurrido el tiempo de carga, se muestra el escritorio de MinGW Developer - 9 -

21 Capítulo 3 Crear una aplicación en lenguaje de programación C C

22 CAPÍTULO 3. Crear una aplicación en lenguaje de programación C. Inicialmente, el área de trabajo del entorno de desarrollo está vacía. Para crear ahora la estructura de una nueva aplicación, se procede del siguiente modo: a. Se elige la opción New en el menú File (o se pulsan las teclas Ctrl y N simultáneamente) o bien se pulsa el botón herramientas. de la barra de b. A continuación, se presenta una ventana en la que se puede elegir el tipo de aplicación que se desea crear. Se selecciona la pestaña Projects y la aplicación de tipo Win32 Console Application. Ahora se procede a nombrar el proyecto escribiendo el nombre que se desea en el cuadro Project name. En el cuadro Location se permite especificar la ruta de acceso al directorio, es decir, el directorio donde se creará la carpeta de nombre igual al del proyecto y que contendrá todos los ficheros relativos

23 al proyecto (ejecutables, código fuente, etc.). Una vez especificado el nombre del proyecto y la ruta de acceso se confirma el cuadro de diálogo pulsando OK y ya se ha creado un proyecto nuevo. En el directorio especificado en el cuadro Location se habrá creado un fichero llamado nombre_del_proyecto.msp (MinGWStudio Project Files). Puede darse la situación de que el fichero creado tenga extensión *.mdsp en vez de *.msp. Esto se debe a que algunas versiones del compilador ponen dicha extensión a los ficheros de proyecto. c. El paso siguiente es crear un fichero y añadirlo al proyecto actualmente vacío. Se elige la opción New del menú File (o se pulsan las teclas Ctrl y N simultáneamente) o se pulsa el botón de la barra de herramientas. Se selecciona la pestaña Files y el fichero de tipo C/C++ Source File para crear un fichero de lenguaje de programación C (*.c) que contenga el código fuente. Se nombra el fichero (se debe añadir la extensión.c) en el cuadro File name y se confirma pulsando OK. El campo Location no debe ser modificado ya que por defecto se muestra la ruta de acceso al directorio del proyecto creado anteriormente. Además, la checkbox Add to project se encuentra activada para añadir el fichero al proyecto que se había creado previamente. Por tanto, la ruta de acceso y la checkbox no deben ser modificadas. En el directorio del proyecto se habrá creado un fichero llamado nombre_del_fichero.c (C Source File)

24 d. El entorno ya está listo para introducir el código en la zona de edición. A continuación se describirá la estructura del entorno de desarrollo así como los componentes y sus propiedades más importantes

25 Capítulo 4 Estructura del entorno de desarrollo de MinGW Developer Studio

26 CAPÍTULO 4. Estructura del entorno de desarrollo de MinGW Developer A continuación se explicará la estructura del entorno de desarrollo en su pantalla inicial. Dicha pantalla consta de tres zonas principales y dos barras de tareas Zonas principales. Se distinguen tres zonas principales: la zona de workspace, la zona de edición y la zona de salida Zona de workspace. En esta zona aparecerá el nombre del proyecto que se cree así como los diferentes ficheros asociados a él. Los ficheros son agrupados en cuatro carpetas principales en función de su tipología. Estas carpetas son presentadas

27 en estructura de árbol de tal forma que se pueden minimizar y maximizar para ocultar y ver su contenido respectivamente haciendo doble clic sobre ellas o sobre el símbolo situado a su izquierda. Las cuatro carpetas en las que son agrupados son: Source Files (Ficheros Fuente), Header Files (Ficheros de cabecera), Resource Files (Ficheros de recursos) y Other Files (Otros ficheros). Por ejemplo, en el proyecto del capítulo 3, la zona de workspace fue la siguiente: Source Files: en esta carpeta aparece el fichero fuente asociado al proyecto. Este fichero puede tener las siguientes extensiones: *.c, *.cc, *.cpp, *.cxx. Se pueden añadir ficheros fuente a un proyecto ya creado pulsando la carpeta Source Files con el botón derecho del ratón y seleccionando Add source files to project Se selecciona el fichero con la extensión apropiada y se añade al proyecto

28 Header Files: en esta carpeta aparecen los ficheros de cabecera asociados al proyecto. Estos ficheros pueden tener las siguientes extensiones: *.h, *.hh, *.hpp, *.hxx. Se pueden añadir ficheros de cabecera a un proyecto ya creado pulsando la carpeta Header Files con el botón derecho del ratón y seleccionando Add header files to project Se selecciona el fichero con la extensión apropiada y se añade al proyecto

29 Resource Files: en esta carpeta aparecen los ficheros con extensión *.rc y *.rc2 asociados al proyecto. Estos ficheros son empleados por GTK+ (GIMP Tool Kit) para tratar las opciones predeterminadas de las aplicaciones. Con ellos se pueden cambiar los colores de cualquier control, poner un dibujo de fondo, etc. GTK+ es un grupo importante de bibliotecas o rutinas para desarrollar interfaces gráficas de usuario (GUI) mediante C, C++ y otros lenguajes de programación. Se pueden añadir ficheros *.rc y *.rc2 a un proyecto ya creado pulsando la carpeta Resource Files con el botón derecho del ratón y seleccionando Add resource files to project Se selecciona el fichero con la extensión apropiada y se añade al proyecto

30 Other Files: en esta carpeta aparecen ficheros de cualquier tipo distinto a los anteriormente citados que haya sido asociado al proyecto. Al igual que en las tres carpetas anteriores, se pueden añadir ficheros a un proyecto ya creado pulsando la carpeta Other Files con el botón derecho del ratón y seleccionando Add other files to project Se selecciona el fichero con la extensión apropiada y se añade al proyecto

31 Finalmente, en la zona de workspace es posible ejecutar acciones sobre el proyecto o sus ficheros asociados pulsando con el botón derecho del ratón sobre su icono correspondiente. De esta forma se evita tener que buscar en el menú principal la opción correspondiente al comportamiento que se desea realizar. Sobre un proyecto aparecen las siguientes opciones: o Close: mismo comportamiento que File Close. o Set Active Configuration: mismo comportamiento que Build Set Active Configuration. o Settings: mismo comportamiento que Project Settings. o Build: mismo comportamiento que Build Build. o Rebuild: mismo comportamiento que Build Rebuild. o Build All Configurations: mismo comportamiento que Build Build All Configurations. o Clean: mismo comportamiento que Build Clean. o Clean All Configurations: mismo comportamiento que Build Clean All Configurations. o Execute: mismo comportamiento que Build Execute. o Export Makefile: mismo comportamiento que Project Export Makefile

32 Los comportamientos correspondientes a cada opción serán explicados en detalle en el apartado Menú principal. Por otra parte, si se pulsa con el botón derecho un fichero asociado a un determinado proyecto aparecen las siguientes opciones: o Open nombre_fichero: abre el fichero seleccionado en la zona de edición. o Compile nombre_fichero: compila el fichero seleccionado. o Remove nombre_fichero from project: elimina el fichero seleccionado del proyecto. La opción Compile nombre_fichero sólo aparece en los ficheros Source Files y en los ficheros Header Files mientras que las otras dos opciones son comunes a los cuatro tipos de ficheros que pueden asociarse a un proyecto Zona de edición. En esta zona se podrá editar el código asociado al proyecto. Dicho código es presentado al usuario en diferentes colores para permitir diferenciar segmentos de código en función de su tipología. El color verde es empleado para destacar los comentarios y observaciones que se escriban en el código mientras que el color azul se utiliza para destacar palabras clave del lenguaje de programación tales como tipos de variables (int, char, float, ), operadores ( ==, &, *, ), palabras reservadas ( do, if, for, return, ), etc. Por otra parte, las directivas del precompilador (include, define, ) se muestran en color marrón mientras que el texto a presentar con printf y el tipo de variable a leer con scanf se muestran en color púrpura. Finalmente, los nombres de variables y las funciones propias del lenguaje como printf, scanf, gets, fflush, stdin, etc. se muestran en color negro. A continuación se muestra un ejemplo de código fuente donde se observan los diferentes colores en la zona de edición según la tipología del código

33 En el ejemplo anterior también se puede observar que el compilador presenta en el lado izquierdo de la zona de edición la numeración de las líneas del código. De esta forma se facilita el seguimiento del código y la futura estimación de la complejidad del programa. Además, se ofrece la posibilidad de ocultar bloques de código independientes como declaraciones de estructuras, funciones, bloques if-else, bloques while o do-while, bloques for o incluso la propia función principal (main). De esta forma se optimiza la búsqueda de errores en código permitiendo al usuario ocultar bloques de código en los que se descarta la aparición de fallos. También hay que destacar que existe una manera de ampliar la zona de edición para facilitar la visualización del código o en caso de que el usuario tenga problemas de vista. Esta forma de hacer zoom sobre la zona de edición consiste en situarse sobre la misma y pulsar la tecla Ctrl y girar la rueda del ratón hacia atrás simultáneamente. Si, por el contrario, se pulsa la tecla Ctrl y se gira la rueda del ratón hacia delante simultáneamente entonces se disminuirá el zoom sobre la zona de edición. De esta manera tan sencilla se permite al usuario ajustar el área de visión de la zona de edición en función de sus necesidades

34 Por último, cuando se abre un fichero aparece una pestaña con su nombre en la parte superior de la zona de edición. Si se pulsa con el botón derecho sobre dicha pestaña aparecen una serie de opciones que permiten ejecutar acciones sobre el fichero sin necesidad de buscar Programación Orientada a Objetos la opción en el menú principal. Estas opciones son las siguientes: o Close: mismo comportamiento que File Close. o Save: mismo comportamiento que File Save. o Save As: mismo comportamiento que File Save As. o Find: mismo comportamiento que Edit Find. o Replace: mismo comportamiento que Edit Replace. o Print: mismo comportamiento que File Print. o Print Preview: mismo comportamiento que File Print Preview. Los comportamientos correspondientes a cada opción serán explicados en detalle en el apartado Menú principal Zona de salida. En esta zona se mostrarán mensajes acerca de las operaciones efectuadas por el compilador a la hora de compilar, enlazar y ejecutar un programa. Así mismo, se mostrará información acerca de los errores y warnings (advertencias) que se produzcan al efectuar alguna de las operaciones anteriormente comentadas. Estos mensajes serán presentados en la pestaña Build, primera de las tres pestañas de las que consta la zona de salida. La segunda pestaña (Debug) presenta información acerca de las operaciones del depurador de errores si bien el funcionamiento del mismo se verá en el capítulo 5 Depuración de programas. La tercera y última pestaña (Find in Files) se encarga de presentar los resultados de la búsqueda en ficheros, es decir, la información relativa a la búsqueda de palabras en ficheros del proyecto. La búsqueda en ficheros será explicada con mayor detalle en el apartado Menú principal. A continuación se explicará en detalle la pestaña Build donde

35 se muestran mensajes relativos a la compilación, enlazado y ejecución de programas. Bajo estas líneas se muestra un ejemplo de un programa que, tras ser compilado, presenta errores y warnings: Como se puede observar, el programa presenta tres errores y un warning. Las dos primeras líneas de la zona de salida muestran un mensaje donde se informa de que el proyecto de nombre Proyecto ha sido compilado. La segunda línea (Compiling ) es generada antes de llevarse a cabo la compilación y presenta información acerca de su resultado. La tercera línea indica el nombre del fichero compilado (programa.c) mientras que la cuarta línea indica el nombre de la función donde se han producido los errores y warnings (main). Las cuatro líneas siguientes (tantas como errores y warnings se han producido) muestran información acerca de cada uno de los errores y warnings. Por cada fallo se presenta la siguiente información: fichero en el que se ha producido el fallo, número de línea dentro del fichero en el que se ha producido el fallo, tipo de fallo (error o warning) y breve descripción del fallo producido. Hay que destacar que el warning que se muestra en el ejemplo es característico de MinGW Developer Studio ya que se debe introducir una línea en blanco al final del código fuente. En caso contrario, el compilador presentará una advertencia que, si bien no

36 afecta a la ejecución del programa, resulta molesto para el usuario. Finalmente, la última línea muestra un resumen del resultado de la compilación en el que se muestra el número total de errores y warnings que se han producido tras la compilación. Además, a la izquierda de esta información aparece el nombre de un fichero: programa.o. Este fichero es generado por el compilador al hacer la compilación y aparece en la carpeta Debug del directorio del proyecto que ha sido compilado. Una de las características que presenta el compilador en la zona de salida es la facilidad a la hora de localizar de forma rápida y precisa errores y warnings en código. Aunque el compilador informa acerca del número de línea en que se producen los errores y warnings tal y como se ha comentado anteriormente, la forma más fácil y rápida de localizar dichos fallos es haciendo doble clic sobre la línea de la zona de salida en la que se informa acerca del fallo. Una vez hecho esto, la línea correspondiente al fallo se sombreará en color amarillo y en la zona de edición se mostrará el segmento de código en el que se produjo el fallo. Dentro de este segmento faltaría localizar la línea en la que se produjo el fallo. Pues bien, esto se realiza por medio de una flecha de color verde situada en el margen izquierdo de la zona de edición. Esta flecha está situada a la derecha del número de línea en que se produjo el fallo y apunta a la línea que lo contiene. De esta forma el fallo ya ha sido localizado y se puede corregir de forma rápida sin necesidad de realizar una búsqueda en la zona de edición para encontrar la línea en que se produjo. La situación anteriormente descrita se ilustra en la siguiente captura:

37 Si en vez de realizar la compilación del programa se hiciera el enlazado del mismo, se presentarían las siguientes diferencias: La segunda línea mostraría el mensaje Compiling source file(s) en vez de Compiling ya que llevaría a cabo la compilación y enlazado de todos los ficheros fuente asociados al proyecto. En la compilación, únicamente se compila un fichero. Si el enlazado es satisfactorio se muestra el mensaje Linking antes de mostrar el resultado del enlazado sin fallos. Si por el contrario el enlazado tiene fallos, se muestran los fallos al igual que en la compilación. La última línea muestra el nombre del fichero programa.exe que se genera al hacer el enlazado y que aparece en la carpeta Debug del directorio del proyecto que ha sido compilado. Este fichero sustituye al fichero programa.o que había sido generado en la compilación dado que al realizar el enlazado también se hace la compilación. Si se realizara la ejecución del programa, la zona de salida contendría información relativa al enlazado puesto que éste es imprescindible para ejecutar

38 el programa. Si se intenta ejecutar el programa sin llevar a cabo el enlazado se presenta el siguiente cuadro de diálogo: El cuadro de diálogo sobre estas líneas informa al usuario que el fichero ha sido modificado desde el último enlazado o compilación o bien no ha sido enlazado todavía. Si se pulsa Sí el compilador llevará a cabo el enlazado (incluye la compilación) del programa y su ejecución. Si, por el contrario, se pulsa No se llevará a cabo la ejecución del programa con la última versión enlazada del fichero (el fichero *.exe en la carpeta Debug del directorio del proyecto) y, por tanto, se estará ejecutando un código distinto al que hay en la zona de edición. Si se hubiera pulsado Cancelar el cuadro de diálogo simplemente habría desaparecido Barras de tareas. Además de las zonas principales explicadas anteriormente, existen dos barras de tareas en la parte superior de la pantalla que permiten manejar las diversas opciones del programa, realizar ajustes y ejecutar de forma directa las operaciones más comunes por medio de iconos. Estas dos barras de tareas son: el menú principal y la barra de herramientas Menú principal. Consta de nueve menús que permiten al usuario llevar a cabo operaciones tales como el guardado del proyecto, la creación de un nuevo proyecto, ajustar las opciones del compilador, etc. Estos menús son: File (Archivo), Edit (Editar), View (Vista), Project (Proyecto), Build (Construir), Debug (Depurar), Tools (Herramientas), Window (Ventana) y Help (Ayuda). Cada uno de los menús será explicado con mayor detalle a continuación

39 File: Consta de catorce opciones como son New (Nuevo), Open (Abrir), Close (Cerrar), Close All (Cerrar todo), Save (Guardar), Save As (Guardar como), Save All (Guardar todo), Export (Exportar), Page Setup (Configurar página), Print (Imprimir), Print Preview (Vista previa de impresión), Recent Files (Ficheros recientes), Recent Projects (Proyectos recientes) y Exit (Salir). Programación Orientada a Objetos o New: Puede activarse también pulsando simultáneamente las teclas Ctrl y N. Esta opción permite crear un nuevo proyecto tal y como se ha explicado en el capítulo 3 si bien solo se explicó cómo crear un proyecto de aplicación de consola Win32. Hay que recordar que los programas de consola se desarrollan mediante Funciones de consola, las cuales proporcionan compatibilidad con el modo de caracteres en ventana de consola. Las bibliotecas en tiempo de ejecución del compilador MinGW Developer Studio también proporcionan entrada y salida de ventanas de consola con funciones estándar de E/S, como printf() y scanf(). Las aplicaciones de consola no tienen interfaz gráfica de usuario. Al compilarse producen un fichero.exe que se puede ejecutar como una aplicación independiente desde la línea de comandos. Otro tipo de proyecto que se puede crear es el de aplicación Win32. Una aplicación Win32 es un programa ejecutable (EXE) escrito en C o C++, que utiliza llamadas a la API Win32 para crear una interfaz gráfica de usuario. El tercer tipo de proyecto que se permite crear es el de biblioteca de vínculos dinámicos (DLL) Win32. Un fichero DLL para Win32 es un fichero binario, escrito en C o C++, que utiliza llamadas a la API Win32 en lugar de llamadas a clases

40 MFC (Microsoft Foundation Classes) y que actúa como una biblioteca compartida de funciones que pueden utilizar simultáneamente múltiples aplicaciones. El cuarto tipo de proyecto que se permite crear es el de biblioteca estática. Una biblioteca estática, también conocida como fichero, consiste en un conjunto de rutinas que son copiadas en una aplicación por el compilador o el enlazador, produciendo ficheros con código objeto y un fichero ejecutable independiente. Este proceso, y el fichero ejecutable, se conocen como construcción estática de la aplicación objetivo. La dirección real, las referencias para saltos y otras llamadas a rutinas se almacenan en una dirección relativa o simbólica, que no puede resolverse hasta que todo el código y las bibliotecas son asignados a direcciones estáticas finales. Otro tipo de proyecto que se puede crear es el de aplicación GTK+. Una aplicación GTK+ es un programa escrito en lenguaje de programación C que realiza llamadas a bibliotecas o rutinas GTK (GIMP Toolkit) para desarrollar interfaces gráficas de usuario (GUI). La gran ventaja de GTK+ es que es multiplataforma por lo que se pueden escribir programas en plataforma Windows y que éstos sean portables a plataforma Linux, por ejemplo. Además, GTK+ es software libre (bajo la licencia LGPL) y parte importante del proyecto GNU, que tiene por objetivo la creación de un sistema operativo completamente libre: el sistema GNU. El último tipo de proyecto que se puede crear es el de aplicación wxwindows (actualmente wxwidgets). Una aplicación wxwindows es un programa escrito en lenguaje de programación C++ que realiza llamadas a bibliotecas o rutinas wxwindows (wxwidgets) para desarrollar interfaces gráficas de usuario (GUI). Al igual que GTK+, wxwindows también es multiplataforma y

41 software libre (bajo la licencia LGPL). Hay que resaltar que el compilador MinGW Developer Studio fue publicado en el año 2002, un año antes de que Microsoft interpusiera una demanda contra wxwindows por una posible confusión con el nombre de su sistema operativo. Desde entonces, wxwindows recibe el nombre de wxwidgets. Las wxwidgets proporcionan una interfaz gráfica basada en las bibliotecas ya existentes en el sistema (nativas), con lo que se integran de forma óptima y resultan muy portables entre distintos sistemas operativos. El 22 de Abril de 2005 fue incluida la versión 2.6 de wxwidgets en la versión 2.05 de MinGW Developer Además de los tipos de proyecto citados anteriormente existen cuatro tipos de ficheros que se pueden crear mediante MinGW Developer Studio: C/C++ Source File (fichero fuente C/C++), C/C++ Header File (fichero de cabecera C/C++), Resource Script (script de recurso) y Text File (fichero de texto). El fichero C/C++ Source File es un fichero que contiene el código fuente del programa escrito en lenguaje de programación C o C++ y que aparecerá en la carpeta Source Files de la zona de workspace. Este fichero puede tener extensión *.c, *.cc, *.cpp o *.cxx. El fichero C/C++ Header File, sin embargo, es un fichero, a menudo en código fuente, que es incluido automáticamente en otro fichero fuente (source file) por parte del compilador. Típicamente, los ficheros de cabecera son incluidos en otro fichero fuente por medio de directivas del compilador al comienzo (o cabecera) de éste. Un fichero de cabecera contiene normalmente declaraciones de subrutinas (funciones), variables y otros identificadores. Los identificadores que necesitan ser declarados en más de un fichero fuente pueden declararse en un fichero de cabecera que será incluido posteriormente cuando su contenido sea requerido. Este

42 fichero aparecerá en la carpeta Header Files de la zona de workspace y tendrá extensión *.h, *.hh, *.hpp o *.hxx. Por otra parte, el fichero Resource Script contiene declaraciones que definen todos los elementos que serán incluidos en el fichero binario de recursos compilado (compiled binary resource file). Cada declaración describe un elemento de recurso (resource item), identificado por un ID, y parámetros adicionales (que varían en función del tipo de recurso). Un resource script puede incluso referenciar un resource item que esté almacenado en un fichero independiente, como un bitmap o un icono. Este fichero aparecerá en la carpeta Resource Files de la zona de workspace y tendrá extensión *.rc o *.rc2. Por último, el fichero Text File contiene comentarios, información administrativa (versión, desarrollador/es, fecha, etc.) y cualquier otra información que se quiera adjuntar al proyecto. Este fichero aparecerá en la carpeta Other Files de la zona de workspace y tendrá extensión *.txt. o Open: Puede activarse también pulsando simultáneamente las teclas Ctrl y O. Esta opción permite abrir un fichero de los siguientes tipos: C/C++ Files incluye Source Files, Header Files y Resource Files (extensiones *.c, *.cc, *.cpp, *.cxx, *.h, *.hh, *.hpp, *.hxx, *.rc y *.rc2), Text Files (extensión *.txt), MinGWStudio Project Files (extensión *.msp o *.mdsp) y cualquier otro fichero con extensión válida para ser abierta por el software. A continuación se muestra una captura de la ventana que aparece al pulsar la opción Open y que permite seleccionar el fichero a abrir

43 o Close: Esta opción cierra el fichero que se encuentre activo en la zona de edición. Es decir, de entre todos los ficheros que pueden encontrarse abiertos simultáneamente en la zona de edición y que se visualizan por medio de pestañas en la parte superior cierra el fichero que se esté visualizando. La opción Close se encontrará desactivada si no hay ningún fichero abierto en la zona de edición. o Close All: Esta opción cierra todos los ficheros que se encuentren abiertos simultáneamente y que se visualizan por medio de pestañas en la parte superior de la zona de edición. La opción Close All se encontrará desactivada si no hay ningún fichero abierto en la zona de edición. o Save: Puede activarse también pulsando simultáneamente las teclas Ctrl y S. Esta opción guarda los cambios efectuados en el fichero que se encuentre activo en la zona de edición. El fichero modificado es guardado en el directorio del proyecto donde se encuentra ubicado si bien la opción Save As que se verá a continuación permite guardarlo en otra ubicación diferente. La opción Save se encontrará desactivada si no se ha realizado cambio alguno en el fichero desde su último guardado o bien si no hay ningún fichero abierto en la zona de edición

44 o Save As: Esta opción guarda los cambios efectuados en el fichero que se encuentre activo en la zona de edición en una ubicación que se debe especificar. Esta opción permite, por tanto, guardar el fichero en otra ubicación diferente a la del directorio del proyecto así como renombrarlo. Una vez pulsada esta opción se muestra un cuadro de diálogo en el que se solicita la confirmación del guardado. Si se pulsa Sí (en cualquier otro caso se renuncia a guardar los cambios) aparecerá entonces un segundo cuadro de diálogo en el que se puede especificar el directorio en el que se quiere guardar el fichero, la extensión que se le quiere dar y el nombre. La opción Save As se encontrará desactivada si no hay ningún fichero abierto en la zona de edición. A continuación se muestran los cuadros de diálogo que aparecen al pulsar sobre esta opción e intentar guardar un fichero de cabecera

45 o Save All: Esta opción guarda todos los cambios efectuados en los ficheros que se encuentren abiertos y que aparezcan en las pestañas en la parte superior de la zona de edición. La opción Save All se encontrará desactivada si no se ha realizado cambio alguno en los ficheros abiertos desde la última vez que se produjo el guardado de los mismos o bien si no hay ningún fichero abierto en la zona de edición. Si alguno de ellos ha sido modificado, entonces la opción Save All llevará a cabo el guardado de todos ellos a pesar de que algunos no habían sido modificados. La única condición, por tanto, para que la opción se encuentre activa es que al menos uno de los ficheros abiertos haya sufrido cambios desde la última vez que se produjo su guardado. En tal caso el resultado de esta opción será el mismo que con la opción Save. o Export (to HTML): Esta opción permite pasar a formato HTML (HyperText Markup Language) el fichero que se muestre en la zona de edición y cuyo nombre se visualizará en la pestaña activa en la parte superior de dicha zona. Esta función es de gran utilidad dado que HTML es el lenguaje de marcado predominante para la construcción de páginas Web. Es usado para describir la estructura y el contenido en forma de texto, así como para complementar el texto con objetos tales como imágenes. Además de permitir la conversión a formato HTML también permite especificar la ubicación donde se quiere guardar el fichero ya convertido. La opción Export se encontrará desactivada si no hay ningún fichero abierto en la zona de edición. A continuación se muestra una captura del cuadro de diálogo que permite la conversión a formato HTML así como del fichero HTML resultante

46 o Page Setup: Esta opción permite configurar las opciones de página para la impresión y está muy relacionada con la opción Print que se explicará en el siguiente punto. Esta opción permite ajustar el papel a utilizar (tamaño y origen), la orientación (vertical u horizontal) y los márgenes de página (izquierdo, derecho, superior e inferior). Además, permite seleccionar la impresora a utilizar para la impresión y ajustar sus propiedades pulsando el botón Impresora. Por último, se permite

47 seleccionar para la impresión una impresora de la red (por defecto Red de Microsoft Windows) pulsando el botón Red dentro del cuadro que aparece al pulsar Impresora. La opción Page Setup se encontrará desactivada si no hay ningún fichero abierto en la zona de edición. A continuación se muestran los cuadros que aparecen al pulsar la opción Page Setup, al pulsar el botón Impresora y al pulsar el botón Red

48 o Print: Puede activarse también pulsando simultáneamente las teclas Ctrl y P. Esta opción permite imprimir el fichero que aparece en la zona de edición. Al pulsarla aparece el cuadro de impresión de Microsoft Windows donde se pueden especificar aspectos como el número de copias a imprimir, las preferencias de impresión, el intervalo de páginas a imprimir, etc. La opción Print se encontrará desactivada si no hay ningún fichero abierto en la zona de edición. A continuación se muestra el cuadro de impresión que aparece al pulsar esta opción. o Print Preview: Esta opción permite la previsualización de página antes de su impresión. Al pulsarla aparece una nueva ventana titulada MinGWStudio Preview que permite visualizar el documento que se imprimiría en caso de pulsar la opción Print. Además, esta ventana permite invocar a la opción Print directamente por medio del botón Print situado en la parte superior de forma que no hay que cerrar la ventana y pulsar la opción desde el menú File. El botón Close cierra la ventana de previsualización mientras que los cuatro botones de dirección permiten (de izquierda a derecha) ir a la primera página, retroceder, avanzar e ir a la última página respectivamente. Por último, la combo box situada en la parte derecha permite ajustar el zoom de visualización de página (desde

49 10% hasta 200%). La opción Print Preview se encontrará desactivada si no hay ningún fichero abierto en la zona de edición. A continuación se muestra una captura de la ventana MinGWStudio Preview que aparece al pulsar la opción Print Preview. o Recent Files: Esta opción muestra los ficheros que han sido abiertos más recientemente de forma que se facilita su rápida apertura sin necesidad de buscarlos en el directorio y abrirlos con la opción Open. Los ficheros se muestran ordenados por orden de visualización (el más reciente será el número 1 y el más antiguo será el último número). El máximo número de ficheros recientes que mostrará esta opción es nueve. El fichero más reciente será denotado por el nombre y su extensión mientras que los ficheros restantes mostrarán también su ruta de acceso. A continuación se muestra una captura de la opción Recent Files

50 o Recent Projects: Esta opción presenta la misma funcionalidad que la opción Recent Files en el punto anterior si bien esta opción se refiere a proyectos en vez de a ficheros. Permite, por tanto, ver los proyectos que han sido abiertos más recientemente. La única diferencia que presenta respecto de la opción Recent Files es que en este caso todos los proyectos recientes muestran la ruta de acceso además del nombre del proyecto con su correspondiente extensión (*.msp o *.mdsp). A continuación se muestra una captura de la opción Recent Projects. o Exit: Puede activarse también pulsando simultáneamente las teclas Alt y X. Esta opción cierra la aplicación. En el caso de que exista un proyecto abierto y alguno o varios de sus ficheros presenten cambios entonces la aplicación preguntará si se desean guardar cada uno de los ficheros que han sido modificados. A continuación se muestra una captura del cuadro que presenta la aplicación en caso de que un fichero presente cambios

51 Edit: Consta de dieciséis opciones como son Undo (Deshacer), Redo (Rehacer), Cut (Cortar), Copy (Copiar), Paste (Pegar), Select All (Seleccionar todo), Find (Buscar), Find Next (Buscar siguiente), Find Previous (Buscar anterior), Find in Files (Buscar en ficheros), Replace (Reemplazar), Match Brace (Encontrar llave), Go To (Ir a), Advanced (Avanzado), File Format (Formato de fichero) y Options (Opciones). Programación Orientada a Objetos o Undo: Puede activarse también pulsando simultáneamente las teclas Ctrl y Z. Esta opción permite deshacer todos los pasos dados desde la última vez que se guardó el fichero. Esta opción se encuentra desactivada si no hay ningún proyecto abierto o si hay un proyecto abierto y ninguno de sus ficheros ha sido modificado. o Redo: Puede activarse también pulsando simultáneamente las teclas Ctrl e Y. Esta opción permite rehacer la última acción realizada así como acciones que se han deshecho por medio de la opción Undo explicada anteriormente. Esta opción se encuentra desactivada si no hay ningún proyecto abierto o si hay un proyecto abierto y ninguno de sus ficheros ha sido modificado y luego se ha pulsado la opción Undo. o Cut: Puede activarse también pulsando simultáneamente las teclas Ctrl y X. Esta opción se aplica sobre trozos de código o texto, ahorrando gran trabajo cuando se quieren desplazar dichos trozos de un lugar a otro. El primer paso a la hora de cortar un texto es seleccionarlo para indicarle al programa sobre qué texto se quiere ejecutar la acción. Cuando se aplica esta opción sobre un texto, éste desaparece del lugar de origen. Para depositarlo en otro sitio se utiliza la opción Paste que se explicará posteriormente. Una vez que un texto se ha cortado permanece en la memoria mientras no se copie o corte otra cosa. Esta opción se encuentra desactivada si no hay ningún proyecto abierto o si hay un proyecto abierto y no ha sido seleccionado texto alguno

52 o Copy: Puede activarse también pulsando simultáneamente las teclas Ctrl y C. Esta opción, al igual que la anterior, se aplica sobre trozos de código o texto y permite repetir sentencias de código, bucles, etc. Al igual que en el caso anterior, el primer paso es seleccionar el texto a copiar. El texto copiado no desaparece del lugar de origen, pero el ordenador ha creado una copia de él. Para depositarlo en otro sitio se utiliza la opción Paste que se explicará posteriormente. Una vez que un texto se ha copiado permanece en la memoria mientras no se copie o corte otra cosa. Así, si se necesita volver a pegar ese mismo texto no hace falta volver a copiar. Esta opción se encuentra desactivada si no hay ningún proyecto abierto o si hay un proyecto abierto y no ha sido seleccionado texto alguno. o Paste: Puede activarse también pulsando simultáneamente las teclas Ctrl y V. Esta opción permite pegar el texto copiado o cortado y del cual el ordenador ha creado una copia que permanece en la memoria mientras no se copie o corte otra cosa. Esta opción se encuentra desactivada si no hay ningún proyecto abierto o si hay un proyecto abierto y no ha sido copiado o cortado texto alguno. o Select All: Puede activarse también pulsando simultáneamente las teclas Ctrl y A. Esta opción permite seleccionar todo el texto del fichero que se encuentre abierto en la zona de edición. Esta opción se encuentra desactivada si no hay ningún fichero en la zona de edición. o Find: Puede activarse también pulsando simultáneamente las teclas Ctrl y F. Esta opción permite buscar palabras y frases en el fichero que se encuentre abierto en la zona de edición. A continuación se muestra una captura del cuadro que aparece al pulsar sobre esta opción y que ayudará en la explicación

53 En el cuadro de texto Find what hay que escribir la palabra o frase a buscar. La caja Direction permite seleccionar si la búsqueda a realizar va a ser de abajo a arriba desde la posición actual (seleccionada opción Up) o de arriba abajo (seleccionada opción Down) en el texto. La checkbox Match whole word only permite especificar que solo se presenten los resultados de palabras que coincidan exactamente con la palabra a buscar y que no esté contenida o sea parte de otra. La checkbox Match case permite presentar resultados independientemente de si éstos están en mayúsculas o en minúsculas. Por último, la checkbox Wrap around, que por defecto se encuentra activada, permite reanudar la búsqueda desde el principio una vez que ésta ha llegado al final. Actúa, por tanto, de forma circular. Una vez que se ha introducido la palabra o frase a buscar y se han activado las opciones que interesen se pulsa el botón Find Next que sombreará en el propio texto de la zona de edición el resultado de la búsqueda (match). Si el resultado no es el que se buscaba se pulsará de nuevo el botón Find Next para reanudarla y así sucesivamente hasta encontrar el resultado esperado. La opción Find se encuentra desactivada si no hay ningún fichero en la zona de edición. o Find Next: Puede activarse también pulsando la tecla F3. Esta opción permite ver el siguiente resultado de la búsqueda efectuada con la opción Find. Su funcionamiento es igual al del botón Find Next que aparece en el cuadro de búsqueda de la opción Find explicado anteriormente. En caso de que se pulse sobre la opción Find Next sin haber iniciado una búsqueda se ejecutará la opción Find. La opción Find Next se encuentra desactivada si no hay ningún fichero en la zona de edición

54 o Find Previous: Puede activarse también pulsando simultáneamente las teclas Shift y F3. Esta opción permite ver el resultado anterior de la búsqueda efectuada con la opción Find. Su funcionamiento es igual al de la opción Find Next con la diferencia de que se muestra el resultado anterior en vez del resultado siguiente. En caso de que se pulse sobre la opción Find Previous sin haber iniciado una búsqueda se ejecutará la opción Find. La opción Find Previous se encuentra desactivada si no hay ningún fichero en la zona de edición. o Find in Files: Esta opción permite buscar palabras o frases en ficheros con extensiones soportadas por MinGW Developer Studio y que se encuentren en cualquier directorio. Para ello se muestra un cuadro de búsqueda que permite especificar la palabra o frase a buscar, la extensión de los ficheros en los que se quiere buscar (*.c, *.cc, *.cpp, *.cxx, *.h, *.hh, *.hpp, *.hxx, *.rc, *.rc2, *.def, *.htm, *.html, *.txt, *.*) y el directorio en el que se quiere buscar. Además, muestra tres checkboxes que permiten especificar propiedades de búsqueda. Las checkboxes Match whole Word only y Match case ya han sido explicadas en la opción Find y sus funciones son las mismas. La checkbox Look in subfolders está activada por defecto y permite realizar la búsqueda en subcarpetas del directorio especificado en la pestaña In folder. El resultado de la búsqueda será mostrado en la pestaña Find in Files de la zona de salida. A continuación se muestra una captura del cuadro de búsqueda de la opción Find in Files

55 o Replace: Puede activarse también pulsando simultáneamente las teclas Ctrl y H. Esta opción permite reemplazar una palabra o frase por otra que se debe especificar. La palabra o frase a reemplazar se escribe en el cuadro de texto Find what mientras que la palabra o frase que la reemplace se escribe en el cuadro Replace with. Las tres checkboxes y sus funciones ya han sido explicadas en la opción Find mientras que el cuadro Replace in permite realizar el reemplazo en todo el fichero (opción Whole file, que está activada por defecto) o solo en una parte de él que debe ser seleccionada (opción Selection). El botón Find Next ya ha sido explicado anteriormente, mientras que el botón Replace ejecuta un único reemplazo frente a Replace All que reemplaza todos los resultados de la búsqueda simultáneamente. La opción Replace se encuentra desactivada si no hay ningún fichero en la zona de edición. o Match Brace: Puede activarse también pulsando simultáneamente las teclas Ctrl y B. Esta opción permite localizar la llave inicial ({) o final (}) de un bloque de código. Esto es especialmente útil en programas con un gran número de líneas de código para localizar el comienzo o el fin de funciones, bucles (for, while, do-while), bloques if-else, switch, etc. Para localizar el inicio/fin de un bloque de código hay que situarse en la llave final (})/inicial ({) y ejecutar la opción. La opción Match brace se encuentra desactivada si no hay ningún fichero en la zona de edición

56 o Go To: Puede activarse también pulsando simultáneamente las teclas Ctrl y G. Esta opción permite ir directamente a una línea de código determinada que se debe especificar en un cuadro de diálogo que aparece al ejecutar la opción. La opción Go to se encuentra desactivada si no hay ningún fichero en la zona de edición. A continuación se muestra una captura del cuadro que aparece al ejecutar la opción Go to. o Advanced: Esta opción permite realizar cuatro acciones diferentes sobre un fragmento de código que se debe seleccionar. La primera opción se llama Make Selection C style comment y convierte el fragmento seleccionado a estilo de comentario en lenguaje de programación C, es decir, el fragmento precedido de /* y con */ al final. Esta opción también puede ejecutarse pulsando simultáneamente las teclas Ctrl e Insert. La segunda opción se llama Make Selection C++ style comment y convierte el fragmento seleccionado a estilo de comentario en lenguaje de programación C++, es decir, el fragmento con // en cada línea. Esta opción también puede ejecutarse pulsando simultáneamente las teclas Ctrl, Shift e Insert. La tercera opción se llama Make Selection Uppercase y convierte el fragmento seleccionado a mayúsculas. Esta opción también puede ejecutarse pulsando simultáneamente las teclas Ctrl, Shift y U. La última opción se llama Make Selection Lowercase y convierte el fragmento seleccionado a minúsculas. Esta opción también puede ejecutarse pulsando simultáneamente las teclas Ctrl y U. La opción Advanced se encuentra desactivada si no hay ningún fichero en la zona de edición. A continuación se muestra una captura de las acciones posibles de la opción Advanced

57 o File Format: Esta opción permite codificar el fichero que se encuentre en la zona de edición de tal forma que sea portable a Windows, UNIX y Macintosh por medio de tres opciones específicas: Windows (CR/LF), UNIX (LF) y Macintosh (CR). Al editar ficheros en MinGW Developer Studio y guardarlos, las líneas se terminan con la combinación de caracteres CR/LF, que significan retorno de carro/avance o fin de línea. Esto se produce en sistemas Windows mientras que en sistemas UNIX se terminan sólo con avance de línea. En sistemas Macintosh, por otro lado, terminan sólo con retorno de carro. Esta opción, por tanto, favorece la portabilidad de ficheros entre los tres tipos de sistemas más utilizados. La opción File Format se encuentra desactivada si no hay ningún fichero en la zona de edición. o Options: Esta opción permite modificar una serie de parámetros agrupados en ocho categorías: Project (Proyecto), Editor (Editor), Tabs (Tabulaciones), Compiler (Compilador), Build (Construir), Directories (Directorios), Help (Ayuda) y Format (Formato). La categoría Project permite cargar el último proyecto abierto cuando se inicia el programa y cargar los documentos asociados a un proyecto cuando éste se abre

58 La categoría Editor permite modificar opciones de guardado de ficheros, opciones de autocompletado, opciones de pestañas en la visualización de ficheros y opciones de impresión. La categoría Tabs permite modificar parámetros relativos a las tabulaciones del texto de la zona de edición. Se puede modificar el espaciado, el sangrado, insertar espacios, mantener tabulaciones, realizar un sangrado automático, etc. La categoría Compiler permite especificar el directorio que utiliza el programa (MinGW path) y donde se encuentran los ficheros de librería (carpeta lib), los ficheros de include (carpeta include), los ficheros de recursos (carpeta include), etc. La categoría Build permite guardar un fichero automáticamente antes de ser compilado y ejecutado cuando se pulsa la opción Build. Además, permite escribir siempre las dependencias cuando se escribe un fichero Makefile. Este fichero se compone de un conjunto de dependencias y reglas. Una dependencia tiene un fichero objetivo (target), que es el fichero a crear, y un conjunto de ficheros fuente de los cuales depende el fichero objetivo. Una regla describe cómo crear el fichero objetivo a partir de los ficheros de los que éste depende. La categoría Directories muestra los directorios donde se encuentran los ficheros de include (Include files), los ficheros de librería (Library files) y los ficheros de recursos (Resource files). Además, permite modificar estos directorios mediante una serie de botones que permiten eliminar el directorio actual y buscar manualmente el directorio nuevo. La categoría Help muestra los directorios donde se encuentran los ficheros de ayuda de win32 y de wxwindows así como modificar dichos

59 directorios. Además, permite especificar que las sugerencias (Call tips) se muestren según el estándar ANSI C y la API de Windows (WinAPI). La categoría Format permite modificar opciones de estilo de texto en la zona de edición y en la zona de salida. Se permite modificar el tamaño del texto, la fuente, el color (del texto, del fondo, del sombreado de errores, ) y el estilo de fuente (negrita, cursiva y subrayado). Estos cambios pueden visualizarse en el propio cuadro de opciones gracias a la ventana Sample que muestra el resultado de los cambios en caso de que éstos se lleven a cabo. A continuación se muestra una captura del cuadro Options en la categoría Format

60 View: Consta de once opciones como son Toolbar (Barra de herramientas), Status Bar (Barra de estado), Toggle Current Fold (Ocultar bloque actual), Toggle All Folds (Ocultar todos los bloques), End Of Line (Fin de Línea), Line Numbers (Números de Línea), Indentation Guides (Guías de sangrado), Margin (Margen), Fold Margin (Margen de bloque), Project Window (Ventana de Proyecto) y Output Window (Ventana de Salida). Programación Orientada a Objetos o Toolbar: Esta opción permite mostrar (opción activada) o esconder (opción desactivada) la barra de herramientas, que se explicará en el apartado Barra de herramientas. o Status Bar: Esta opción permite mostrar (opción activada) o esconder (opción desactivada) la barra de estado. Esta barra está situada debajo de la zona de salida y está dividida en dos zonas diferenciadas. Una zona muy amplia situada en el lado izquierdo muestra información acerca de la acción que realiza cada una de las opciones de los menús cuando el cursor se encuentra situado sobre cada opción. La segunda zona está situada en el lado derecho y muestra el número de línea y columna en el que se encuentra el cursor en la zona de edición así como el modo de teclado activo (INS/OVR) (inserción/sobreescritura). o Toggle Current Fold: Cuando se explicó la zona de edición se decía que se pueden ocultar bloques de código independientes como declaraciones de estructuras, funciones, bloques if-else, bloques while o do-while, bloques for o incluso la propia función principal (main). Pues bien, la opción Toggle Current Fold permite ocultar o mostrar estos bloques de código independientes. Para ello hay que situar el cursor al comienzo del bloque (a la derecha del símbolo de minimizar/maximizar) y pulsar sobre esta opción. Si el bloque está oculto se mostrará, mientras que si se

61 estaba mostrando se ocultará. Esta opción se encuentra desactivada si no hay ningún fichero en la zona de edición. o Toggle All Folds: Esta opción permite ocultar todos los bloques de código independientes tal y como se ha explicado en la opción anterior. La única diferencia que presenta respecto de dicha opción es que no influye la situación del cursor a la hora de ejecutar la acción puesto que todos los bloques serán ocultados/mostrados. Esta opción se encuentra desactivada si no hay ningún fichero en la zona de edición. o End of Line: Esta opción permite visualizar el fin o avance de línea (LF) y el retorno de carro (CR) en cada una de las líneas del fichero que se encuentra en la zona de edición. El avance de línea y el retorno de carro ya fueron explicados en la opción File Format del menú Edit. o Line Numbers: Esta opción permite mostrar (opción activada) o esconder (opción desactivada) los números de línea que se encuentran a la izquierda del fichero cargado en la zona de edición. o Indentation Guides: Esta opción permite mostrar (opción activada) o esconder (opción desactivada) los puntos suspensivos azules situados en cada tabulación que ayudan a ordenar el código para facilitar su seguimiento y a localizar el inicio y fin de bloques if-else, do-while, while, bucles for, etc. o Margin: Esta opción permite mostrar (opción activada) o esconder (opción desactivada) el margen situado entre los números de línea y el código del fichero cargado en la zona de edición. o Fold Margin: Esta opción permite mostrar (opción activada) o esconder (opción desactivada) el margen y la llave de seguimiento situados en los bloques de código independientes ya explicados. El margen y la llave de

62 seguimiento permiten una rápida localización de dichos bloques por lo que no es recomendable su ocultación. o Project Window: Puede activarse también pulsando simultáneamente las teclas Alt y 0. Esta opción permite mostrar (opción activada) o esconder (opción desactivada) la zona de workspace. o Output Window: Puede activarse también pulsando simultáneamente las teclas Alt y 2. Esta opción permite mostrar (opción activada) o esconder (opción desactivada) la zona de salida

63 Project: Consta de siete opciones como son New Project (Nuevo Proyecto), Open Project (Abrir Proyecto), Save Project (Guardar Proyecto), Close Project (Cerrar Proyecto), Add To Project (Añadir al Proyecto), Settings (Ajustes) y Export Makefile (Exportar fichero Makefile). Programación Orientada a Objetos o New Project: Puede activarse también pulsando simultáneamente las teclas Ctrl y N. Esta opción presenta el mismo comportamiento que la opción New del menú File ya explicado y se encuentra activada si no hay ningún proyecto en la zona de workspace. o Open Project: Esta opción permite abrir un abrir un fichero de proyecto MinGWStudio Project Files (extensión *.msp o *mdsp). Esta opción se encuentra activada si no hay ningún proyecto en la zona de workspace. A continuación se muestra una captura de la ventana que aparece al pulsar la opción y que permite seleccionar el proyecto a abrir. o Save Project: Esta opción permite guardar los cambios realizados en la configuración del proyecto mediante la opción Settings que se explicará posteriormente y que forma parte de este menú. Esta opción no guarda cambios realizados en los ficheros del proyecto

64 o Close Project: Esta opción cierra el proyecto que se encuentre abierto en la zona de workspace. Antes de cerrar el proyecto aparece un cuadro de confirmación de cierre de proyecto. Además, en caso de que alguno de los ficheros del proyecto haya sido modificado aparecerá un segundo cuadro que preguntará acerca de la posibilidad de guardar los cambios realizados. o Add To Project: Esta opción permite añadir al proyecto ficheros de proyecto u otro tipo de ficheros. Para ello, existen dos opciones diferentes que se muestran en un submenú: New y Files. New presenta el mismo comportamiento que la opción New Project de este mismo menú y que la opción New del menú File. Por otra parte, el submenú Files permite añadir ficheros al proyecto. Estos ficheros pueden tener cualquiera de las extensiones soportadas por el programa y que fueron explicadas en la opción Open del menú File. o Settings: Esta opción permite establecer una serie de propiedades del proyecto agrupadas en cuatro categorías: General (General), Compile (Compilar), Link (Enlazar) y Resources (Recursos). La categoría General permite escribir datos relativos al directorio de trabajo, a los argumentos del programa y a los directorios de ficheros de salida (tanto intermedios como de salida). La categoría Compile permite escribir definiciones del preprocesador, opciones extra de compilación y directorios adicionales de include. Además, permite especificar opciones adicionales relativas a warnings, información de Debugging (depuración), niveles de optimización y lenguaje C++ (información en tiempo de ejecución y gestión de excepciones). A continuación se muestra una captura del cuadro Project Settings en la categoría General, que es la que aparece por defecto al pulsar sobre la opción Settings

65 o Export Makefile: Esta opción crea un fichero Makefile a partir del fichero que se encuentre abierto en la zona de edición. El fichero Makefile ya fue explicado al detallar la categoría Build del submenú Options del menú Edit. El fichero Makefile aparecerá en el mismo directorio del proyecto una vez que se pulsa esta opción. A continuación se muestra una captura del fichero Makefile creado a partir de un fichero

66 Programación Orientada a Objetos

67 Build: Consta de diez opciones como son Compile (Compilar), Build (Construir), Rebuild All (Reconstruir todo), Build All Configurations (Construir todas las configuraciones), Build and Execute (Construir y Ejecutar), Clean (Limpiar), Clean All Configurations (Limpiar todas las configuraciones), Stop (Parar), Execute (Ejecutar) y Set Active Configuration (Establecer configuración activa). Ninguna de estas opciones estará activa a menos que haya un proyecto en la zona de workspace. En tal caso estarán todas las opciones activas menos Compile que requiere que haya un fichero abierto en la zona de edición y Stop que sólo estará activa durante el tiempo que se esté llevando a cabo alguna de las acciones situadas por encima de ella en el menú. o Compile: Puede activarse también pulsando simultáneamente las teclas Ctrl y F7. Esta opción permite compilar el fichero que se encuentre abierto en la zona de edición. Los mensajes que aparecen en la zona de salida ya se explicaron cuando se comentó dicha zona. o Build: Puede activarse también pulsando la tecla F7. Esta opción permite compilar y enlazar el fichero que se encuentre abierto en la zona de edición. Los mensajes que aparecen en la zona de salida ya se explicaron cuando se comentó dicha zona. o Rebuild All: Esta opción compila y enlaza el fichero que se encuentre abierto en la zona de edición tras eliminar los ficheros intermedios y ficheros de salida generados en anteriores compilaciones, enlazados y ejecuciones con la configuración Debug que se explicará en el siguiente punto. Una vez ejecutada, se habrá creado la carpeta Debug en el directorio del proyecto y contendrá el fichero con extensión *.o generado tras la compilación y el fichero con extensión *.exe generado tras el enlazado

68 o Build All Configurations: Un proyecto de MinGW tiene configuraciones diferentes para las versiones de lanzamiento (Release) y de depuración (Debug) del programa. Como sus nombres indican, la versión Debug se construye para depuración mientras que la versión Release se construye para la distribución final del programa en su lanzamiento. Si se crea un programa con MinGW, éste crea automáticamente las configuraciones y establece opciones apropiadas por defecto y otros ajustes. Con las opciones por defecto: La configuración Debug del programa es compilada con información simbólica de depuración y sin optimización. La optimización complica la depuración porque la relación entre el código fuente y las instrucciones generadas es de mayor complejidad. La configuración Release del programa está completamente optimizada y no contiene información simbólica de depuración. Una vez explicadas las dos configuraciones posibles, la opción Build All Configurations crea ambas configuraciones en el directorio del proyecto. En dicho directorio aparecen, por tanto, la carpeta Debug y la carpeta Release con sus respectivas configuraciones. Si no se pulsa esta opción, el compilador creará únicamente la versión Debug, que es la establecida por defecto. o Build and Execute: Esta opción construye el programa (ver comportamiento de la opción Build explicada anteriormente) y lo ejecuta. Por tanto, compila, enlaza y ejecuta el fichero que se encuentre abierto en la zona de edición. En caso de que la compilación o el enlazado presenten errores la ejecución se suspenderá y aparecerá un cuadro con el mensaje Cannot execute program (No se puede ejecutar el programa)

69 o Clean: Esta opción borra los ficheros intermedios y los ficheros de salida generados con la configuración Debug. Elimina, por tanto, la carpeta Debug del directorio del proyecto. o Clean All Configurations: Esta opción borra los ficheros intermedios y los ficheros de salida generados con las configuraciones Debug y Release. Elimina, por tanto, las carpetas Debug y Release del directorio del proyecto. o Stop: Esta opción permite parar la ejecución de las acciones situadas por encima de ella en el menú Build. Permite, por tanto, parar la ejecución de las opciones Compile, Build, Rebuild All, Build All Configurations, Build and Execute, Clean y Clean All Configurations una vez que alguna de ellas haya sido pulsada y sin que haya terminado la ejecución de la tarea que realiza. o Execute: Puede activarse también pulsando simultáneamente las teclas Ctrl y F5. Esta opción ejecuta el programa (el fichero *.exe generado tras el enlazado en la carpeta Debug del directorio del proyecto). En caso de que el programa no haya sido compilado o enlazado, MinGW desplegará un cuadro informando acerca de la situación (The target is out of date) y preguntando si se quiere realizar el compilado y enlazado. Este cuadro se muestra a continuación. o Set Active Configuration: Esta opción permite seleccionar la configuración (Debug o Release) de la versión del proyecto. La configuración por defecto es Debug. Ambas configuraciones ya fueron explicadas anteriormente (ver opción Build All Configurations)

70 Debug: Este menú será explicado posteriormente en el apartado 5.1 Menú Debug del capítulo

71 Tools: Consta de una única opción como es Resource Editor (Editor de recursos). o Resource Editor: Puede activarse también pulsando simultáneamente las teclas Ctrl y R. Esta opción abre el editor de recursos. El editor de recursos permite crear ficheros resource script (extensión *.rc) de forma rápida e intuitiva. El editor cuenta con una interfaz gráfica muy cómoda para diseñar el aspecto de ventanas, iconos, botones, barras de herramientas y otros muchos tipos de recursos gráficos. Hay que recordar que los ficheros *.rc son empleados por GTK+ (GIMP Tool Kit) para tratar las opciones predeterminadas de las aplicaciones. Con ellos se pueden cambiar los colores de cualquier control, poner un dibujo de fondo, etc. GTK+ es un grupo importante de bibliotecas o rutinas para desarrollar interfaces gráficas de usuario (GUI) mediante C, C++ y otros lenguajes de programación. A continuación se muestra una captura del editor de recursos

72 Window: Consta de ocho opciones como son Close (Cerrar), Close All (Cerrar todo), Cascade (Cascada), Tile Horizontally (Mosaico Horizontal), Tile Vertically (Mosaico Vertical), Arrange Icons (Ordenar iconos), Next (Siguiente) y Previous (Anterior). Además, a continuación de las ocho opciones muestra el nombre de los ficheros que se encuentran abiertos ordenados de arriba hacia abajo en orden de apertura (el primero será el que se abrió primero y el último será el que se abrió más recientemente). Además, a la Programación Orientada a Objetos izquierda del fichero que se encuentre abierto en la zona de edición se mostrará el símbolo indicando dicha situación. o Close: Esta opción cierra el fichero que se encuentre abierto en la zona de edición. Además, elimina su correspondiente pestaña de la zona superior de la zona de edición y la entrada con su nombre en el menú Window. o Close All: Esta opción cierra todos los ficheros abiertos. Además, elimina sus correspondientes pestañas de la zona superior de la zona de edición y las entradas con sus nombres en el menú Window. Como resultado, la zona de edición queda en color gris al igual que al iniciar la aplicación. o Cascade: Esta opción permite visualizar los ficheros abiertos en cascada dentro de la zona de edición tal y como se muestra a continuación

73 o Tile Horizontally: Esta opción permite visualizar los ficheros abiertos en mosaico horizontal dentro de la zona de edición tal y como se muestra a continuación

74 o Tile Vertically: Esta opción permite visualizar los ficheros abiertos en mosaico vertical dentro de la zona de edición tal y como se muestra a continuación. o Arrange Icons: Esta opción permite ordenar las ventanas que se encuentren minimizadas en la zona de edición. Si varias ventanas se encuentran minimizadas en la zona de edición tras visualizarlas mediante mosaico horizontal, vertical o cascada esta opción permite ordenarlas en el mismo orden en que fueron minimizadas. De esta forma se sitúan los iconos de las ventanas ordenados en la parte inferior izquierda de la zona de edición. o Next: Esta opción permite activar el fichero (la ventana) siguiente al que se encuentra activo en los modos de visualización en cascada, mosaico horizontal y mosaico vertical. De este modo, se activa la siguiente ventana y el cursor se sitúa donde se había quedado la última vez que dicho fichero estuvo activo. Si nunca lo estuvo, se situará al comienzo del fichero

75 o Previous: Esta opción permite activar el fichero (la ventana) anterior al que se encuentra activo en los modos de visualización en cascada, mosaico horizontal y mosaico vertical. De este modo, se activa la ventana anterior y el cursor se sitúa donde se había quedado la última vez que dicho fichero estuvo activo. Si nunca lo estuvo, se situará al comienzo del fichero

76 Help (About MinGW Developer Studio): Esta opción abre un cuadro de diálogo con créditos acerca de la aplicación (versión, fecha de creación y software que se emplea GNU GCC, MINGW, wxwindows, wxstyledtextctrl, Scintilla and SciTE y ResEd con una breve explicación de cada uno y un enlace web)

77 Barra de Herramientas. La barra de herramientas es un sistema cómodo y rápido para ejecutar directamente cualquier opción de los menús explicados en el apartado anterior. Consta de veintisiete iconos que permiten realizar acciones como crear un nuevo proyecto, abrir un fichero, compilar un programa, depurar un programa, solicitar ayuda, etc. Cada uno de los iconos será explicado a continuación mediante una tabla que muestra la equivalencia entre los iconos de la barra de herramientas y la opción del menú que es ejecutada cuando se pulsa el icono. Icono Acción ejecutada File New (Ctrl+N) File Open (Ctrl+O) File Save (Ctrl+S) File Save All Edit Cut (Ctrl+X) Edit Copy (Ctrl+C) Edit Paste (Ctrl+V) Edit Undo (Ctrl+Z) Edit Redo (Ctrl+Y) View Project Window (Alt+0) View Output Window (Alt+2) Previous (Alt+Left Arrow) Next (Alt+Right Arrow) Build Compile (Ctrl+F7) Build Build (F7) Build Stop Build Execute (Ctrl+F5) Debug Go (F5) Debug Toggle Breakpoint (F9) Debug Step Into (F11) Debug Step Over (F10) Debug Step Out of Function (Shift+F11) Debug Run to Cursor (Ctrl+F10) Debug QuickWatch (Shift+F9) File Print Preview File Print (Ctrl+P) Help About MinGW Developer Studio

78 Capítulo 5 Depuración de Programas (Debugging)

79 CAPÍTULO 5. Depuración de programas (Debugging). Debugging es el nombre que recibe el proceso de eliminación y limpieza de bugs (errores) de los programas. Para realizar la depuración de programas se emplea el debugger, que es una herramienta diseñada para revisar las instrucciones de un programa paso a paso y examinar su estado en cada paso. El Debugging comienza en cuanto el usuario se empieza a preguntar las razones por las que su programa no produce los resultados deseados. La primera tarea que se debe realizar es asegurarse de que el código C/C++ compila y enlaza sin errores. Si se produce algún error, el código debe ser modificado de tal manera que no ocurra. La segunda tarea que se debe realizar es examinar el código y comparar los resultados deseados con los que se están obteniendo. Sin embargo, en muchas ocasiones sucede que tras realizar un examen profundo del código sigue sin aparecer el error. Es en estos casos en los que es necesario emplear el debugger, que puede realizar las siguientes acciones: Recorrer las sentencias del programa paso a paso, bien over (por encima de) o into (dentro de) las funciones. En el primer caso (over) se omite el recorrido dentro de las funciones mientras que en el segundo caso se recorren las sentencias de las funciones y se vuelve a la función principal. Ejecutar el programa hasta un cierto punto (bien hasta el cursor o hasta un breakpoint) y luego detener la ejecución. En el primer caso (cursor) se ejecuta el programa hasta el lugar del código donde esté situado el cursor antes de comenzar el debugging. En el segundo caso (breakpoint) el programa se ejecutará hasta un breakpoint o punto de parada que se habrá situado en el código antes de comenzar el debugging. Mostrar los valores (o el contenido) de las variables en cada punto durante la ejecución del programa

80 5.1. Menú Debug. El menú Debug consta de nueve opciones como son Go (Iniciar), Stop Debugging (Detener la depuración), Step Into (Ejecutar dentro de), Step Over (Ejecutar por encima de), Run to Cursor (Ejecutar hasta el cursor), Step Out of Function (Salir de la función), Back trace (Visualización de origen), Toggle Breakpoint (Situar/Eliminar breakpoint) y QuickWatch (Vista rápida). o Go: Puede activarse también pulsando la tecla F5. Esta opción inicia la depuración del fichero que se encuentre abierto en la zona de edición. Sin embargo, la depuración del programa es tan rápida que no permite ver paso a paso la evolución del mismo. Esto puede evitarse situando un breakpoint (mediante la opción Toggle Breakpoint que se explicará posteriormente) en el punto del código donde se quiere detener la depuración o bien por medio de la opción Run to Cursor que se explicará posteriormente. La pestaña Debug situada en la zona de salida mostrará el mensaje Debug has started (La depuración ha comenzado) cuando se pulse esta opción y Debug has stopped (La depuración ha finalizado) cuando finalice la depuración tal y como se muestra a continuación. o Stop Debugging: Puede activarse también pulsando simultáneamente las teclas Shift y F5. Esta opción detiene la depuración del fichero que se encuentre abierto en la zona de edición. La depuración puede haberse iniciado por medio de la opción Go, la opción Step Into o la opción Run to cursor. Al pulsar esta opción la pestaña Debug situada en la zona de

81 salida mostrará el mensaje Debug has stopped (La depuración ha finalizado). o Step Into: Puede activarse también pulsando la tecla F11. Esta opción permite la ejecución paso a paso del fichero que se encuentre abierto en la zona de edición. La primera vez que se pulse esta opción sin haberse iniciado la depuración, ésta comenzará. Cuando comienza la depuración aparece la ventana de consola y una flecha amarilla se sitúa a la derecha del número de línea de la primera sentencia del programa. Si se pulsa de nuevo se avanzará por medio de la flecha amarilla hasta la siguiente sentencia del programa y así sucesivamente siguiendo el flujo de ejecución del programa. En caso de que una sentencia sea una llamada a una función desde la función principal, la opción Step Into permite saltar directamente a la primera sentencia de la función y ver las sentencias de ésta hasta que vuelve o retorna a la función principal. Una vez que se pulsa esta opción estando en la última sentencia del programa la ventana de consola contendrá la ejecución completa del programa con sus respectivas salidas y la pestaña Debug situada en la zona de salida mostrará el mensaje Debug has stopped (La depuración ha finalizado). A continuación se muestra una captura del debugging una vez se ha pulsado la opción Step Into

82 Como se puede ver en la captura sobre estas líneas, cuando el debugger llega a la sentencia de llamada a la función Suma (res=suma(a,b);) y se pulsa la opción Step Into, la flecha amarilla avanza hasta la primera sentencia de la función (suma=0;) y permite revisar su comportamiento. Si se vuelve a pulsar repetidamente, el debugger continuará revisando las sentencias de la función hasta llegar al final (denotado por } ) y volverá a la función llamante (main). o Step Over: Puede activarse también pulsando la tecla F10. Esta opción realiza exactamente lo mismo que la opción anterior (Step Into) con la diferencia de que si una sentencia es una llamada a una función desde la función principal no salta a la primera sentencia de la función y permite revisar sus sentencias sino que salta a la siguiente sentencia de la función principal tras haber realizado las acciones que desempeñaba la función. En resumen, se pasa a la siguiente sentencia de la función principal omitiendo la revisión de todas las sentencias de la función aunque a

83 efectos de resultado es como si se hubiera realizado. De este modo se ahorra tiempo de revisión de funciones donde se descarta la aparición de errores (bugs). A continuación se muestra una captura de la ejecución del debugger una vez se ha pulsado la opción Step Over. Como se puede ver, cuando el debugger llega a la sentencia de llamada a la función Suma (res=suma(a,b);) y se pulsa la opción Step Over, la flecha amarilla avanza hasta la siguiente sentencia de la función principal (printf) omitiendo la revisión de las sentencias de la función Suma. o Run to Cursor: Puede activarse también pulsando simultáneamente las teclas Ctrl y F10. Esta opción permite llevar a cabo la depuración del fichero que se encuentre abierto en la zona de edición hasta el lugar donde se haya situado el cursor antes de iniciar la depuración. De este modo se ejecutan las sentencias del programa sólo hasta un determinado punto especificado por el usuario antes de comenzar la depuración

84 o Step Out of Function: Puede activarse también pulsando simultáneamente las teclas Shift y F11. Esta opción sólo se encuentra activa cuando el debugger se encuentra situado en una sentencia de una función y permite regresar a la función principal omitiendo la revisión del resto de sentencias de la función. Cuando regresa a la función principal, las sentencias restantes no se revisan aunque sus acciones se han ejecutado. o Back trace: Puede activarse también pulsando la tecla F12. Esta opción imprime en la pestaña Debug de la zona de salida información acerca de la sentencia que se está revisando. La información que se muestra es: level (nivel de profundidad), addr (dirección de memoria de la instrucción), func (nombre de la función), file (nombre del fichero que se está depurando) y line (número de línea de la sentencia). El nivel de profundidad será el más alto si se trata de la función principal, el anterior al de la función principal si se trata de una función llamada por la función principal, el anterior al anterior al de la función principal si se trata de una función llamada por una función llamada por la función principal y así sucesivamente. Cuando se pulsa la opción Back trace sobre una sentencia de una función se muestra información acerca de la sentencia de la función y acerca de la sentencia de la función principal que llamó a dicha función. A continuación se muestra una captura de la zona de salida una vez pulsada la opción Back trace estando el debugger en una sentencia de una función

85 o Toggle Breakpoint: Puede activarse también pulsando la tecla F9. Esta opción añade/elimina un punto de parada (breakpoint) en la sentencia del programa donde se sitúe el cursor. Como ya se ha comentado, los breakpoints sirven para ejecutar el debugger hasta el lugar donde estén situados. La sentencia en la que se sitúe un breakpoint se distinguirá del resto ya que aparecerá un círculo de color rojo a la derecha del número de línea. A continuación se muestra una captura de la opción Toggle Breakpoint en la que se observa el punto rojo situado al lado de la sentencia (printf) donde se ha colocado el breakpoint

86 o QuickWatch: Puede activarse también pulsando simultáneamente las teclas Shift y F9. Esta opción abre una ventana de observación de variables que permite visualizar el valor de las variables del programa a medida que avanza el debugger. A continuación se muestra una captura de la ventana de observación que ayudará en la explicación. En el cuadro de texto Expression se escribe el nombre de la variable que se desea observar. Al pulsar el botón Add Watch, dicha variable se introducirá en el cuadro Current value e inicialmente tomará un valor desconocido (??). Al pulsar una variable del cuadro Current Value se podrán realizar las siguientes acciones: eliminarla (botón Delete) o cambiarle el valor (botón Set Value). La opción Set Value es útil para ver

87 los resultados que se producirían en caso de que las variables tomasen otros valores. El botón Delete All elimina todas las variables del cuadro Current value mientras que el botón Close cierra la ventana de observación. Una vez que todas las variables que se desean observar han sido introducidas y aparecen en el cuadro Current value ya se puede iniciar el debugger para ver los valores que van tomando. De esta forma en cada paso del debugger se observarán los valores que toman las distintas variables del cuadro Current value y se podrá modificar el programa para obtener los resultados esperados. Para ello, con la opción Set Value se pueden modificar los valores de las variables y ver la ejecución que se produce. A continuación se muestra la ventana de observación de la opción QuickWatch al ejecutar un programa con el debugger

88 La ventana de observación del ejemplo anterior se produjo cuando el debugger se encontraba en la segunda vuelta del bucle for (i=2) por lo que todas las variables tomaban un valor salvo res puesto que la función aún no había terminado su ejecución. Es por ello que en dicha variable aparece el mensaje No symbol res in current context informando acerca de dicha situación. Existe otra forma alternativa de ver los valores que toman las variables en cada sentencia en la que se detiene el debugger. Esta forma consiste en situar el cursor encima de la variable que se quiere observar en la zona de edición. De esta forma aparecerá una etiqueta que mostrará el mismo valor que se muestra en la ventana de observación de la opción QuickWatch. Esta manera de ver el valor de las variables es más rápida que con la opción QuickWatch si bien no permite monitorizar todas las variables en una misma ventana, algo que sí es posible con la citada opción

89 Por último hay que comentar que MinGW Developer Studio no puede cerrarse si el debugger está funcionando por lo que es necesario detener su ejecución si se quiere abandonar la aplicación. Por ello, se mostrará un cuadro informando acerca de dicha situación en caso de intentar salir del programa con el debugger funcionando. Dicho cuadro se muestra a continuación. El cuadro de la figura muestra el mensaje You cannot close the Project while debugging. Select the Stop Debugging befote closing the project (No puedes cerrar el proyecto mientras está funcionando el debugger. Selecciona la opción Stop Debugging antes de cerrar el proyecto) para indicar la situación comentada en el párrafo anterior

90 PARTE II: Funcionamiento del compilador en la parte que se corresponde a Orientación a Objetos (C++)

91 Capítulo 1 Introducción

92 CAPÍTULO 1. Introducción. El compilador MinGW Developer Studio permite llevar a cabo programación orientada a objetos (POO) por medio del lenguaje de programación C++, uno de los más empleados en la actualidad. Se puede decir que C++ es un lenguaje híbrido, ya que permite programar tanto en estilo procedimental (orientado a algoritmos), como en estilo orientado a objetos, como en ambos a la vez. Además, también se puede emplear mediante programación basada en eventos para crear programas que usen interfaz gráfica de usuario (GUI). Como lenguaje procedimental se asemeja al C y es compatible con él, aunque presenta ciertas ventajas. Como lenguaje orientado a objetos se basa en una filosofía completamente distinta, que exige del programador un completo cambio de mentalidad. El nacimiento de C++ se sitúa en el año 1980, cuando Bjarne Stroustrup, de los laboratorios Bell, desarrolló una extensión de C llamada C with Classes (C con Clases) que permitía aplicar los conceptos de la programación orientada a objetos con el lenguaje C. Stroustrup se basó en las características de orientación a objetos del lenguaje de programación Simula, aunque también tomó ideas de otros lenguajes importantes de la época como ALGOL68 o ADA. Durante los siguientes años, Stroustrup continuó el desarrollo del nuevo lenguaje y en 1983 se acuñó el término C++ (C Plus Plus). En 1985, Bjarne Stroustrup publicó la primera versión de The C++ Programming Language (El lenguaje de programación C++), que a partir de entonces se convirtió en el libro de referencia del lenguaje. En la actualidad, este lenguaje se encuentra estandarizado a nivel internacional mediante el estándar ISO/IEC 14882:1998 con el título Information Technology Programming Languages C++, publicado el 1 de Septiembre de En el año 2003 se publicó una versión corregida del estándar (ISO/IEC

93 14882:2003). Finalmente, en la actualidad se está preparando una nueva versión del lenguaje, llamada C++0X, que se espera que esté preparada para el año En C, la unidad de programación es la función, con lo cual, se trata de una programación orientada a la acción. Por el contrario, en C++ la unidad de programación es la clase a partir de la cual, los objetos son producidos. Se trata, pues, de una programación orientada a objetos. Las bibliotecas estándar de C++ proporcionan un conjunto extenso de capacidades de entrada/salida. C++ usa entrada/salida de tipo seguro por lo que no podrán introducirse datos equivocados dentro del sistema. Se pueden especificar entradas/salidas de tipos definidos por el usuario, así como de tipos estándar. Esta extensibilidad es una de las características más valiosas de este lenguaje de programación. C++ permite un tratamiento común de entradas/salidas de tipos definidos por usuario. Este tipo de estado común facilita el desarrollo de software en general y de la reutilización de software en particular. Las principales ventajas que presenta el lenguaje C++ son: o Difusión: al ser uno de los lenguajes más empleados en la actualidad, posee un gran número de usuarios y existe una gran cantidad de libros, cursos, páginas Web, etc. dedicados a él. o Versatilidad: C++ es un lenguaje de propósito general, por lo que se puede emplear para resolver cualquier tipo de problema. o Portabilidad: el lenguaje está estandarizado y un mismo código fuente se puede compilar en diversas plataformas

94 o Eficiencia: C++ es uno de los lenguajes más rápidos en cuanto a ejecución. o Herramientas: existe una gran cantidad de compiladores, depuradores, librerías, etc

95 Capítulo 2 Creación de aplicaciones C++ en MinGW Developer Studio

96 CAPÍTULO 2. Creación de aplicaciones C++ en MinGW Developer Inicialmente, el área de trabajo del entorno de desarrollo está vacía. Para crear ahora la estructura de una nueva aplicación C++, se procede del siguiente modo: a. Se elige la opción New en el menú File (o se pulsan las teclas Ctrl y N simultáneamente) o bien se pulsa el botón herramientas. de la barra de b. A continuación, se presenta una ventana en la que se puede elegir el tipo de aplicación que se desea crear. Se selecciona la pestaña Projects y la aplicación de tipo Win32 Console Application. Ahora se procede a nombrar el proyecto escribiendo el nombre que se desea en el cuadro Project name. En el cuadro Location se permite especificar la ruta de acceso al directorio, es decir, el directorio donde se creará la carpeta de nombre igual al del proyecto y que contendrá todos los ficheros relativos

97 al proyecto (ejecutables, código fuente, etc.). Una vez especificado el nombre del proyecto y la ruta de acceso se confirma el cuadro de diálogo pulsando OK y ya se ha creado un proyecto nuevo. En el directorio especificado en el cuadro Location se habrá creado un fichero llamado nombre_del_proyecto.msp (MinGWStudio Project Files). Puede darse la situación de que el fichero creado tenga extensión *.mdsp en vez de *.msp. Esto se debe a que algunas versiones del compilador ponen dicha extensión a los ficheros de proyecto. c. El paso siguiente es crear un fichero y añadirlo al proyecto actualmente vacío. Se elige la opción New del menú File (o se pulsan las teclas Ctrl y N simultáneamente) o se pulsa el botón de la barra de herramientas. Se selecciona la pestaña Files y el fichero de tipo C/C++ Source File para crear un fichero de lenguaje de programación C++ (*.cpp) que contenga el código fuente. Se nombra el fichero en el cuadro File name y se confirma pulsando OK. El campo Location no debe ser modificado ya que por defecto se muestra la ruta de acceso al directorio del proyecto creado anteriormente. Además, la checkbox Add to project se encuentra activada para añadir el fichero al proyecto que se había creado previamente. Por tanto, la ruta de acceso y la checkbox no deben ser modificadas. En el directorio del proyecto se habrá creado un fichero llamado nombre_del_fichero.cpp (C Plus Plus Source File)

98 d. El entorno ya está listo para introducir el código en la zona de edición

99 2.1. Opciones de MinGW Developer Studio relacionadas con C++. El compilador dispone de una serie de opciones relacionadas con el lenguaje de programación C++ que se verán a continuación. o Comentarios en estilo C++: el compilador dispone de una opción que permite convertir un texto seleccionado en comentario C++ (cada línea de comentario precedida de // ). Esta opción se encuentra en el menú Edit Advanced Make Selection C++ style comment y es preciso seleccionar el texto a convertir en comentario C++ antes de pulsarla. A continuación se muestra un ejemplo de comentario C++. // stdafx.h: include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently o Manejo de excepciones e información en tiempo de ejecución: el compilador dispone de dos opciones relativas al lenguaje C++ que permiten habilitar o deshabilitar el manejo de excepciones y la información de tipo Runtime. El manejo de excepciones es una estructura de control del lenguaje C++ diseñada para manejar condiciones anormales que pueden ser tratadas por el mismo programa que se desarrolla. La información de tipo Runtime (RTTI Run-Time Type Information) es un sistema C++ que guarda en memoria información acerca del tipo de datos de un objeto en tiempo de ejecución. RTTI resulta útil cuando se trabaja con punteros a objetos en los que, en general, no se puede determinar el tipo de objeto al que referencian. Las dos opciones anteriormente descritas se encuentran en el menú Project Settings y en la pestaña Compile. En dicha pestaña hay una groupbox llamada C++ Language que contiene ambas opciones. A continuación se muestra una captura del cuadro Settings en la pestaña Compile donde se muestran las opciones relativas a C

100 Cuando se desarrollan aplicaciones orientadas a objetos es necesario declarar las clases (este concepto se verá en el capítulo 3) en ficheros independientes. El tipo de fichero que se emplea para declarar las clases es el fichero de cabecera (C/C++ Header File). Para crear un fichero de cabecera y añadirlo al proyecto se elige la opción New del menú File (o se pulsan las teclas Ctrl y N simultáneamente) o se pulsa el botón de la barra de herramientas. Se selecciona la pestaña Files y el fichero de tipo C/C++ Header File para crear un fichero de cabecera (*.h) que contenga la declaración de la clase. Se nombra el fichero en el cuadro File name con el mismo nombre que se le quiera dar a la clase y se confirma pulsando OK. El campo Location no debe ser modificado ya que por defecto se muestra la ruta de acceso al directorio del proyecto creado anteriormente. Además, la checkbox Add to project se encuentra activada para añadir el fichero de cabecera al proyecto que se había creado previamente. Por tanto, la ruta de acceso y la checkbox no deben ser modificadas. En el directorio del proyecto se habrá creado un fichero llamado nombre_de_la_clase.h

101 Capítulo 3 Programación Orientada a Objetos (POO) en C

102 CAPÍTULO 3. Programación Orientada a Objetos (POO) en C++. Para explicar la POO (Programación Orientada a Objetos) se partirá de un ejemplo sencillo en el que se verán algunos conceptos clave. A continuación se muestra un objeto de la clase Persona. La zona amarilla muestra los atributos del objeto (nombre y edad) mientras que el resto de colores muestran los métodos del objeto (getnombre, getedad, setnombre y setedad), es decir, las acciones y tareas que puede desempeñar dicho objeto. A los atributos de un objeto nunca se tendrá acceso directo (como una especie de caja negra) y sólo se accederá a ellos a través de los métodos. Se necesitarán, pues, dos tipos de métodos para manejar los objetos: los que obtengan los datos (getters) y los que asignen datos (setters). Los métodos definen lo que se conoce por interfaz de un objeto, es decir, la parte que maneja el usuario y a la que se puede acceder. Los atributos, sin embargo, forman parte de la zona oculta al usuario y a la que no se tiene acceso. Las peticiones que se pueden hacer a un objeto se encuentran definidas en su interfaz y es el tipo de objeto el que determina la interfaz. La interfaz establece qué peticiones pueden hacerse a un objeto particular. La forma de acceder a los objetos es invocando sus métodos de la siguiente manera: objeto.método(). A continuación se muestran objetos creados de la clase Persona:

103 Ejemplos de tareas a realizar con estos objetos: Obtener el nombre de la persona p1 y la edad de la persona p4. p1.getnombre(); // Devuelve Pedro p4.getedad(); // Devuelve 23 Cambiar el nombre de la persona p2 y la edad de la persona p3. p2.setnombre( Alberto ); p3.setedad(38); Una vez vistos en la práctica el funcionamiento de los objetos, éstos se pueden definir como entidades complejas provistas de datos (propiedades, atributos) y comportamiento (métodos). Posteriormente se verá la relación entre los objetos y la clase a la que pertenecen (en el ejemplo, Persona). A continuación se explicará en detalle lo que es una clase

104 3.1. Clase. La programación orientada a objetos se basa en encapsular datos (atributos) y funciones o comportamientos (métodos) juntos en estructuras llamadas clases. Las clases responden a la necesidad del programador de construir objetos o tipos de datos que respondan a sus necesidades y se emplean para modelar objetos del mundo real. Para explicar el concepto de clase se comenzará con un ejemplo sencillo que ayude a entenderlo. Supóngase que se quiere preparar un flan. Para ello se necesitarán una serie de ingredientes como azúcar, huevo, leche, etc. Todos estos ingredientes se mezclarán y se introducirán en un molde, que es el que se meterá en el horno. Una vez finalizado el tiempo de horneo se obtendrá el flan. Si se quisiera preparar otro flan igual se haría lo mismo y así sucesivamente. El mismo molde serviría para elaborar un número infinito de flanes. Pues bien, algo parecido sucede con los objetos y la clase a la que pertenecen. Todos los objetos de una misma clase comparten los mismos atributos (en el ejemplo, ingredientes) y la clase es el molde que permite su creación. En la clase estarán definidas todas las propiedades y funcionalidad común a los objetos que pertenezcan a ella. Los objetos, por tanto, heredan las propiedades y también el comportamiento de todas las clases a las que pertenezcan. Una clase se define como una estructura que define atributos e implementa métodos de cada objeto. La tarea principal de una clase es crear objetos. Las clases se definen mediante la palabra reservada class

105 A continuación se muestra la representación de la clase Persona del ejemplo del punto anterior. Como se puede ver en la figura sobre estas líneas, la clase Persona tiene dos atributos (zona verde) y cuatro métodos (zona roja). Los getters permiten obtener el nombre y la edad del objeto de la clase Persona mientras que los setters permiten modificar el nombre y la edad de dicho objeto. Existen dos tipos de clases: o Clases abstractas: son clases que tienen definidos sus métodos pero no su implementación. Ningún objeto puede pertenecer directamente a estas clases. Las clases que heredan (la herencia se verá en el capítulo 4) de una clase abstracta deben implementar sus métodos. Las clases abstractas se explican en detalle en el apartado del capítulo 4. o Clases concretas: los objetos pueden pertenecer directamente a estas clases

106 3.2. Constructor y destructor. Ya se ha comentado que la clase es como una especie de molde que permite crear objetos. Para llevar a cabo la creación de objetos hace uso de un elemento llamado constructor. El constructor es un método que se declara con el mismo nombre que la clase y en el que se deben especificar los atributos a inicializar. Una clase sin constructor lo único que puede hacer es generar los objetos, pero vacíos (sin inicializar). El compilador MinGW Developer Studio proporciona un constructor por defecto que permite crear los objetos vacíos de forma automática. A continuación se muestra un ejemplo de un constructor: Persona(string nombre, int edad); A este constructor se le llama constructor personalizado ya que lo especifica el programador. Cuando no haya creado un constructor personalizado entonces será el constructor por defecto el que creará los objetos. En caso de que exista más de un constructor personalizado, éstos deben ser claramente diferenciables por sus argumentos (número o tipo). A este fenómeno mediante el cual varios métodos (el constructor también es un método) tienen el mismo nombre pero con distintos argumentos y definición se le llama sobrecarga. Cuando se invoca un método sobrecargado, el compilador analiza los argumentos de la llamada y, en función de su tipo, deduce cuál de las distintas versiones del método con ese nombre debe recibir el control. Debido a la sobrecarga, en C++ es obligatoria la declaración de los métodos y de los tipos de sus argumentos (int, float, string, char, etc.). A continuación se muestran tres constructores sobrecargados de la clase Persona: Persona(string nombre); Persona(int edad); Persona(string nombre, int edad); Como se ve en el ejemplo sobre estas líneas, los tres constructores se diferencian entre ellos en el número de argumentos salvo los dos primeros que

107 tienen el mismo número. Sin embargo, estos dos se diferencian en el tipo de argumento por lo que el conflicto es inexistente. Por otra parte, existe un elemento que es invocado por el compilador de forma automática antes de la destrucción de un objeto. Este elemento recibe el nombre de destructor. Su declaración dentro de la clase es opcional y no devuelve tipo alguno ni admite parámetros. Se nombra con el nombre de la clase precedido del símbolo ~. A continuación se muestra el destructor de la clase Persona: ~Persona(){} 3.3. Creación de objetos. Aunque el elemento que se encarga de la creación de objetos, el constructor, ya ha sido explicado no así el proceso de creación de objetos. Existen dos formas de crear objetos: o Automática (Nombre_Clase Nombre_objeto (argumentos)): El compilador se encarga de incluir el código necesario para crearlo antes de su primer uso y para destruirlo después de su último uso. Su alcance comienza en su declaración y termina con el bloque de código en el que se ha declarado (encerrado entre llaves). Si no pertenece a ningún bloque se crea al iniciarse el programa y se destruye inmediatamente antes de finalizar el programa. A continuación se muestran dos ejemplos de creación de objetos de forma automática: Persona per1( Pedro, 65); Persona per1(); //Utilizando el constructor //Persona(string nombre, int edad); //Utilizando el constructor por //defecto

108 o Dinámica (operadores new y delete): Permite decidir el momento de la creación y destrucción de los objetos. Usa asignación dinámica de memoria (variables de tipo puntero). A continuación se muestran un ejemplo de creación y destrucción de objetos de forma dinámica: Persona *per1; //Declaración de la variable per1 de clase Persona per1 = new Persona( Juana, 27); //Creación del objeto per1 usando //el constructor Persona(string //nombre, int edad); delete per1; // Destrucción del objeto per1 Dependiendo de la forma elegida a la hora de crear un objeto cambiará la forma de acceder a sus métodos. Por ello se distinguen dos casos: o Si el objeto fue creado de forma automática, entonces el acceso a sus métodos se hará mediante el operador punto (.) tal y como se muestra a continuación. Persona per1( Pedro, 65); per1.setedad(45); // Creación automática //NombreObjeto.método o Si el objeto fue creado de forma dinámica, entonces el acceso a sus métodos se hará mediante el operador flecha (->) tal y como se muestra a continuación. Persona *per1; // Declaración del objeto per1 = new Persona( Juana, 27); // Creación dinámica per1->setedad(34); //NombreObjeto->método

109 3.4. Especificadores de acceso. Al comienzo de este capítulo se decía que la interfaz de un objeto define el conjunto de métodos accesibles a dicho objeto. Además, se decía que los atributos forman parte de la zona oculta al usuario y a la que no se tiene acceso. Pues bien, los especificadores de acceso permiten determinar el nivel de acceso de los miembros de una clase y, por tanto, diferenciar entre la zona oculta y la interfaz. Se utilizan pues para determinar el nivel de ocultación de cada objeto (la ocultación se explicará en el apartado 4.2 del capítulo 4). Los especificadores de acceso permiten poner en práctica un principio básico de POO como es el encapsulamiento. Según este principio todo objeto tiene una capacidad de aislamiento (atributos y métodos) respecto a otros objetos de la misma o de otra clase. En definitiva, que el acceso a los atributos de un objetos se debe hacer por medio de sus métodos. Este principio se explicará en detalle en el apartado 4.1 del capítulo 4. Existen tres tipos de especificadores de acceso: o private: es opcional y se toma por defecto desde el principio de la definición de la clase hasta que aparece otro especificador de acceso. Los atributos y los métodos sólo son accesibles desde la propia clase. Es el especificador de acceso más restrictivo. Los atributos son siempre private ya que sólo tendrá acceso a ellos la propia clase puesto que no forman parte de la interfaz del objeto. o public: los atributos y los métodos son accesibles por cualquier clase. Es el especificador de acceso menos restrictivo. Los métodos son siempre public puesto que forman parte de la interfaz del objeto. o protected: los atributos y métodos son accesibles sólo por la clase que los contiene y todas aquellas que hereden de ésta (la herencia se explicará en el apartado 4.4 del capítulo 4). Se encuentra entre private y public, en un nivel restrictivo intermedio

110 3.5. Ficheros de cabecera y Espacio de nombres. Programación Orientada a Objetos A la hora de crear programas en C++ es necesario incluir dos sentencias que permitan posteriormente la utilización de instrucciones de las librerías de C++. Estas sentencias son: #include<iostream> y using namespace std; La instrucción #include<iostream> incluye el contenido del fichero de cabecera de flujo de entrada/salida (input output stream) en el código del programa. C++ dispone de dos jerarquías de clases para las operaciones de entrada/salida: una de bajo nivel, streambuf, que no se va a explicar porque sólo es utilizada por programadores expertos, y otra de alto nivel, con las clases: istream, ostream y iostream, que derivan de la clase ios. Estas clases disponen de variables y métodos para controlar los flujos de entrada y salida. La clase que se emplea normalmente para controlar el flujo de entrada/salida es iostream. A continuación se muestra la jerarquía de clases de entrada y salida de C++ donde las clases ifstream, ofstream y fstream se utilizan para el manejo de ficheros

111 En C++ se distinguen dos tipos de ficheros de cabecera: C y C++. Los de C no hacen uso de espacio de nombres y llevan el prefijo c. Por ejemplo, cstdio, cstdlib o cstring. Los ficheros de encabezado de C++, sin embargo, hacen uso de espacio de nombres (el espacio de nombres estándar std). En ambos casos, no llevan la extensión.h. Temporalmente, es posible que estén disponibles los ficheros de cabecera antiguos (con la extensión.h), pero no se aconseja su uso. Además, hay que tener cuidado para no confundir string.h (librería de C), cstring (librería de C adaptada para ser usada en C++) y string (librería de C++). Las librerías estándar de C++ están definidas dentro de un espacio de nombres llamado std. Por tanto, si se quiere evitar el tener que emplear el operador de ámbito (::) constantemente, hay que añadir la sentencia using namespace std; justo después de la inclusión (#include) de las librerías. Esta sentencia permite, por tanto, el acceso a todos los miembros definidos en el espacio de nombres std que se emplea en el fichero iostream

112 3.6. Ejemplo de aplicación orientada a objetos mediante MinGW Developer Una vez vistos los conceptos básicos para entender el desarrollo de una aplicación orientada a objetos en C++ se verá el ejemplo de la clase Persona desarrollado en MinGW Developer A continuación se muestra el contenido del fichero Persona.h que contiene la definición de la clase Persona. // Declaración de la Clase Persona #include<iostream> using namespace std; class Persona { private: // Atributos string nombre; int edad; public: //Getters string getnombre(void){return nombre;} int getedad(void){return edad;} //Setters void setnombre(string _nombre){nombre=_nombre;} void setedad(int _edad){edad=_edad;} //Constructor Persona(string _nombre, int _edad) { nombre=_nombre; edad=_edad; } }; Es preciso comentar que cuando se desarrollan aplicaciones orientadas a objetos es muy habitual declarar las diferentes clases con las que se va a

113 trabajar en ficheros de cabecera independientes (extensión.h) y luego incluirlas en el programa principal por medio de la directiva #include. A continuación se muestra el programa principal (fichero programa.cpp) que incluye el fichero Persona.h mostrado anteriormente. // Programa principal #include<iostream> #include "Persona.h" using namespace std; // Inclusión del fichero donde se declara // la clase Persona int main(void) { Persona *p1; p1=new Persona("Pedro", 48); // Creación dinámica Persona p2("ana", 35); // Creación automática cout<<"persona 1 - Nombre: "<<p1->getnombre()<<" Edad: " <<p1->getedad()<<endl; // Información del objeto dinámico p1 } cout<<"persona 2 - Nombre: "<<p2.getnombre()<<" Edad: " <<p2.getedad()<<endl; // Información del objeto automático p2 En el ejemplo que se muestra sobre estas líneas se crean dos objetos de clase Persona y se muestra su información. El primer objeto, p1, se crea de forma dinámica mediante el operador new tras haber sido declarado en la línea anterior. Hay que recordar que el objeto va precedido del operador asterisco (*) en su declaración. El segundo objeto, p2, es creado de forma automática por lo que la declaración y creación del objeto van en la misma línea de código. Posteriormente, mediante cout (se explicará en el siguiente apartado) se muestra la información de ambos objetos invocando a sus métodos correspondientes (getnombre para obtener el nombre y getedad para obtener la

114 edad). En el caso del objeto p1, creado de forma dinámica, se accede a sus métodos mediante una flecha según lo descrito en el apartado 3.3. Por último, se muestra la salida por pantalla tras la ejecución del código mostrado anteriormente: 3.7. Operadores de entrada/salida. En todo programa C++ existen dos elementos que permiten al usuario comunicarse con el programa. Se trata de la salida estándar, cout y de la entrada estándar cin. Estos elementos permiten enviar a la pantalla o leer desde el teclado cualquier variable o constante, incluidos literales. Equivale a las funciones printf y scanf propias del lenguaje de programación C y situadas en la librería stdio.h. cout es un objeto de la clase ostream y cin un objeto de la clase istream. Como ambas clases heredan de la clase superior iostream basta con incluir esta última clase al comienzo del programa para poder utilizar ambos objetos. El diagrama con la jerarquía de clases para efectuar entrada/salida en C++ se mostró anteriormente en el apartado 3.5. A continuación se muestra el formato de utilización de ambas clases:

115 #include <iostream> using namespace std; cout << <variable constante> [<< <variable constante>...]; cin >> <variable> [>> <variable>...]; Su uso es muy simple tal y como se muestra en el siguiente ejemplo donde se lee un número por medio de cin y se muestra en pantalla por medio de cout: #include <iostream> using namespace std; int main() { int a; } cin >> a; cout << "la variable a vale " << a; Un método muy útil para cout es endl, que hará que la siguiente salida se imprima en una nueva línea. cout << hola << endl; Otro método, éste para cin es get(), que sirve para leer un carácter, pero que nos puede servir para detener la ejecución de un programa. Esto es especialmente útil cuando se trabaja con compiladores que crean programas de consola win32 en los que se produce lo siguiente: cuando se ejecutan los programas desde el compilador con el que se esté trabajando, al terminar se cierra la ventana automáticamente, impidiendo ver los resultados. Usando get() se puede detener la ejecución del programa hasta que se pulse una tecla. Por otra parte, hay veces, sobre todo después de una lectura mediante cin, en las que pueden quedar caracteres pendientes de leer. En ese caso hay que usar más de una línea cin.get()

116 3.8. Modificadores. Las variables que se declaran en los programas desarrollados en lenguaje de programación C++ tienen el siguiente formato: [mod_general] [mod_almacenamiento] tipo identificador [=valor] [mod_general] [mod_almacenamiento] tipo identificador [(valor)] La diferencia entre ambos formatos reside en que la inicialización de una variable puede realizarse de forma convencional mediante el operador de asignación = (primer caso) o bien situando el valor entre paréntesis (segundo caso). Los modificadores son opcionales y se sitúan antes del tipo de la variable a inicializar. Existen dos tipos de modificadores: modificadores generales y modificadores de almacenamiento. o Modificador general: Indica al compilador una variación en el comportamiento habitual de una variable. Si no aparece el compilador no asume ninguno por defecto. Existen los siguientes tipos: const: Constantes, se marcan como de solo lectura y no pueden modificarse durante el resto de la ejecución. Una variable definida como const se comporta como una constante (numérica o literal) en todo el programa y sólo se le puede asignar un valor inicial. Su ventaja principal frente a la directiva #define es que el compilador realiza una comprobación de tipos. Ejemplo: const int tamano=1; volatile: El valor de la variable se puede alterar por medios distintos al propio programa, por ejemplo una llamada del sistema operativo. Se usan en muy raras ocasiones

117 mutable: Aplicable a objetos, indica que un atributo puede cambiar su valor pese a ser constante (sólo lectura). Se usa raramente. o Modificador de almacenamiento: Indica el tipo de almacenamiento en memoria y el momento en que se crea y se destruye una variable. Existen los siguientes tipos: auto: Automático, no se usa. Es el modificador por defecto. register: La variable se almacena en un registro del procesador. Está obsoleto ya que los compiladores modernos optimizan por defecto la forma en que se deben almacenar las variables. Se mantiene por compatibilidad con códigos más antiguos. static: Cuando una variable es local indica al compilador que solo debe construirla una vez y debe hacer su valor perdurable para futuras ejecuciones del mismo bloque de código. Se suele utilizar sobre todo para limitar el acceso a algunas variables globales. extern: Se utiliza para declarar en el código propio variables globales que se corresponden con variables declaradas en otros módulos

118 3.9. Variable reservada this. this es una variable reservada de C++ que no necesita ser declarada. Esta variable es un puntero al objeto concreto al que se aplica el método que se está ejecutando. Es una variable predefinida para todos los métodos u operadores de una clase. Este puntero contiene la dirección del objeto concreto de la clase al que se está aplicando el método o el operador. Se puede decir que this es un alias del objeto correspondiente. Conviene tener en cuenta que cuando un método se aplica a un objeto de su clase (su argumento implícito), accede directamente a los atributos (sin utilizar el operador punto o flecha), pero no tiene forma de referirse al objeto como tal, pues no le ha sido pasado explícitamente como argumento. Este problema se resuelve con la variable reservada this. A continuación se muestra un ejemplo de empleo de dicha variable en la clase Persona:

119 #include<iostream> using namespace std; class Persona { private: // Atributos string nombre; int edad; public: //Getters string getnombre(void){return nombre;} int getedad(void){return edad;} //Setters void setnombre(string _nombre){nombre=_nombre;} void setedad(int _edad){edad=_edad;} // Método que devuelve el año de nacimiento int devuelvefechanac(void) { return 2008 this->getedad(); } //Constructor Persona(string _nombre, int _edad) { nombre=_nombre; edad=_edad; } }; En el ejemplo anterior se puede ver implementado el método devuelvefechanac que devuelve la fecha de nacimiento de un objeto de clase Persona. Para realizar este cálculo se necesita conocer el valor del atributo edad por lo que se invoca el método getedad gracias a la variable reservada this

120 3.10. Métodos inline. Los métodos inline se utilizan para mejorar la velocidad de ejecución. Un método marcado como inline indica al compilador que debe sustituir cada llamada a dicho método por su código correspondiente. De esta manera se mejora la velocidad de proceso ya que se ahorra las instrucciones de salto y devolución de valores al programa principal. La principal ventaja de un método inline es que mejora la eficiencia del programa sin afectar a su legibilidad. Los métodos cuyo código aparece dentro de la declaración de una clase son por defecto inline. Los métodos inline se usan cuando la implementación del método no es muy compleja como, por ejemplo, métodos que devuelven cálculos muy simples. A continuación se muestra un ejemplo de un método inline que calcula la longitud de una circunferencia a partir de su radio: inline double circun(double radio) int main(void) { { double r; return 2*3.1416*radio; cin >> r; } cout << La longitud de la circunferencia cuyo radio es << r << es: << } circun(r); Se debe tener en cuenta que los compiladores analizan el código del método y deciden si usan el método como inline o como método normal. La decisión depende del compilador. Cuando un método se implementa dentro de la declaración de la clase, se considera como inline. A continuación se muestra un ejemplo de esta situación:

121 #include<iostream> using namespace std; class MiClase { private: // Atributos int i; public: void print() { cout << i << ; } }; // Método inline implícito Clases y métodos friend. Existen ocasiones en las que dos clases están muy relacionadas entre sí de modo que se quiere que una tenga acceso a la otra y que trabajen conjuntamente con los mismos atributos a través de los métodos. Sin embargo, una de las limitaciones que presentan los métodos es que sólo pueden pertenecer a una única clase. Además, un método convencional sólo puede actuar directamente sobre un único objeto de la clase (su argumento implícito, que es el objeto con el que ha sido llamado por medio del operador punto (.) o flecha (->), como por ejemplo en per1.setedad(45)). Para que actúe sobre un segundo o un tercer objeto hay que pasárselos como argumentos. Se puede concluir que a pesar de las grandes ventajas del encapsulamiento (se verá en el apartado 4.1 del capítulo 4), en muchas ocasiones es necesario dotar a la programación orientada a objetos de una mayor flexibilidad. Esto se consigue por medio de los métodos friend. Un método friend de una clase es un método que no pertenece a la clase, pero que tiene permiso para acceder a sus atributos y a sus métodos privados por medio de los operadores punto (.) y flecha (->), sin tener que recurrir a los

122 métodos públicos de la clase. Si una clase se declara friend de otra, todos sus métodos son friend de esta segunda clase. El carácter de friend puede restringirse a métodos concretos, que pueden pertenecer a alguna clase o pueden ser métodos generales que no pertenecen a ninguna clase. Para declarar un método o una clase como friend de otra clase, es necesario hacerlo en la declaración de la clase que debe autorizar el acceso a sus atributos privados. Esto se puede hacer de forma indiferente en la zona de declaración de variables o en la zona privada de declaración de atributos. Un ejemplo de declaración de una clase friend podría ser el que sigue: class MiClase { friend class Amiga; private: int atributo; }; public: int getatributo(){return atributo;} Es muy importante tener en cuenta que esta relación funciona sólo en una dirección, es decir, los métodos de la clase Amiga pueden acceder a los atributos privados de la clase MiClase a través de sus métodos, por ejemplo a la variable entera atributo a través del método getatributo(), pero esto no es cierto en sentido inverso: los métodos de la clase MiClase no pueden acceder a un atributo privado de la clase Amiga a través de sus métodos. Si se quiere que varias clases tengan acceso mutuo a todos los atributos y métodos, cada una debe declararse como friend en todas las demás, para conseguir una relación recíproca. Se plantea un problema cuando dos clases deben ser declaradas mutuamente friend la una de la otra. Considérense por ejemplo las clases vector y matriz. Las declaraciones podrían ser las siguientes:

123 // declaración de las clases vector y matriz (mutuamente friend) class matriz; // declaración anticipada de clase matriz class vector { // declaración de métodos de la clase vector... friend matriz; }; class matriz { // declaración de métodos de la clase matriz... friend vector; }; A primera vista sorprende la segunda línea de lo que sería el fichero de declaración de ambas clases. En esta línea aparece la sentencia class matriz;. Esto es lo que se llama una declaración anticipada, que es necesaria por el motivo que se explica a continuación. Sin declaración anticipada cuando la clase matriz aparece declarada como friend en la clase vector, el compilador aún no tiene noticia de dicha clase, cuya declaración viene después. Al no saber lo que es matriz, da un error. Si la clase matriz se declara antes que la clase vector, el problema se repite, pues vector se declara como friend en matriz. La única solución es esa declaración anticipada que advierte al compilador que matriz es una clase cuya declaración se encuentra más adelante

124 Capítulo 4 Paradigmas de programación

125 CAPÍTULO 4. Paradigmas de programación. Programación Orientada a Objetos Para explicar la POO (Programación Orientada a Objetos) es fundamental enumerar las características o paradigmas propios de este enfoque. En este capítulo se explicarán en detalle los cinco paradigmas más importantes de la POO: el encapsulamiento, la ocultación, la abstracción, la herencia y el polimorfismo Encapsulamiento. En programación orientada a objetos se denomina encapsulamiento a la ocultación del estado, es decir, de los datos (atributos) de un objeto de manera que sólo se pueden cambiar mediante las operaciones (métodos) definidas para ese objeto. Cada objeto está aislado del exterior, es un módulo natural, y la aplicación entera se reduce a un agregado o rompecabezas de objetos. El aislamiento protege a los datos asociados a un objeto contra su modificación por quien no tenga derecho a acceder a ellos, eliminando efectos secundarios e interacciones. De esta forma el usuario de la clase puede obviar la implementación de los métodos y propiedades para concentrarse sólo en cómo usarlos. Por otro lado se evita que el usuario pueda cambiar su estado de manera imprevista e incontrolada. Como se pudo observar en el diagrama del objeto de la clase Persona del capítulo 3 (figura), los atributos del objeto se localizan en el centro o núcleo del objeto. Los métodos rodean y esconden el núcleo del objeto de otros objetos en el programa. Al empaquetamiento de los atributos de un objeto con la protección de sus métodos se le llama encapsulamiento

126 Típicamente, el encapsulamiento es utilizado para esconder detalles de implementación a otros objetos. Entonces, los detalles de implementación pueden cambiar en cualquier momento sin afectar a otras partes del programa. El encapsulamiento de atributos y métodos en un componente de software ordenado es una idea simple pero potente que provee dos principales beneficios a los desarrolladores de software: El encapsulamiento consiste en unir en la clase las características y comportamientos, esto es, los atributos y métodos. Es tener todo esto en una sola entidad. En los lenguajes estructurados esto era imposible. Es evidente que el encapsulamiento se logra gracias a la abstracción y la ocultación que se verán en los próximos apartados. La utilidad del encapsulamiento reside en la facilidad para manejar la complejidad, ya que se tendrá a las clases como cajas negras donde sólo se conoce el comportamiento pero no los detalles internos, y esto es conveniente porque lo que interesará al usuario será conocer qué hace la clase pero no será necesario saber cómo lo hace. El encapsulamiento da lugar a que las clases se dividan en dos partes: Interfaz: captura la visión externa de una clase, abarcando la abstracción del comportamiento común a los ejemplos de esa clase. La interfaz de un objeto ya se explicó al comienzo del capítulo 3. Implementación: comprende la representación de la abstracción, así como los mecanismos que conducen al comportamiento deseado. La forma habitual de poner en práctica el paradigma de encapsulamiento es mediante los especificadores de acceso explicados en el apartado 3.4 del capítulo

127 4.2. Ocultación. El paradigma de ocultación hace referencia a que los atributos privados de un objeto no pueden ser modificados ni obtenidos a no ser que se haga a través de los métodos públicos pertenecientes a su interfaz. Como ya se ha comentado anteriormente, los atributos de un objeto no son accesibles de manera directa sino que hay que pasar por los métodos para acceder a ellos. Esto se debe a que los atributos están ocultos mientras que los métodos forman parte de la interfaz del objeto, es decir, la parte visible por el resto de objetos. Precisamente es la interfaz la que materializa la definición de ocultación. Cada objeto está aislado del exterior, es un módulo natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las propiedades de un objeto contra su modificación por quien no tenga derecho a acceder a ellas, solamente los propios métodos internos del objeto pueden acceder a su estado. Esto asegura que otros objetos no pueden cambiar el estado interno de un objeto de manera inesperada, eliminando efectos secundarios e interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso directo a los datos internos del objeto de una manera controlada y limitando el grado de abstracción. La aplicación entera se reduce entonces a un agregado o rompecabezas de objetos

128 4.3. Abstracción. La abstracción expresa las características esenciales de un objeto, las cuales distinguen al objeto de los demás. Además de distinguir entre los objetos provee límites conceptuales. Entonces se puede decir que el encapsulamiento separa las características esenciales de las no esenciales dentro de un objeto. Si un objeto tiene más características de las necesarias resultará difícil de usar, modificar, construir y comprender. La abstracción genera una percepción de simplicidad dado que minimiza la cantidad de características que definen a un objeto. A la hora de realizar la abstracción de un elemento del mundo real se hace lo siguiente: se selecciona el elemento y se toma la parte que interesa, la parte representativa del objeto, omitiendo así algunas características de dicho elemento. Si el programador toma los atributos que le interesan, entonces se trata de una abstracción de datos. Si por el contrario toma los métodos que le interesan, entonces será una abstracción funcional. Cada objeto en el sistema sirve como modelo de un "agente" abstracto que puede realizar trabajo, informar y cambiar su estado, y "comunicarse" con otros objetos en el sistema sin revelar cómo se implementan estas características. Los procesos, las funciones o los métodos pueden también ser abstraídos y cuando lo están, una variedad de técnicas son requeridas para ampliar una abstracción. Pensar en términos de objetos es muy parecido a cómo se haría en la vida real. Por ejemplo se va a pensar en un coche para tratar de modelarlo en un esquema de POO. Se podría decir que el coche es el elemento principal que tiene una serie de características, como podrían ser el color, el modelo o la marca. Además tiene una serie de funcionalidades asociadas, como pueden ser ponerse en marcha, parar o aparcar

129 Pues en un esquema POO el coche sería el objeto, las características serían los atributos como el color o el modelo y los métodos serían las funcionalidades asociadas como ponerse en marcha o parar. Estos objetos se podrán utilizar en las aplicaciones, por ejemplo en un programa que gestione un taller de coches se utilizarán objetos coche. Las aplicaciones orientadas a objetos utilizan muchos objetos para realizar las acciones que se desean realizar y ellas mismas también son objetos. Es decir, el taller de coches será un objeto que utilizará objetos coche, herramienta, mecánico, recambios, etc Herencia. La mente humana clasifica los conceptos de acuerdo a dos dimensiones: pertenencia y variedad. Se puede decir que el Seat Ibiza es un tipo de coche (variedad o relación del tipo es un) y que una rueda es parte de un coche (pertenencia o relación del tipo tiene un). En C++ se puede resolver el problema de la pertenencia mediante las estructuras, que pueden ser todo lo complejas que se quiera. Pero con la herencia se consigue clasificar los tipos de datos (abstracciones) por variedad, acercando así un paso más la programación al modo de razonar humano. La herencia se define como la capacidad de definir jerarquías mediante la división de una clase en subclases. La herencia permite que una clase (y los objetos que pertenecen a ella) herede los métodos y atributos de su clase base. La herencia permite, por tanto, definir una clase modificando una o más clases ya existentes. Estas modificaciones consisten habitualmente en añadir nuevos miembros (atributos o métodos) a la clase que se está definiendo, aunque también se pueden redefinir atributos o métodos ya existentes. La clase base de la que se parte en este proceso recibe el nombre de superclase o clase padre, y la nueva clase que se obtiene se denomina subclase

130 o clase hija. Ésta a su vez puede ser superclase en un nuevo proceso de derivación, iniciando de esta manera una jerarquía de clases. De ordinario las superclases suelen ser más generales que las subclases. Esto es así porque a las subclases se les suele ir añadiendo características, en definitiva atributos y métodos que diferencian, concretan y particularizan. En algunos casos una clase no tiene otra utilidad que la de ser superclase para otras clases que hereden de ella. A este tipo de superclases, de las que no se declara ningún objeto, se les denomina superclases abstractas y su función es la de agrupar miembros comunes de otras clases que heredarán de ellas. Por ejemplo, se puede definir la clase vehículo para después derivar de ella coche, bicicleta, patinete, etc., pero todos los objetos que se declaren pertenecerán a alguna de estas últimas clases; no habrá vehículos que sean sólo vehículos. Las características comunes de estas clases (como un atributo que indique si está parado o en marcha, otro que indique su velocidad, el método de arrancar y el de frenar, etc.), pertenecerán a la superclase y las que sean particulares de alguna de ellas pertenecerán sólo a la subclase (por ejemplo el número de platos y piñones, que sólo tiene sentido para una bicicleta, o el método embragar que sólo se aplicará a los vehículos de motor con varias marchas). Este mecanismo de herencia presenta múltiples ventajas evidentes a primera vista, si bien la más importante y la que dota a la POO de gran potencia es la posibilidad de reutilizar código sin tener que escribirlo de nuevo. Esto es posible porque todas las subclases pueden utilizar el código de la superclase sin tener que volver a definirlo en cada una de ellas. Además, la reusabilidad permite desarrollar nuevas clases (clases hija) tomando como referencia clases ya existentes (clases padre). Otra gran ventaja de la herencia es la eliminación de redundancias ya que en la superclase se definen los métodos y atributos comunes a las subclases. Uno de los problemas que aparece con la herencia es el del control del acceso a los datos. Puede un método de una subclase acceder a los atributos

131 privados de su superclase? En principio una clase no puede acceder a los atributos privados de otra, pero podría ser muy conveniente que una subclase accediera a todos los atributos de su superclase. Para hacer posible esto, existe el especificador de acceso protected. Este especificador es privado para todas aquellas clases que no son subclases, pero público para una subclase de la clase en la que se ha definido el atributo como protected. A la hora de aplicar la herencia existen dos formas: o por especialización: la nueva clase especializa el comportamiento de la clase ya existente. A Especializa Nueva Clase En el ejemplo de herencia por especialización de la figura, Nueva Clase hereda de A y A es, por tanto, una especialización de NC (Nueva Clase). A será la superclase o clase padre mientras que NC será la subclase o clase hija. Como NC hereda de A se puede decir que NC es un A y que la subclase (NC) tendrá los mismos métodos y atributos que la superclase (A) así como lo que la subclase NC refinará para generalizar el comportamiento

132 o por generalización: la nueva clase generaliza el concepto de la clase ya existente. Nueva Clase Generaliza A En el ejemplo de herencia por generalización de la figura, Nueva Clase es una generalización de A. NC tendrá, por tanto, los mismos métodos y atributos de A así como aquellos que hayan sido implementados para llevar a cabo dicha generalización. Para entender estos conceptos de forma más clara se explicará un ejemplo del mundo real. Si se piensa en dos conceptos como son Trabajador y Persona se llega a las siguientes conclusiones: o Trabajador es un refinamiento de Persona o Trabajador especializa a Persona Se puede decir entonces que Trabajador es una Persona. A continuación se muestra el código de este mismo ejemplo programado en C++ en MinGW Developer

133 Clase Persona (fichero Persona.h) // Declaración de la Superclase Persona #include<iostream> using namespace std; class Persona { protected: // Atributos string nombre; int edad; public: //Getters string getnombre(void){return nombre;} int getedad(void){return edad;} //Setters void setnombre(string _nombre){nombre=_nombre;} void setedad(int _edad){edad=_edad;} //Constructor Persona(string _nombre, int _edad) { nombre=_nombre; edad=_edad; } }; Antes de mostrar la clase Trabajador, que hereda de la clase Persona, es preciso mostrar la sintaxis para llevar a cabo la herencia: class A { }; class B : public A { }; // Clase padre o superclase // Clase hija o subclase

134 Clase Trabajador (fichero Trabajador.h) // Declaración de la Subclase Trabajador #include<iostream> using namespace std; class Trabajador : public Persona // Trabajador subclase de Persona { private: // Atributos long sueldo; string departamento; public: //Getters long getsueldo(void){return sueldo;} string getdepartamento(void){return departamento;} //Setters void setsueldo(long _sueldo){sueldo=_sueldo;} void setdepartamento (string _departamento) {departamento=_departamento;} //Constructor Trabajador(string _nombre, int _edad, long _sueldo, string _departamento) : Persona(_nombre, _edad) { sueldo=_sueldo; departamento=_departamento; } }; A continuación se muestra el programa principal en el que se crea un objeto de clase Trabajador y se muestra su información:

135 Programa principal (fichero programa.cpp) #include<iostream> // Se incluyen los ficheros donde se definen las clases #include "Persona.h" #include "Trabajador.h" using namespace std; int main(void) { Trabajador *t1; t1 = new Trabajador("Antonio", 54, 2500, "Finanzas"); cout<<endl<<"trabajador 1 - Nombre: "<<t1->getnombre() <<" Edad: "<<t1->getedad()<<" Sueldo: " <<t1->getsueldo()<<" Departamento: " <<t1->getdepartamento()<<endl; } Explicación del ejemplo de herencia Trabajador-Persona o Persona.h: La superclase Persona es la misma que se mostró en el apartado 3.6 del capítulo 3 exceptuando una modificación que se realizó en el especificador de acceso de los atributos. El especificador pasó de ser public a ser protected para permitir a la subclase (Trabajador) acceder a sus atributos. Este especificador es privado para todas aquellas clases que no son subclases de la clase Persona. o Trabajador.h: La subclase Trabajador hereda de la clase Persona por lo que en su definición se especifica esta situación mediante la sentencia class Trabajador : public Persona. La clase Trabajador tendrá, por tanto, los mismos métodos y atributos que la clase Persona, su superclase. Además, tiene dos atributos adicionales como son el sueldo y el departamento en el que trabaja. Estos atributos son accedidos por medio de los getters y setters que también se definen en la clase

136 Trabajador. Por último, el constructor tendrá como parámetros sus atributos así como los de la superclase y se invocará el constructor de la superclase mediante una llamada directa por medio de la sentencia Trabajador(string _nombre, int _edad, long _sueldo, string _departamento) : Persona(_nombre, _edad) que permitirá crear un objeto de la clase Trabajador sin necesidad de reescribir el código necesario para definir los atributos de la superclase. El constructor de la clase padre es invocado siempre (de forma directa o indirectamente) antes de la ejecución del constructor de la subclase. o Programa.cpp: El programa principal necesita conocer la definición de la clase Persona y de su subclase Trabajador. Es por ello que es necesario incluir mediante la directiva #include los dos ficheros de cabecera donde se definen ambas clases. En el programa se crea un objeto de la clase Trabajador con un nombre, una edad, un sueldo y un departamento en el que trabaja. Hay que recordar que aunque nombre y edad son atributos de la clase Persona, la clase Trabajador hereda de ésta por lo que dichos atributos también pertenecerán a la subclase. Una vez creado el objeto t1 de clase Trabajador se muestra su información invocando los métodos correspondientes. A continuación se muestra la salida por pantalla tras la ejecución del código mostrado anteriormente:

137 Ahora se mostrará un diagrama del ejemplo anterior donde se visualizará de manera clara el funcionamiento de la herencia. Como se puede observar en la figura, la subclase Trabajador hereda los atributos y métodos de la superclase Persona. Además, define dos atributos y sus correspondientes métodos que refinan y especializan a la clase Persona. Estos atributos y métodos aparecen subrayados en color rojo en la figura. El constructor de Trabajador tendrá por parámetros los atributos heredados de Persona así como los definidos en la propia clase

138 Herencia múltiple. Hasta ahora se ha explicado la herencia simple, donde una clase sólo puede heredar de una superclase. Pues bien, la herencia múltiple permite que una clase pueda heredar comportamientos y características de más de una superclase. La herencia múltiple permite a una clase tomar funcionalidades de otras clases, como permitir a una clase llamada Hidroplano heredar de una clase llamada Aeroplano y una clase llamada Barco. La sintaxis necesaria para llevar a cabo la herencia múltiple en C++ se muestra a continuación: class Aeroplano { }; class Barco { }; class Hidroplano : public Aeroplano, public Barco { }; En la herencia múltiple aparecen ambigüedades, por lo que debe usarse con cuidado ya que pueden presentarse problemas como los siguientes: o Una misma clase no debe especificarse dos o más veces como superclase de una dada. Este hecho puede producirse indirectamente como en el caso: class A { }; class B : public A { }; class C : public A { }; class D : public B, public C { };

139 o Una clase no puede heredar un mismo atributo o método de dos superclases. Cada lenguaje de programación trata estos problemas de herencia múltiple de forma diferente. En el caso de C++, el lenguaje requiere que el programador establezca de qué clase padre vendrá la característica a usar por medio del operador :: tal y como se muestra a continuación: Subclase :: Superclase.nombre_Atributo Subclase :: Superclase.nombre_Método 4.5. Polimorfismo. Se entiende por polimorfismo la capacidad de definir métodos distintos, que comparten el mismo nombre, pero que se aplican a clases diferentes. Estos métodos pueden actuar sobre objetos distintos dentro de una jerarquía de clases, sin tener que especificar el tipo exacto de los objetos. Esto se puede entender mejor con el siguiente ejemplo: Clase Triángulo + Pintar() Clase Cuadrado + Pintar() En el ejemplo que se ve en la figura se observa una jerarquía de clases. En los dos niveles de esta jerarquía está contenido un método llamado Pintar(). Este método no tiene por qué ser igual en todas las clases, aunque es habitual

140 que sea un método que efectúe una operación muy parecida sobre distintos tipos de objetos. Es importante comprender que el compilador no decide en tiempo de compilación cuál será el método que se debe utilizar en un momento dado del programa. Esa decisión se toma en tiempo de ejecución. A este proceso de decisión en tiempo de ejecución se le denomina vinculación dinámica, en oposición a la habitual vinculación estática, consistente en decidir en tiempo de compilación qué método se aplica en cada caso. A este tipo de métodos, incluidos en varios niveles de una jerarquía de clases con el mismo nombre pero con distinta definición se les denomina métodos virtuales. Hay que insistir en que la definición del método en cada nivel es distinta. El polimorfismo hace posible que un usuario pueda añadir nuevas clases a una jerarquía sin modificar o recompilar el código original. Esto quiere decir que si desea añadir una nueva subclase es suficiente con establecer la clase padre, definir sus atributos y métodos, y compilar esta parte del código, ensamblándolo después con lo que ya estaba compilado previamente. Es necesario comentar que los métodos virtuales son algo menos eficientes que los métodos normales. A continuación se explica, sin entrar en gran detalle, el funcionamiento de los métodos virtuales. Cada clase que utiliza métodos virtuales tiene un vector de punteros, uno por cada método virtual, llamado v-table. Cada uno de los punteros contenidos en ese vector apunta al método virtual apropiado para esa clase, que será, habitualmente, el método virtual definido en la propia clase. En el caso de que en esa clase no esté definido el método virtual en cuestión, el puntero de v-table apuntará al método virtual de su clase padre más próxima en la jerarquía, que tenga una definición propia del método virtual. Esto quiere decir que buscará primero en la propia

141 clase, luego en la clase anterior en el orden jerárquico y se irá subiendo en ese orden hasta dar con una clase que tenga definido el método buscado. Cada objeto creado de una clase que tenga un método virtual contiene un puntero oculto a la v-table de su clase. Mediante ese puntero accede a su v- table correspondiente y a través de esta tabla accede a la definición adecuada del método virtual. Es este trabajo extra el que hace que los métodos virtuales sean menos eficientes que los métodos normales. Como ejemplo se puede suponer la clase Trabajador y la clase Mecanico. Ambas tienen el método calcularsueldo() pero con la siguiente diferencia: o Trabajador: el sueldo se calcula como el número de horas trabajadas multiplicado por 6. o Mecanico: el sueldo se calcula como el número de horas trabajadas multiplicado por 20. Además, se añade un extra de 100 por cada reparación que realice en el plazo de reparación establecido. El código correspondiente a los métodos explicados sería el siguiente: // método virtual de la clase Trabajador virtual void calcularsueldo() { //El método getnumhoras() devuelve el número de horas trabajadas sueldo=this.getnumhoras()*6; } // método virtual de la clase Mecanico virtual void calcularsueldo() { //El método getnumhoras() devuelve el número de horas trabajadas //El método getnumrep() devuelve el número de reparaciones //realizadas dentro del plazo establecido sueldo=this.getnumhoras()*20 + this.getnumrep()*100; }

142 La idea central del polimorfismo es la de poder llamar a métodos distintos aunque tengan el mismo nombre, según la clase a la que pertenece el objeto al que se aplican. Esto es imposible utilizando nombres de objetos: siempre se aplica el método de la clase correspondiente al nombre del objeto y esto se decide en tiempo de compilación. Sin embargo, utilizando punteros puede conseguirse el objetivo buscado. Recuérdese que un puntero a la clase padre puede contener direcciones de objetos de cualquiera de las subclases. En principio, el tipo de puntero determina también el método que es llamado, pero si se utilizan métodos virtuales es el tipo de objeto al que apunta el puntero lo que determina el método que se llama. Esta es la esencia del polimorfismo Implementación de los métodos virtuales. Un método virtual puede ser llamado como un método convencional, es decir, utilizando vinculación estática. En este caso no se están aprovechando las características de los métodos virtuales, pero el programa puede funcionar correctamente. A continuación se presenta un ejemplo de este tipo de implementación que no es recomendable usar, ya que utilizando un método convencional se ganaría en eficiencia: Clase_A Objeto_1; Clase_A *Puntero_1; float atributo; // Se definen un objeto de una clase // y un puntero que puede apuntarlo Puntero_1 = &Objeto_1; atributo = Objeto_1.metodo_1(); //Utilización de vinculación estática atributo = Puntero_1->metodo_1();//Con métodos virtuales. Absurdo En el ejemplo anterior en las dos asignaciones a la variable atributo, los métodos que se van a utilizar se determinan en tiempo de compilación

143 A continuación se presenta un ejemplo de utilización correcta de los métodos virtuales: Clase_Padre Objeto_Padre; Clase_Hija Objeto_Hijo; Clase_Padre *Puntero_Padre_1; Clase_Padre *Puntero_Padre_2; float atributo;... // El puntero a la clase padre puede apuntar a un objeto de la clase // padre Puntero_Padre_1 = &Objeto_Padre; // o a un objeto de la clase hija Puntero_Padre_2 = &Objeto_Hijo;... // Utilización correcta de un método virtual atributo = Puntero_Padre_2->metodo_1(); En este nuevo ejemplo se utiliza vinculación dinámica, ya que el Puntero_Padre_2 puede apuntar a un objeto de la clase padre o a un objeto de cualquiera de las clases hija en el momento de la asignación a la variable atributo, en la última línea del ejemplo. Por eso, es necesariamente en tiempo de ejecución cuando el programa decide cuál es el metodo_1 concreto que tiene que utilizar. Ese metodo_1 será el definido para la clase del Objeto_Hijo si está definido, o la de la clase padre más próxima en el orden jerárquico que tenga definido ese metodo_

144 Métodos virtuales puros. Habitualmente los métodos virtuales de la clase padre de la jerarquía no se utilizan porque en la mayoría de los casos no se declaran objetos de esa clase, y/o porque todas las subclases tienen su propia definición del método virtual. Sin embargo, incluso en el caso de que el método virtual de la clase padre no vaya a ser utilizado, debe declararse. De todos modos, si el método no va a ser utilizado es necesario definirlo, y es suficiente con declararlo como método virtual puro. Un método virtual puro se declara así: Virtual metodo_1()=0; // Método virtual puro La única utilidad de esta declaración es la de posibilitar la definición de métodos virtuales en las subclases. De alguna manera se puede decir que la definición de un método como virtual puro hace necesaria la definición de ese método en las subclases, a la vez que imposibilita su utilización con objetos de la superclase. Al definir un método virtual se debe tener en cuenta que: o No hace falta definir el código de ese método en la superclase. o No se pueden definir objetos de la superclase, ya que no se puede llamar a los métodos virtuales puros. o Sin embargo, es posible definir punteros a la superclase, pues es a través de ellos como será posible manejar objetos de las subclases

145 Clases abstractas. Se denomina clase abstracta a aquella que contiene uno o más métodos virtuales puros. El nombre se debe a que no puede existir ningún objeto de esa clase. Si una subclase no redefine un método virtual, la subclase la hereda como método virtual puro y se convierte también en clase abstracta. Por el contrario, aquellas subclases que redefinen todos los métodos virtuales puros de sus superclases reciben el nombre de subclases concretas, nomenclatura únicamente utilizada para diferenciarlas de las mencionadas anteriormente. Aparentemente puede parecer que carece de sentido definir una clase de la que no va a existir ningún objeto, pero se puede afirmar, sin miedo a equivocarse, que la abstracción es una herramienta imprescindible para un correcto diseño de la Programación Orientada a Objetos. Es evidente que la jerarquía que se presenta en la figura sobre estas líneas no es suficiente, porque un avión y un helicóptero, o un patinete y una bicicleta, serían objetos de la misma clase. Pero lo que se pretende ilustrar es la necesidad de una clase Vehículo que englobe las características comunes de todos ellos (dimensiones, peso, velocidad máxima, ) aunque no exista ningún objeto de esa clase, ya que cualquier vehículo en el que se piense, podrá definirse como un objeto de una subclase de la primera superclase

146 Habitualmente las clases superiores de muchas jerarquías de clases son clases abstractas y las clases que heredan de ellas definen sus propios métodos virtuales, convirtiéndose así en clases concretas Destructores virtuales. Como norma general, el constructor de la superclase se llama antes que el constructor de la subclase. Con los destructores, sin embargo, sucede al revés: el destructor de la subclase se llama antes que el de la superclase. Por esa razón, en el caso de que se borre, aplicando delete, un puntero a un objeto de la superclase que apunte a un objeto de una subclase, se llamará al destructor de la superclase, en vez de al destructor de la subclase, que sería lo adecuado. La solución a este problema consiste en declarar como virtual el destructor de la superclase. Esto hace que automáticamente los destructores de las subclases sean también virtuales, a pesar de tener nombres distintos. De este modo, al aplicar delete a un puntero de la superclase que puede apuntar a un puntero de ese tipo o a cualquier objeto de una subclase, se aplica el destructor adecuado en cada caso. Por eso es conveniente declarar un destructor virtual en todas las clases abstractas, ya que aunque no sea necesario para esa clase, sí puede serlo para una clase que herede de ella. Este problema no se presenta con los constructores y por eso no existe ningún tipo de constructor virtual o similar

147 PARTE III: Estudio de las librerías gráficas del compilador para permitir desarrollar interfaces gráficas de usuario (GUI)

148 Capítulo 1 Introducción

149 CAPÍTULO 1. Introducción. La interacción entre las personas y los ordenadores en la actualidad se realiza principalmente a través de interfaces gráficas de usuario (Graphical User Interfaces - GUI), un tipo de interfaz de usuario compuesto por metáforas gráficas inscritas en una superficie de contacto. Esta superficie contiene además otros elementos como los iconos, botones, controles, etc. e interfaces humanos (dispositivos de entrada como el ratón o el teclado) necesarios para posibilitar dicha interacción con los signos-objetos en la interfaz gráfica. El concepto de interfaz de usuario es un concepto amplio que se utiliza para referirse de forma genérica al espacio que media la relación de un sujeto y un ordenador o sistema interactivo. El interfaz de usuario es esa ventana mágica de un sistema informático que posibilita a una persona interactuar con él. Cuando se habla de interfaz gráfica de usuario, el concepto es aún más específico en cuanto que supone un tipo específico de interfaz que usa metáforas visuales y signos gráficos como paradigma interactivo entre la persona y el ordenador. La interfaz gráfica de usuario se define, pues, como un método de interacción con un ordenador a través del paradigma de manipulación directa de imágenes gráficas, controles y texto. En el contexto del proceso de interacción persona-ordenador, la interfaz gráfica de usuario es el artefacto tecnológico de un sistema interactivo que posibilita, a través del uso y la representación del lenguaje visual, una interacción amigable con un sistema informático. La interfaz gráfica de usuario es un tipo de interfaz de usuario que utiliza un conjunto de imágenes y objetos gráficos para representar la información y acciones disponibles en la interfaz. Habitualmente las acciones se realizan mediante manipulación directa para facilitar la interacción del usuario con el ordenador

150 Las interfaces gráficas de usuario surgen como evolución de la línea de comandos de los primeros sistemas operativos y son pieza fundamental en un entorno gráfico. Como ejemplo de interfaces gráficas de usuario se pueden citar el escritorio o desktop del sistema operativo Windows, el entorno X-Window de Linux o el entorno Finder de Mac OS X. La historia reciente de la informática está indisolublemente unida a las interfaces gráficas, puesto que los sistemas operativos gráficos han ocasionado grandes consecuencias en la industria del software y del hardware. Las interfaces gráficas surgen de la necesidad de hacer los ordenadores más accesibles para el uso de los usuarios comunes. La mayoría de ordenadores domésticos requerían conocimientos de BASIC (el 95% de ellos mostraban el intérprete BASIC al encenderse) u ofrecían una interfaz de línea de órdenes (como los sistemas operativos CP/M o los diferentes OS del Apple II), lo que requería conocimientos por encima de la media si se deseaba hacer algo más que usarlo como consola de videojuegos. Esta limitación fue salvada gracias al desarrollo de los entornos gráficos, que permitieron que las personas pudieran acceder a un ordenador sin tener que pasar por el tortuoso proceso de tener que aprender a manejar un entorno bajo línea de órdenes

151 Capítulo 2 API de Windows (WinAPI)

152 CAPÍTULO 2. API de Windows. A la hora de programar interfaces gráficas de usuario (GUI) mediante MinGW Developer Studio se emplea el API (Application Programs Interface) de Windows, también conocido como WinAPI Introducción. El API de Windows, WinAPI, es un conjunto de interfaces de programación de aplicaciones (application programming interfaces - API) de Microsoft disponible en los sistemas operativos Microsoft Windows. Todos los programas Windows deben interactuar con el API de Windows sin importar el lenguaje de programación. La Windows Driver Foundation o API Nativa (Native API), utilizada principalmente por drivers de dispositivo, proporciona acceso de bajo nivel a sistemas Windows. El API de Windows está formado por más de 600 funciones en lenguaje de programación C. Para acceder a ella los compiladores utilizan librerías de objetos, permitiendo acceder al API de manera más rápida y sencilla. La librería de MinGW Developer Studio que permite dicho acceso es windows.h. Hasta 1985, los ordenadores empleaban el sistema operativo MS-DOS. Este sistema operativo funcionaba a base de interrupciones de tal modo que cada vez que un programa necesitaba hacer algo, llamaba a una interrupción, servicio de BIOS o de DOS. Sin embargo, en Agosto de 1985 apareció en el mercado la primera versión de Windows que disponía de interfaz gráfica de usuario y con ella se produjo un cambio radical. Este cambio se basa en que en Windows es el propio sistema operativo el que llama al programa por medio de mensajes cada vez que se mueve el ratón, se pulsa una tecla del teclado o se produce lo que se conoce como evento. Cuando esto sucede, el sistema operativo avisa al programa del cambio (evento) por medio de un mensaje y éste

153 decide si quiere llamar a una interrupción que lo controle. En caso de llamar a una interrupción de DOS se hará por medio del API de Windows. En Windows se dispone de un kit de desarrollo software (software development kit - SDK) que proporciona documentación y herramientas para permitir a los desarrolladores crear software usando el API de Windows y las tecnologías asociadas a Windows. La funcionalidad que proporciona el API de Windows se puede agrupar en ocho categorías: o Servicios Básicos (Base Services) o Servicios Avanzados (Advanced Services) o Interfaz de Gráficos de Dispositivos (Graphics Device Interface) o User Interface (Interfaz de Usuario) o Librería Común de Cuadro de Diálogo (Common Dialog Box Library) o Librería Común de Control (Common Control Library) o Shell de Windows (Windows Shell) o Servicios de Red (Network Services) La categoría en la que se profundizará será la de Interfaz de Usuario (User Interface) ya que es la que proporciona la funcionalidad para crear y gestionar ventanas y controles básicos como botones y cajas de texto, recibir eventos del ratón y el teclado, y otra funcionalidad asociada con la parte GUI de Windows. Esta unidad funcional reside en el fichero user.exe en Windows de 16 bits y en el fichero user32.dll en Windows de 32 bits. Desde la primera versión de Windows XP, los controles básicos residen en el fichero comctl32.dll, junto con los controles básicos (Common Control Library)

154 2.2. Características de la programación en Windows. A la hora de explicar la forma en que se programan las interfaces gráficas de usuario en Windows usando el API es preciso explicar una serie de características especiales de la programación en Windows como son la independencia, los recursos, las ventanas, los eventos y los controles Independencia de la máquina. Los programas Windows son independientes de la máquina en la que se ejecutan (o al menos deberían serlo), el acceso a los dispositivos físicos se hace a través de interfaces, y nunca se accede directamente a ellos. Esta es una de las principales ventajas para el programador, que no tiene que preocuparse por el modelo de tarjeta gráfica o de impresora que emplea puesto que la aplicación funcionará con todas, y será el sistema operativo el que se encargue de que así sea Recursos. Un concepto importante es el de recurso. Desde el punto de vista de Windows, un recurso es todo aquello que puede ser usado por una o varias aplicaciones. Existen recursos físicos, que son los dispositivos que componen el ordenador, como la memoria, la impresora, el teclado o el ratón y recursos virtuales o lógicos, como los gráficos, los iconos o las cadenas de caracteres. Por ejemplo, si una aplicación requiere el uso de un puerto serie, primero debe averiguar si está disponible, es decir, si existe y si no lo está usando otra aplicación; y después lo reservará para su uso. Esto es necesario porque este tipo de recurso no puede ser compartido. Lo mismo pasa con la memoria o con la tarjeta de sonido, aunque son casos diferentes. Por ejemplo, la memoria puede ser compartida, pero de una

155 forma general, cada porción de memoria no puede compartirse y se trata de un recurso finito. Las tarjetas de sonido, dependiendo del modelo, podrán o no compartirse por varias aplicaciones. Otros recursos como el ratón y el teclado también se comparten, pero se asigna su uso automáticamente a la aplicación activa, que normalmente se conoce como la que tiene el "foco", es decir, la que mantiene contacto con el usuario. Desde el punto de vista del programador de aplicaciones, también se consideran como recursos varios componentes como los menús, los iconos, los cuadros de diálogo, las cadenas de caracteres, los mapas de bits, los cursores, etc. En los programas, Windows almacena separados el código y los recursos, dentro del mismo fichero, y estos últimos pueden ser editados por separado, permitiendo por ejemplo, hacer versiones de los programas en distintos idiomas sin tener acceso a los ficheros fuente de la aplicación Ventanas. La forma en que se presentan las aplicaciones Windows (al menos las interactivas) ante el usuario, es la ventana. Una ventana es un área rectangular de la pantalla que se usa de interfaz entre la aplicación y el usuario. Cada aplicación tiene al menos una ventana, la ventana principal, y todas las comunicaciones entre usuario y aplicación se canalizan a través de una ventana. Cada ventana comparte el espacio de la pantalla con otras ventanas, incluso de otras aplicaciones, aunque sólo una puede estar activa, es decir, sólo una puede recibir información del usuario Eventos. Los programas en Windows están orientados a eventos, es decir, normalmente están esperando a que se produzca un acontecimiento que les incumba, y mientras tanto permanecen dormidos

156 Un evento puede ser, por ejemplo, el movimiento del ratón, la activación de un menú, la llegada de información desde el puerto serie, una pulsación de una tecla, etc. Esto se debe a que Windows es un sistema operativo multitarea, y el tiempo del microprocesador ha de repartirse entre todos los programas que se estén ejecutando. Si los programas fueran secuenciales puros, esto no sería posible, ya que hasta que una aplicación finalizara, el sistema no podría atender al resto. Ejemplo de programa secuencial:

157 Ejemplo de programa por eventos: Controles. Los controles son la forma en que las aplicaciones Windows intercambian datos con el usuario. Normalmente se usan dentro de los cuadros de diálogo, pero en realidad pueden usarse en cualquier ventana. Los más importantes y conocidos son: o control static: son etiquetas, marcos, iconos o dibujos. o control edit: permiten que el usuario introduzca datos alfanuméricos en la aplicación. o control list box: el usuario puede escoger entre varias opciones de una lista. o control combo box: es una combinación entre un edit y un list box. o control scroll bar: barras de desplazamiento, para la introducción de valores entre márgenes definidos

158 o control button: realizan acciones o comandos. Del control button derivan otros dos controles muy comunes: control check box: permite leer variables de dos estados "checked" o "unchecked". control radio button: se usa en grupos. Dentro de cada grupo sólo uno puede ser activado Creación de proyectos WinAPI en MinGW Developer Inicialmente, el área de trabajo del entorno de desarrollo está vacía. Para crear ahora la estructura de una nueva aplicación WinAPI, se procede del siguiente modo: a. Se elige la opción New en el menú File (o se pulsan las teclas Ctrl y N simultáneamente) o bien se pulsa el botón herramientas. de la barra de

159 b. A continuación, se presenta una ventana en la que se puede elegir el tipo de aplicación que se desea crear. Se selecciona la pestaña Projects y la aplicación de tipo Win32 Application. Ahora se procede a nombrar el proyecto escribiendo el nombre que se desea en el cuadro Project name. En el cuadro Location se permite especificar la ruta de acceso al directorio, es decir, el directorio donde se creará la carpeta de nombre igual al del proyecto y que contendrá todos los ficheros relativos al proyecto (ejecutables, código fuente, etc.). Una vez especificado el nombre del proyecto y la ruta de acceso se confirma el cuadro de diálogo pulsando OK y ya se ha creado un proyecto nuevo. En el directorio especificado en el cuadro Location se habrá creado un fichero llamado nombre_del_proyecto.msp/mdsp (MinGWStudio Project Files). c. El paso siguiente es crear un fichero y añadirlo al proyecto actualmente vacío. Se elige la opción New del menú File (o se pulsan las teclas Ctrl y N simultáneamente) o se pulsa el botón de la barra de herramientas. Se selecciona la pestaña Files y el fichero de tipo C/C++ Source File para crear un fichero de lenguaje de programación C (*.c) que contenga el código fuente. Se nombra el fichero (se debe añadir la extensión.c) en el cuadro File name y se confirma pulsando OK. El campo Location no debe ser modificado ya que por defecto se muestra la ruta de acceso al directorio del proyecto creado anteriormente. Además, la checkbox Add to project se encuentra activada para añadir el fichero al proyecto que se

160 había creado previamente. Por tanto, la ruta de acceso y la checkbox no deben ser modificadas. En el directorio del proyecto se habrá creado un fichero llamado nombre_del_fichero.c (C Source File). d. El entorno ya está listo para introducir el código en la zona de edición

161 2.4. Componentes de una ventana. En este apartado se verán los elementos que componen una ventana, si bien no todos tienen por qué estar presentes en todas las ventanas. 1) El borde de la ventana: hay varios tipos, dependiendo de que estén o no activas las opciones de cambiar el tamaño de la ventana. Se trata de un área estrecha alrededor de la ventana que permite cambiar su tamaño. 2) Barra de título: zona en la parte superior de la ventana que contiene el icono y el título de la ventana. Esta zona también se usa para mover la ventana a través de la pantalla, y mediante doble clic, para cambiar entre el modo maximizado y el tamaño normal. 3) Caja de minimizar: pequeña área cuadrada situada en la parte derecha de la barra de título que sirve para disminuir el tamaño de la ventana. Antes de la aparición de Windows 95 la ventana se convertía a su forma icónica, pero desde la aparición de Windows 95 los iconos desaparecieron, la ventana se oculta y sólo permanece un botón en la barra de estado. 4) Caja de maximizar: pequeña área cuadrada situada en la parte derecha de la barra de título que sirve para agrandar la ventana para que ocupe toda la pantalla. Cuando la ventana está maximizada, se sustituye por la caja de restaurar

162 5) Caja de cerrar: pequeña área cuadrada situada en la parte derecha de la barra de título que sirve para cerrar la ventana. 6) Caja de control de menú: pequeña área cuadrada situada en la parte izquierda de la barra de título que normalmente contiene el icono de la ventana, y sirve para desplegar el menú del sistema. Menú (o menú del sistema): se trata de una ventana especial que contiene las funciones comunes a todas las ventanas, también accesibles desde las cajas y el borde, como minimizar, restaurar, maximizar, mover, cambiar tamaño y cerrar. Este menú se despliega al pulsar sobre la caja de control de menú. 7) Barra de menú: zona situada debajo de la barra de título que contiene los menús de la aplicación. 8) Barra de scroll horizontal: barra situada en la parte inferior de la ventana que permite desplazar horizontalmente la vista del área del cliente. 9) Barra de scroll vertical: barra situada en la parte derecha de la ventana que permite desplazar verticalmente la vista del área de cliente. 10) Área de cliente: es la zona donde el programador sitúa los controles y los datos para el usuario. En general es toda la superficie de la ventana que no está ocupada por las zonas anteriormente descritas

163 2.5. Notación húngara. La notación húngara es un sistema usado normalmente para crear los nombres de variables, tipos y estructuras cuando se programa en Windows. Es el sistema usado en la programación del sistema operativo, y también por la mayoría de los programadores. Fundamentalmente ayudará a interpretar el tipo básico al que pertenece cada estructura, miembro o tipo definido. Consiste en prefijos en minúsculas que se añaden a los nombres de las variables, y que indican su tipo; en el caso de tipos definidos, las letras del prefijo estarán en mayúscula. El resto del nombre indica la función que realiza la variable o tipo. A continuación se muestra una tabla con el significado de los prefijos más utilizados en notación húngara: Prefijo Significado b Booleano c Carácter (un byte) dw Entero largo de 32 bits sin signo (DOBLE WORD) f Flags empaquetados en un entero de 16 bits h Manipulador de 16 bits (HANDLE) l Entero largo de 32 bits lp Puntero a entero largo de 32 bits lpfn Puntero largo a una función que devuelve un entero lpsz Puntero largo a una cadena terminada con cero n Entero de 16 bits p Puntero a entero de 16 bits pt Coordenadas (x, y) empaquetadas en un entero de 32 bits rgb Valor de color RGB empaquetado en un entero de 32 bits sz Cadena terminada en cero u Sin signo (unsigned) w Entero corto de 16 bits sin signo (WORD)

164 Por último se muestran una serie de ejemplos de variables creadas con notación húngara así como ejemplos de tipos definidos por el API de Windows: o ncontador: la variable es un entero que se usará como contador. o sznombre: una cadena terminada con cero que almacena un nombre. o brespuesta: una variable booleana que almacena una respuesta. Ejemplos de tipos definidos por el API de Windows: o UINT: entero sin signo. Windows redefine los enteros para asegurar que el tamaño en bits es siempre el mismo para todas las variables del API. o LRESULT: entero largo usado como valor de retorno. o WPARAM: entero corto de 16 bits usado como parámetro. o LPARAM: entero largo de 32 bits usado como parámetro. o LPSTR: puntero largo a una cadena de caracteres. En el API de 32 bits no existen distinciones entre punteros largos y cortos, pero la nomenclatura se conserva por compatibilidad. o LPCREATESTRUCT: puntero a una estructura CREATESTRUCT, que define los parámetros de inicialización pasados al procedimiento ventana de una aplicación

165 2.6. Estructura de un programa Windows GUI. Programación Orientada a Objetos Hay algunas diferencias entre la estructura de un programa C/C++ normal y la correspondiente a un programa Windows GUI. Algunas de estas diferencias se deben a que los programas GUI están basados en mensajes mientras que otras son sencillamente debidas a que siempre hay un determinado número de tareas que hay que realizar. // Ficheros include #include <windows.h> // Prototipos LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM); // Función de entrada int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdparam, int ncmdshow) { // Declaración // Inicialización // Bucle de mensajes return Message.wParam; } // Definición de funciones Cabeceras. Lo primero que hay que hacer para poder usar las funciones del API de Windows es incluir al menos un fichero de cabecera, pero generalmente no bastará con uno. La librería windows.h contiene la mayoría de los ficheros de cabecera corrientes en aplicaciones GUI, pero se pueden incluir sólo los que se necesiten, siempre que se sepa cuáles son. Por ejemplo, la función WinMain está declarada en el fichero de cabecera winbase.h

166 Generalmente esto resultará incómodo, ya que para cada nueva función, mensaje o estructura habrá que comprobar, y si es necesario, incluir nuevos ficheros. Por ello se usa directamente windows.h Prototipos. Cada tipo (o clase) de ventana que se use en un programa (normalmente sólo será una), o cuadro de diálogo (puede haber muchos), necesitará un procedimiento propio, que se debe declarar y definir. Siguiendo la estructura de un programa C, esta es la zona normal de declaración de prototipos Función de de entrada WinMain. La función de entrada de un programa Windows es WinMain, en lugar de la conocida main. Normalmente, la definición de esta función cambia muy poco de unas aplicaciones a otras. Se divide en tres partes claramente diferenciadas: declaración, inicialización y bucle de mensajes Parámetros de entrada de WinMain. int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdparam, int ncmdshow) La función WinMain tiene cuatro parámetros de entrada: o hinstance: es un manipulador para la instancia del programa que se esté ejecutando. Cada vez que se ejecuta una aplicación, Windows crea una instancia para ella, y le pasa un manipulador de dicha instancia a la aplicación. o hprevinstance: es un manipulador a instancias previas de la misma aplicación. Como Windows es multitarea, pueden existir varias versiones

167 de la misma aplicación ejecutándose, varias instancias. En Windows 3.1, este parámetro servía para saber si la aplicación ya se estaba ejecutando, y de ese modo se podían compartir los datos comunes a todas las instancias. Pero eso era antes, ya que Win32 usa un segmento distinto para cada instancia y este parámetro es siempre NULL, sólo se conserva por motivos de compatibilidad. o lpszcmdparam: esta cadena contiene los argumentos de entrada del comando de línea. o ncmdshow: este parámetro especifica cómo se mostrará la ventana. Se recomienda no usar este parámetro en la función ShowWindow la primera vez que ésta es llamada. En su lugar debe usarse el valor SW_SHOWDEFAULT Función WinMain típica. int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdparam, int ncmdshow) { HWND hwnd; /* Manipulador de ventana */ MSG mensaje; /* Mensajes recibidos por la aplicación */ WNDCLASSEX wincl; /*Estructura de datos para la clase de ventana*/ /* Inicialización: */ /* Estructura de la ventana */ wincl.hinstance = hinstance; wincl.lpszclassname = "NOMBRE_CLASE"; wincl.lpfnwndproc = WindowProcedure; wincl.style = CS_DBLCLKS; wincl.cbsize = sizeof(wndclassex); /* Usar icono y puntero por defecto */

168 wincl.hicon = LoadIcon(NULL, IDI_APPLICATION); wincl.hiconsm = LoadIcon(NULL, IDI_APPLICATION); wincl.hcursor = LoadCursor(NULL, IDC_ARROW); wincl.lpszmenuname = NULL; wincl.cbclsextra = 0; wincl.cbwndextra = 0; wincl.hbrbackground = (HBRUSH)COLOR_BACKGROUND; Programación Orientada a Objetos /* Registrar la clase de ventana, si falla, salir del programa */ if(!registerclassex(&wincl)) return 0; hwnd = CreateWindowEx( 0, "NOMBRE_CLASE", "Ventana 1", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hinstance, NULL ); ShowWindow(hwnd, SW_SHOWDEFAULT); /* Bucle de mensajes: */ while(true == GetMessage(&mensaje, 0, 0, 0)) { TranslateMessage(&mensaje); DispatchMessage(&mensaje); } } return mensaje.wparam;

169 Declaración. En la primera zona se declaran las variables que se necesitan para la función WinMain, que como mínimo serán tres: o HWND hwnd: es un manipulador para la ventana principal de la aplicación. Se sabe pues que la aplicación necesitará al menos una ventana. o MSG mensaje: es una variable para manipular los mensajes que lleguen a la aplicación. o WNDCLASSEX wincl: es una estructura que se usará para registrar la clase particular de ventana que se usará en la aplicación Inicialización. Esta zona se encarga de registrar la clase o clases de ventana, crear la ventana y visualizarla en pantalla. Para registrar la clase primero hay que rellenar adecuadamente la estructura WNDCLASSEX, que define algunas características que serán comunes a todas las ventanas de una misma clase como color de fondo, icono, menú por defecto, el procedimiento de ventana, etc. Después hay que llamar a la función RegisterClassEx. A continuación se crea la ventana usando la función CreateWindowEx. Cualquiera de estas dos funciones devuelve un manipulador de ventana que se puede necesitar en otras funciones como, por ejemplo, la función ShowWindow. Lo descrito anteriormente es fundamental pero esto no muestra la ventana en la pantalla. Para que la ventana sea visible hay que llamar a la función ShowWindow. La primera vez que se llama a esta función, después de

170 crear la ventana, se puede usar el parámetro ncmdshow de WinMain como parámetro o usar el valor SW_SHOWDEFAULT, opción ésta recomendada por Windows Bucle de mensajes. Este es el núcleo de la aplicación. Tal y como se observa en el código, el programa permanece en este bucle mientras la función GetMessage devuelve un valor TRUE. while(true == GetMessage(&mensaje, 0, 0, 0)) { TranslateMessage(&mensaje); DispatchMessage(&mensaje); } La función TranslateMessage se usa para traducir los mensajes de teclas virtuales a mensajes de carácter. Los mensajes traducidos se reenvían a la lista de mensajes del proceso, y se recuperarán con las siguientes llamadas a GetMessage. La función DispatchMessage envía el mensaje al procedimiento de ventana, donde será tratado adecuadamente. El procedimiento de ventana se explicará en el punto 2.7 y una vez explicado se estará en disposición de crear una interfaz gráfica de usuario mediante MinGW Developer Definición de funciones. En esta zona se definen, entre otras cosas, los procedimientos de ventana, que se encargan de procesar los mensajes que lleguen a cada ventana. Los procedimientos de ventana se explicarán a continuación

171 2.7. El procedimiento de ventana. Cada ventana tiene una función asociada que se conoce como procedimiento de ventana, y es la encargada de procesar adecuadamente todos los mensajes enviados a una determinada clase de ventana. Es la responsable de todo lo relativo al aspecto y al comportamiento de una ventana. Normalmente, estas funciones están basadas en una estructura "switch" donde cada "case" corresponde a un determinado tipo de mensaje Sintaxis. LRESULT CALLBACK WindowProcedure ( HWND hwnd, // Manipulador de ventana UINT mensaje, // Mensaje WPARAM wparam, // Parámetro palabra, varía LPARAM lparam // Parámetro doble palabra, varía ); o hwnd es el manipulador de la ventana a la que está destinado el mensaje. o mensaje es el código del mensaje. o wparam es el parámetro de tipo palabra asociado al mensaje. o lparam es el parámetro de tipo doble palabra asociado al mensaje. Se puede considerar este prototipo como una plantilla para crear procedimientos de ventana. El nombre de la función puede cambiar, pero el valor de retorno y los parámetros deben ser los mismos. El miembro lpfnwndproc de la estructura WNDCLASSEX es un puntero a una función de este tipo. Esa función es la que se encargará de procesar todos los mensajes para esa clase de ventana. Cuando se registra la clase de ventana, se tiene que asignar a ese miembro el puntero al procedimiento de ventana

172 Prototipo de procedimiento de ventana. Programación Orientada a Objetos LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM); Implementación de procedimiento de ventana simple. /* Esta función es llamada por la función del API DispatchMessage() */ LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT mensaje, WPARAM wparam, LPARAM lparam) { switch (mensaje) /* manipulador del mensaje */ { case WM_DESTROY: /* envía un mensaje WM_QUIT a la cola de mensajes */ PostQuitMessage(0); break; default: /* para los mensajes de los que no se ocupa el usuario */ return DefWindowProc(hwnd, mensaje, wparam, lparam); } return 0; } En general, habrá tantos procedimientos de ventana como programas diferentes y todos serán distintos, pero también tendrán algo en común: todos ellos procesarán los mensajes que lleguen a una clase de ventana. En este ejemplo sólo se procesa un tipo de mensaje, se trata de WM_DESTROY que es el mensaje que se envía a una ventana cuando se recibe un comando de cerrar, ya sea por menú o mediante el icono de aspa en la esquina superior derecha de la ventana. Este mensaje sólo sirve para informar a la aplicación de que el usuario tiene la intención de abandonar la aplicación, y le da una oportunidad de dejar las cosas en su sitio: cerrar ficheros, liberar memoria, guardar variables, etc. Esto lo hace enviándole un mensaje WM_QUIT, mediante la función PostQuitMessage

173 El resto de los mensajes se procesan en el caso "default", y simplemente se cede su tratamiento a la función del API que hace el proceso por defecto para cada mensaje, DefWindowProc. Este es el camino que sigue el mensaje WM_QUIT cuando llega, ya que el proceso por defecto para este mensaje es cerrar la aplicación Ejemplo GUI mediante MinGW Developer Una vez explicados los procedimientos de ventana ya se puede mostrar el primer ejemplo de interfaz gráfica de usuario mediante MinGW Developer El siguiente segmento de código muestra una ventana por pantalla. #include <windows.h> /* Declaración del procedimiento de ventana */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdparam, int ncmdshow) { HWND hwnd; /* Manipulador de ventana */ MSG mensaje; /* Mensajes recibidos por la aplicación */ WNDCLASSEX wincl; /*Estructura de datos para la clase de ventana*/ /* Inicialización: */ /* Estructura de la ventana */ wincl.hinstance = hinstance; wincl.lpszclassname = "NOMBRE_CLASE"; wincl.lpfnwndproc = WindowProcedure; wincl.style = CS_DBLCLKS; wincl.cbsize = sizeof(wndclassex); /* Usar icono y puntero por defecto */ wincl.hicon = LoadIcon(NULL, IDI_APPLICATION); wincl.hiconsm = LoadIcon(NULL, IDI_APPLICATION);

174 } wincl.hcursor = LoadCursor(NULL, IDC_ARROW); wincl.lpszmenuname = NULL; wincl.cbclsextra = 0; wincl.cbwndextra = 0; wincl.hbrbackground = (HBRUSH)COLOR_BACKGROUND; Programación Orientada a Objetos /* Registrar la clase de ventana, si falla, salir del programa */ if(!registerclassex(&wincl)) return 0; hwnd = CreateWindowEx( ); 0, "NOMBRE_CLASE", "Ventana 1", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hinstance, NULL ShowWindow(hwnd, SW_SHOWDEFAULT); /* Bucle de mensajes: */ while(true == GetMessage(&mensaje, 0, 0, 0)) { } TranslateMessage(&mensaje); DispatchMessage(&mensaje); return mensaje.wparam; /* Esta función es invocada por la función DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT mensaje, WPARAM wparam, LPARAM lparam) { switch (mensaje) /* manipulador de mensaje */ { case WM_DESTROY: cola de mensajes */ PostQuitMessage (0); /* Envía el mensaje WM_QUIT a la

175 } break; default: /* Mensajes que no se quieren manejar */ return DefWindowProc (hwnd, mensaje, wparam, lparam); } return 0; La salida por pantalla tras ejecutar el código anterior sería la siguiente:

176 Capítulo 3 Menús y cuadros de diálogo

177 CAPÍTULO 3. Menús y cuadros de diálogo. Programación Orientada a Objetos En el presente capítulo se explican dos herramientas fundamentales a la hora de desarrollar interfaces gráficas de usuario (GUI). Estas herramientas son los menús y los cuadros de diálogo Menús. Una vez explicado el esqueleto de una aplicación gráfica, se verá una herramienta fundamental de comunicación con ella: el menú. Un menú es una ventana un tanto especial, del tipo pop-up, que contiene una lista de comandos u opciones entre las cuales el usuario puede elegir. Cuando los menús se usan en una aplicación, normalmente se agrupan bajo una barra horizontal, que es también un menú, dividida en varias zonas o ítems. Cada ítem de un menú, salvo los separadores y aquellos que despliegan nuevos menús, tiene asociado un identificador. El valor de ese identificador se usará por parte de la aplicación para saber qué opción activó el usuario y decidir las acciones a tomar en consecuencia. La forma más sencilla y frecuente de implementar menús es mediante ficheros de recursos (extensión *.rc). A la hora de trabajar con ficheros de recursos es importante adquirir algunas buenas costumbres como son: o Usar siempre etiquetas como identificadores de los ítems de los menús, y nunca valores numéricos literales. o Crear un fichero de cabecera con las definiciones de los identificadores. Se llamará, por ejemplo, ids.h

178 o Este fichero de cabecera se incluirá tanto en el fichero de recursos como en el del código fuente de la aplicación. A la hora de elaborar el fichero de recursos existen dos opciones: mediante el editor de recursos del compilador o mediante un editor de texto (por ejemplo, el Bloc de notas). La primera alternativa se explicará en el siguiente capítulo mientras que la primera se explicará a continuación. La creación de ficheros de recursos mediante un editor de texto ayudará a entender el funcionamiento y utilidad de estos ficheros antes de explicar su creación por medio del editor de recursos del compilador. Dicho esto se procede a explicarla. Supóngase que se quiere crear una aplicación con un menú que contenga dos ítems: Abrir y Salir. Como ya se ha comentado anteriormente, estos ítems tendrán asociado un identificador que debe ser declarado en el fichero de cabecera ids.h. Es por ello que la primera línea del fichero de recursos debe ser: #include ids.h Siendo el fichero de cabecera ids.h el siguiente: #define ABRIR 1000 #define SALIR 1001 Una vez se ha hecho el include del fichero ids.h se procede a elaborar el fichero de recursos. Dicho fichero debe contener la declaración del menú así como de los ítems que lo componen, que en este caso serán dos. El primer ítem (ABRIR) tendrá el identificador 1000 mientras que el segundo (SALIR) tendrá el Una vez dicho esto se muestra el fichero de recursos ya creado:

179 Menu MENU BEGIN END POPUP "&Menú" BEGIN END MENUITEM "&Abrir", ABRIR MENUITEM SEPARATOR MENUITEM "&Salir", SALIR Programación Orientada a Objetos El fichero de recursos sobre estas líneas permite crear la estructura del menú de forma fácil. El ejemplo crea una barra de menú con una columna Menú, con dos opciones: Abrir y Salir, y con un separador entre ambas. La sintaxis es sencilla, se define el menú mediante una cadena identificadora, sin comillas, seguida de la palabra MENU. Entre las palabras BEGIN y END se pueden incluir ítems, separadores u otras columnas. Para incluir columnas se usa una sentencia del tipo POPUP seguida de la cadena que se mostrará como texto en el menú. Cada POPUP se comporta del mismo modo que un MENU. Los ítems se crean usando la palabra MENUITEM seguida de la cadena que se mostrará en el menú, una coma, y el comando asignado a ese ítem, que será una macro definida en el fichero ids.h. SEPARATOR. Los separadores se crean usando MENUITEM seguido de la palabra Como se puede observar en el ejemplo, las cadenas que se muestran en el menú contienen el símbolo & en su interior, por ejemplo &Abrir. Este símbolo indica que la siguiente letra puede usarse para activar la opción del menú desde el teclado, usando la tecla [ALT] más la letra que sigue al símbolo &. Para indicar dicha situación, en pantalla se muestra esa letra subrayada, por ejemplo Abrir

180 El último paso que se debe realizar es usar el menú creado desde el fichero fuente. Para ello se deben realizar los siguientes pasos: o Incluir el fichero de cabecera ids.h mediante la sentencia #include ids.h. o Asignar el menú creado como menú por defecto de la clase. Para ello se realiza la siguiente asignación en la función WinMain: WNDCLASSEX wincl;... wincl.lpszmenuname = Menu ; Otra alternativa, más compleja que la explicada, a la hora de usar un menú es la de cargarlo y asignarlo a la ventana por medio de la función LoadMenu en la llamada a CreateWindowEx. El código necesario para llevar a cabo esta alternativa se muestra a continuación: hwnd = CreateWindowEx( 0, "NOMBRE_CLASE", "Ventana 1", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, LoadMenu(hInstance, "Menu"), /* Carga y asignación de menú */ NULL, hinstance, NULL ); A continuación se explicará la función MessageBox que se empleará para mostrar cuadros de mensaje una vez pulsada una opción del menú

181 Función MessageBox. Una vez explicada la forma de crear un menú y asignarlo a una ventana se explicará un mecanismo muy simple para informar al usuario de cualquier situación que se produzca en la aplicación. Este mecanismo es el cuadro de mensaje (message box), que consiste en una pequeña ventana con un mensaje para el usuario y uno o varios botones, según el tipo de cuadro de mensaje que se use. Para visualizar un cuadro de mensaje simple se usará la función MessageBox. La función MessageBox es una función perteneciente a la cabecera winuser.h que crea, muestra y ejecuta un cuadro de mensaje. El cuadro de mensaje contiene un mensaje definido por la aplicación y un título, así como cualquier combinación de iconos predefinidos y botones. La sintaxis de la función es la siguiente: int MessageBox( HWND hwnd, // manipulador de la ventana propietaria LPCTSTR lptext, // dirección del texto del mensaje LPCTSTR lpcaption, // dirección del texto del título UINT utype // estilo del cuadro de mensaje ); Los parámetros de la función tienen el siguiente significado: o hwnd: identifica a la ventana propietaria del cuadro de mensaje a crear. Si este parámetro es NULL, el cuadro de mensaje no tendrá ventana propietaria. o lptext: apunta a una cadena terminada en cero que contiene el mensaje a mostrar

182 o lpcaption: apunta a una cadena terminada en cero usada como título para el cuadro de diálogo. Si este parámetro es NULL, se usará el título por defecto de Error. o utype: especifica el contenido y comportamiento del cuadro de diálogo. A continuación se muestra una tabla con algunos de los valores más empleados del parámetro utype: Valor MB_ABORTRETRYIGNORE MB_ICONEXCLAMATION MB_ICONQUESTION MB_ICONSTOP MB_OK MB_OKCANCEL MB_RETRYCANCEL MB_YESNO MB_YESNOCANCEL Significado El cuadro de mensaje contiene tres botones: Anular, Reintentar e Omitir. Se mostrará un icono de exclamación. Se mostrará un icono con una interrogación. Se mostrará un icono con un signo de stop. El cuadro de mensaje contiene un único botón de Aceptar. El cuadro de mensaje contiene dos botones: Aceptar y Cancelar. El cuadro de mensaje contiene dos botones: Reintentar y Cancelar. El cuadro de mensaje contiene dos botones: Sí y No. El cuadro de mensaje contiene tres botones: Sí, No y Cancelar

183 mensaje: Programación Orientada a Objetos A continuación se mostrará un ejemplo de un pequeño cuadro de MessageBox(hwnd, Fichero guardado OK., Guardar Fichero, MB_OK); La salida por pantalla sería la siguiente: Una vez explicada la manera de crear cuadros de mensaje proseguimos con el ejemplo del menú. A pesar de que el menú ya había sido creado y asociado a la ventana, sus dos opciones (Abrir y Salir) carecían de comportamiento. Es por ello que ahora se está en disposición de asignar a cada opción un cuadro de mensaje que informe acerca del comando del menú que se ha pulsado. Al pulsar una opción del menú se produce una activación del mismo. Esta activación se recibe mediante un mensaje WM_COMMAND. Para procesar estos mensajes se utilizará la palabra de menor peso del parámetro wparam del mensaje. Es por ello que dentro del case WM_COMMAND en el procedimiento de ventana se hará un switch en función del identificador del ítem del parámetro wparam. Para extraer dicho identificador se emplea la macro LOWORD. Una vez hecho esto ya sólo falta mostrar en cada case correspondiente a cada ítem del menú un cuadro de mensaje que informe acerca de la opción pulsada. A continuación se muestra el código del procedimiento de ventana para procesar los mensajes del menú:

184 LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT mensaje, WPARAM wparam, LPARAM lparam) { switch (mensaje) /* manipulador del mensaje */ { case WM_COMMAND: switch(loword(wparam)) { case ABRIR: "Mensaje de menú", MB_OK); MessageBox(hwnd, "Se ha pulsado la opción Abrir.", break; case SALIR: "Mensaje de menú", MB_OK); cola de mensajes */ } de mensajes */ } } break; MessageBox(hwnd, "Se ha pulsado la opción Salir.", PostQuitMessage(0); break; case WM_DESTROY: PostQuitMessage(0); break; /* envía un mensaje WM_QUIT a la /* envía un mensaje WM_QUIT a la cola default: /* Mensajes que no se quieren manejar */ return 0; return DefWindowProc(hwnd, mensaje, wparam, lparam); También se puede ver en el código sobre estas líneas que cuando se pulsa la opción Salir se sale de la aplicación mediante la función PostQuitMessage. Con este último trozo de código se da por terminada la explicación del ejemplo de aplicación de menú con cuadros de mensaje. En el siguiente apartado se muestra el código de todos los ficheros del ejemplo así como las salidas por pantalla

185 Ejemplo completo de menús y cuadros de mensaje. En este apartado se muestra el contenido de los ficheros necesarios para desarrollar el ejemplo de menús y cuadros de mensaje explicado anteriormente así como las salidas por pantalla de la aplicación final. Se mostrarán, pues, los ficheros ids.h, menu.rc y menu.c. Fichero de identificadores (fichero ids.h) #define ABRIR 1000 #define SALIR 1001 Fichero de recursos (fichero menu.rc) #include "ids.h" Menu MENU BEGIN POPUP "&Menú" BEGIN MENUITEM "&Abrir", ABRIR MENUITEM SEPARATOR MENUITEM "&Salir", SALIR END END

186 Programa Principal (fichero menu.c) #include <windows.h> #include "ids.h" /* Declaración del procedimiento de ventana */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdparam, int ncmdshow) { HWND hwnd; /* Manipulador de ventana */ MSG mensaje; /* Mensajes recibidos por la aplicación */ WNDCLASSEX wincl; /* Estructura de datos para la clase de ventana */ /* Estructura de la ventana */ wincl.hinstance = hinstance; wincl.lpszclassname = "NOMBRE_CLASE"; wincl.lpfnwndproc = WindowProcedure; wincl.style = CS_DBLCLKS; wincl.cbsize = sizeof (WNDCLASSEX); /* Usar icono y puntero por defector */ wincl.hicon = LoadIcon (NULL, IDI_APPLICATION); wincl.hiconsm = LoadIcon (NULL, IDI_APPLICATION); wincl.hcursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszmenuname = "Menu"; /* Con menú Menu */ wincl.cbclsextra = 0; wincl.cbwndextra = 0; wincl.hbrbackground = (HBRUSH)COLOR_BACKGROUND; /* Registrar la clase de ventana, si falla, salir del programa */ if(!registerclassex(&wincl)) return 0; hwnd = CreateWindowEx( 0, "NOMBRE_CLASE", "Ventana 1", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, //LoadMenu(hInstance, "Menu"), /* Otra alternativa */ NULL, hinstance, NULL ); ShowWindow(hwnd, SW_SHOWDEFAULT);

187 } /* Bucle de mensajes */ while(true == GetMessage(&mensaje, 0, 0, 0)) { TranslateMessage(&mensaje); DispatchMessage(&mensaje); } return mensaje.wparam; /* Esta función es invocada por la función DispatchMessage() */ LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT mensaje, WPARAM wparam, LPARAM lparam) { switch (mensaje) /* manipulador del mensaje */ { case WM_COMMAND: switch(loword(wparam)) { case ABRIR: MessageBox(hwnd, "Se ha pulsado la opción Abrir.", "Mensaje de menú", MB_OK); break; case SALIR: MessageBox(hwnd, "Se ha pulsado la opción Salir.", "Mensaje de menú", MB_OK); PostQuitMessage(0); /* envía un mensaje WM_QUIT a la cola de mensajes */ break; } break; case WM_DESTROY: PostQuitMessage(0); /* envía un mensaje WM_QUIT a la cola de mensajes */ break; default: /* Mensajes que no se quieren manejar */ return DefWindowProc(hwnd, mensaje, wparam, lparam); } return 0; }

188 A continuación se muestra la salida por pantalla tras la ejecución del código mostrado así como el comportamiento de la aplicación al pulsar cada una de las dos opciones del menú. Al pulsar la opción Abrir del menú aparece el siguiente cuadro de mensaje: Y al pulsar la opción Salir aparece el siguiente cuadro de mensaje tras el cual se cerrará la aplicación:

189 3.2. Cuadros de diálogo. Los cuadros de diálogo son la forma de ventana más habitual de comunicación entre una aplicación gráfica y el usuario. Para facilitar la tarea del usuario a la hora de introducir datos existen varios tipos de controles, cada uno de ellos diseñado para un tipo específico de información. Los más comunes son los static, edit, button, listbox, scroll, combobox, group, checkbutton y radiobutton. Un cuadro de diálogo es una ventana normal aunque con algunas peculiaridades. También tiene su procedimiento de ventana (que recibirá el nombre de procedimiento de diálogo), pero puede devolver un valor a la ventana que lo invoque. La forma más sencilla y frecuente de implementar cuadros de diálogo es mediante ficheros de recursos (extensión *.rc). Al igual que en el apartado anterior, se explicará la creación de dicho fichero mediante un editor de texto ya que ayudará a entender el funcionamiento y la estructura del fichero antes de explicar su creación por medio del editor de recursos del compilador en el próximo capítulo. A continuación se muestra el código del fichero de recursos necesario para crear un menú con un ítem llamado Diálogo y un cuadro de diálogo con un texto ( Mensaje de prueba ) y un botón de Aceptar : #include <windows.h> #include "ids.h" Menu MENU BEGIN POPUP "&Menú" BEGIN MENUITEM "&Diálogo", DIALOGO END

190 END DialogoPrueba DIALOG 0, 0, 118, 48 STYLE DS_MODALFRAME WS_POPUP WS_VISIBLE WS_CAPTION CAPTION "Diálogo de prueba" FONT 8, "Helv" BEGIN CONTROL "Mensaje de prueba", TEXTO, "static", SS_LEFT WS_CHILD WS_VISIBLE, 8, 9, 84, 8 CONTROL "Aceptar", IDOK, "button", BS_PUSHBUTTON BS_CENTER WS_CHILD WS_VISIBLE WS_TABSTOP, 56, 26, 50, 14 END Se necesita incluir el fichero windows.h ya que en él se definen muchas constantes, como por ejemplo IDOK que es el identificador que se usa para el botón de Aceptar. También se necesita el fichero ids.h para definir los identificadores que se usarán en el programa, por ejemplo, el identificador de la opción del menú para abrir el diálogo. A continuación se muestra el fichero ids.h : #define TEXTO 1000 #define DIALOGO 1001 Lo primero que se definirá es un menú para poder comunicarle a la aplicación que se quiere abrir un cuadro de diálogo. A continuación está la definición del diálogo. La primera línea define un diálogo llamado DialogoPrueba mediante la palabra DIALOG, así como las coordenadas y dimensiones del diálogo. En cuanto a los estilos, las constantes para definir los estilos de ventana comienzan con WS_ mientras que los estilos de diálogos comienzan con

191 DS_. Los estilos que se han definido en el fichero de recursos mediante la palabra STYLE son los siguientes: o DS_MODALFRAME: indica que se creará un cuadro de diálogo con un marco de dialogbox modal que puede combinarse con una barra de título y un menú de sistema. o WS_POPUP: crea una ventana pop-up. o WS_VISIBLE: crea una ventana inicialmente visible. o WS_CAPTION: crea una ventana con una barra de título. La siguiente línea del fichero es la de CAPTION y en ella se especifica el texto que aparecerá en la barra de título del diálogo. La línea de FONT sirve para especificar el tamaño y el tipo de fuente de caracteres que usará el diálogo. Después se encuentra la zona de controles en la que se define un texto estático y un botón. Un control estático (static) sirve para mostrar textos o rectángulos, que se pueden usar para informar al usuario de algo, como etiquetas o simplemente como adorno. El control button sirve para que el usuario se comunique con el diálogo. A continuación se explica en detalle la definición del control button. CONTROL "Aceptar", IDOK, "button", BS_PUSHBUTTON BS_CENTER WS_CHILD WS_VISIBLE WS_TABSTOP, 56, 26, 50, 14 o CONTROL es una palabra clave que indica que se va a definir un control. o A continuación, en el parámetro text se introduce el texto que se mostrará en su interior. o id es el identificador del control. La aplicación recibirá este identificador junto con el mensaje WM_COMMAND cuando el usuario active el botón. La etiqueta IDOK está definida en el fichero windows.h

192 o class es la clase de control, en este caso button. Programación Orientada a Objetos o style es el estilo de control que se quiere. En este caso es una combinación de varios estilos de button y varios de ventana: o BS_PUSHBUTTON: crea un botón corriente que envía un mensaje WM_COMMAND a su ventana padre cuando el usuario selecciona el botón. o BS_CENTER: centra el texto horizontalmente en el área del botón. o WS_CHILD: crea el control como una ventana hija. o WS_VISIBLE: crea una ventana inicialmente visible. o WS_TABSTOP: define un control que puede recibir el foco del teclado cuando el usuario pulsa la tecla TAB. Presionando la tecla TAB, el usuario mueve el foco del teclado al siguiente control con el estilo WS_TABSTOP. o Coordenada x del control. o Coordenada y del control. o Width: anchura del control. o Height: altura del control Procedimiento de diálogo. Como ya se ha comentado anteriormente, un diálogo es básicamente una ventana, y al igual que ésta, necesita un procedimiento asociado que procese los mensajes que le sean enviados, en este caso, un procedimiento de diálogo. La sintaxis es la siguiente: BOOL CALLBACK DialogProc( HWND hwnddlg, // Manipulador del cuadro de diálogo UINT mensaje, // Mensaje WPARAM wparam, // Primer parámetro del mensaje LPARAM lparam ); // Segundo parámetro del mensaje o hwnddlg identifica el cuadro de diálogo y es el manipulador de la ventana a la que está destinado el mensaje

193 o mensaje es el código del mensaje. Programación Orientada a Objetos o wparam es el parámetro de tipo palabra asociado al mensaje. o lparam es el parámetro de tipo doble palabra asociado al mensaje. La diferencia fundamental con el procedimiento de ventana es el tipo de valor de retorno, que en el caso del procedimiento de diálogo es de tipo booleano. Excepto en la respuesta al mensaje WM_INITDIALOG, el procedimiento de diálogo debe devolver un valor no nulo si procesa el mensaje y cero si no lo hace. Cuando responde a un mensaje WM_INITDIALOG, el procedimiento de diálogo debe devolver cero si llama a la función SetFocus para poner el foco a uno de los controles del cuadro de diálogo. En otro caso debe devolver un valor distinto de cero, y el sistema pondrá el foco en el primer control del diálogo que pueda recibirlo. El prototipo del procedimiento de diálogo es el siguiente: BOOL CALLBACK DialogProc(HWND,UINT, WPARAM, LPARAM); A la hora de implementar el procedimiento de diálogo para el ejemplo explicado se debe analizar el diálogo creado. Éste sólo puede proporcionar un comando, así que sólo se deberá responder a un tipo de mensaje WM_COMMAND y al mensaje WM_INITDIALOG. Tal y como se ha comentado, el mensaje WM_INITDIALOG debe devolver un valor distinto de cero si no se llama a SetFocus, como es el caso. Este mensaje se usará para inicializar el diálogo antes de que sea visible para el usuario, siempre que haya algo que inicializar, claro

194 Cuando se procese el mensaje WM_COMMAND, que será siempre el que procede del único botón del diálogo, se cerrará el diálogo llamando a la función EndDialog y se devolverá un valor distinto de cero. En cualquier otro caso de devolverá el valor FALSE, ya que no se estará procesando el mensaje. El procedimiento de diálogo será el siguiente: BOOL CALLBACK DlgProc(HWND hdlg, UINT mensaje, WPARAM wparam, LPARAM lparam) { switch (mensaje) /* manipulador del mensaje */ { case WM_INITDIALOG: return TRUE; case WM_COMMAND: EndDialog(hDlg, FALSE); return TRUE; } return FALSE; } Una vez implementado el procedimiento de diálogo ya sólo falta crear el cuadro de diálogo. Para ello se usará un comando (opción) de menú, por lo que el diálogo se activará desde el procedimiento de ventana. El código necesario para crear el cuadro de diálogo en el procedimiento de ventana es el siguiente:

195 LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT mensaje, WPARAM wparam, LPARAM lparam) { static HINSTANCE hinstance; switch (mensaje) /* manipulador del mensaje */ { case WM_CREATE: hinstance = ((LPCREATESTRUCT)lParam)->hInstance; return 0; break; case WM_COMMAND: switch(loword(wparam)) { case DIALOGO: DialogBox(hInstance, "DialogoPrueba", hwnd, DlgProc); break; } break; case WM_DESTROY: PostQuitMessage(0); /* envía un mensaje WM_QUIT a la cola de mensajes */ break; default: /* Mensajes que no se quieren manejar */ return DefWindowProc(hwnd, mensaje, wparam, lparam); } return 0; } continuación. En este procedimiento hay una serie de novedades que se explicarán a En primer lugar, se ha declarado una variable estática hinstance para tener siempre disponible un manipulador de la instancia actual. Para inicializar este valor se hace uso del mensaje WM_CREATE, que se envía a una ventana cuando es creada, antes de que se visualice por primera vez. Se aprovecha el hecho de que el procedimiento de ventana sólo recibe una

196 vez este mensaje y de que lo hace antes de poder recibir ningún otro mensaje o comando. El mensaje WM_CREATE tiene como parámetro en lparam un puntero a una estructura CREATESTRUCT que contiene información sobre la ventana. Para el ejemplo sólo interesará el campo hinstance. Otra novedad es la llamada a la función DialogBox, que es la que crea el cuadro de diálogo. Esta función necesita varios parámetros: o Un manipulador a la instancia de la aplicación, que se ha obtenido al procesar el mensaje WM_CREATE. o Un identificador de recurso de diálogo. Este es el nombre que se utilizó para nombrar al diálogo (entre comillas) cuando se creó el recurso en el fichero de recursos. o Un manipulador a la ventana a la que pertenece el diálogo. o La dirección del procedimiento de ventana que hará el tratamiento del diálogo Paso de parámetros a un cuadro de diálogo. A la hora de crear un diálogo existe otra opción además de la ya citada función DialogBox que permite enviar un parámetro extra al procedimiento de diálogo. Esta función recibe el nombre de DialogBoxParam. El parámetro que se envía al procedimiento de ventana es enviado a través del parámetro lparam del procedimiento de diálogo, y puede contener un valor entero o, lo que es mucho más útil, un puntero. Esta función tiene los mismos parámetros que DialogBox, más uno añadido. Este quinto parámetro es el que se usa para recibir valores desde el procedimiento de diálogo

197 Por ejemplo, supóngase que se quiere saber cuántas veces se ha invocado un diálogo. Para ello se llevará la cuenta en el procedimiento de ventana, incrementando esa cuenta cada vez que se reciba un comando u opción del menú para mostrar el diálogo. Además, se pasará ese valor como parámetro lparam al procedimiento de diálogo. A continuación se muestra el procedimiento de ventana con los dos diálogos que se mostrarán en la aplicación: DIALOGO1 (el del apartado anterior) y DIALOGO2 (el que lleva la cuenta del número de veces que se ha invocado). LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT mensaje, WPARAM wparam, LPARAM lparam) { static HINSTANCE hinstance; static int veces; switch (mensaje) /* manipulador del mensaje */ { case WM_CREATE: hinstance = ((LPCREATESTRUCT)lParam)->hInstance; return 0; break; case WM_COMMAND: switch(loword(wparam)) { case DIALOGO1: DialogBox(hInstance, "DialogoPrueba", hwnd, DlgProc); break; case DIALOGO2: veces++; DialogBoxParam(hInstance, "DialogoPrueba", hwnd, DlgProc2, veces); break; } break; case WM_DESTROY: PostQuitMessage(0); break; default:

198 } } return 0; return DefWindowProc(hwnd, mensaje, wparam, lparam); El procedimiento de ventana mostrado tomará el valor de la variable veces y lo pasará como parámetro lparam al procedimiento de diálogo. Éste último será el encargado de crear el texto de un control estático mostrando su valor tal y como se muestra a continuación: BOOL CALLBACK DlgProc2(HWND hdlg, UINT mensaje, WPARAM wparam, LPARAM lparam) { char texto[25]; } switch (mensaje) /* manipulador del mensaje */ { case WM_INITDIALOG: sprintf(texto, "Veces invocado: %d", lparam); SetWindowText(GetDlgItem(hDlg, TEXTO), texto); return TRUE; case WM_COMMAND: EndDialog(hDlg, FALSE); return TRUE; } return FALSE; Para conseguir un texto estático a partir del parámetro lparam se ha usado la función estándar sprintf. Posteriormente se usa ese texto para modificar el control estático TEXTO. Por otra parte, la función SetWindowText se usa para cambiar el título de una ventana, pero en este caso sirve para cambiar el texto del control estático. El paso de parámetros a un cuadro de diálogo es de gran utilidad cuando éste se usa para pedir datos al usuario. De este modo se facilita en gran medida

199 el intercambio de datos entre la aplicación y los procedimientos de diálogo y se evita el uso de variables globales. Una vez mostrado el procedimiento de diálogo del cuadro de diálogo DIALOGO2 se da por terminada la explicación del ejemplo de aplicación de menú con cuadros de diálogo. En el siguiente apartado se muestra el código de todos los ficheros del ejemplo así como las salidas por pantalla

200 Ejemplo completo de cuadros de diálogo. Programación Orientada a Objetos En este apartado se muestra el contenido de los ficheros necesarios para desarrollar el ejemplo de cuadros de diálogo explicado anteriormente así como las salidas por pantalla de la aplicación final. Se mostrarán, pues, los ficheros ids.h, dialogo.rc y dialogo.c. Fichero de identificadores (fichero ids.h) #define TEXTO 1000 #define DIALOGO #define DIALOGO Fichero de recursos (fichero dialogo.rc) #include <windows.h> #include "ids.h" Menu MENU BEGIN POPUP "&Menú" BEGIN MENUITEM "&Diálogo", DIALOGO1 MENUITEM "&Con parámetro", DIALOGO2 END END DialogoPrueba DIALOG 0, 0, 118, 48 STYLE DS_MODALFRAME WS_POPUP WS_VISIBLE WS_CAPTION CAPTION "Diálogo de prueba" FONT 8, "Helv" BEGIN CONTROL "Mensaje de prueba", TEXTO, "static", SS_LEFT WS_CHILD WS_VISIBLE, 8, 9, 84, 8 CONTROL "Aceptar", IDOK, "button", BS_PUSHBUTTON BS_CENTER WS_CHILD WS_VISIBLE WS_TABSTOP, 56, 26, 50, 14 END

201 Programa Principal (fichero dialogo.c) #include <windows.h> #include "ids.h" /* Declaración del procedimiento de ventana */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DlgProc2(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdparam, int ncmdshow) { HWND hwnd; /* Manipulador de ventana */ MSG mensaje; /* Mensajes recibidos por la aplicación */ WNDCLASSEX wincl; /* Estructura de datos para la clase de ventana */ /* Estructura de la ventana */ wincl.hinstance = hinstance; wincl.lpszclassname = "NOMBRE_CLASE"; wincl.lpfnwndproc = WindowProcedure; wincl.style = CS_DBLCLKS; wincl.cbsize = sizeof(wndclassex); /* Usar icono y puntero por defector */ wincl.hicon = LoadIcon(NULL, IDI_APPLICATION); wincl.hiconsm = LoadIcon(NULL, IDI_APPLICATION); wincl.hcursor = LoadCursor(NULL, IDC_ARROW); wincl.lpszmenuname = "Menu"; wincl.cbclsextra = 0; wincl.cbwndextra = 0; wincl.hbrbackground = (HBRUSH)COLOR_BACKGROUND; /* Registrar la clase de ventana, si falla, salir del programa */ if(!registerclassex(&wincl)) return 0; hwnd = CreateWindowEx( 0, "NOMBRE_CLASE", "Ventana 1", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hinstance, NULL ); ShowWindow(hwnd, SW_SHOWDEFAULT); /* Bucle de mensajes */ while(true == GetMessage(&mensaje, NULL, 0, 0)) { TranslateMessage(&mensaje);

202 } DispatchMessage(&mensaje); } /* Salir con valor de retorno */ return mensaje.wparam; /* Esta función es invocada por la función DispatchMessage() */ LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT mensaje, WPARAM wparam, LPARAM lparam) { static HINSTANCE hinstance; static int veces; switch (mensaje) /* manipulador del mensaje */ { case WM_CREATE: hinstance = ((LPCREATESTRUCT)lParam)->hInstance; return 0; break; case WM_COMMAND: switch(loword(wparam)) { case DIALOGO1: DialogBox(hInstance, "DialogoPrueba", hwnd, DlgProc); break; case DIALOGO2: veces++; DialogBoxParam(hInstance, "DialogoPrueba", hwnd, DlgProc2, veces); break; } break; case WM_DESTROY: PostQuitMessage(0); /* envía el mensaje WM_QUIT a la cola de mensajes */ break; default: /* Mensajes que no se quieren manejar */ return DefWindowProc(hwnd, mensaje, wparam, lparam); } return 0; } BOOL CALLBACK DlgProc(HWND hdlg, UINT mensaje, WPARAM wparam, LPARAM lparam) { switch (mensaje) /* manipulador del mensaje */ { case WM_INITDIALOG: return TRUE; case WM_COMMAND: EndDialog(hDlg, FALSE); return TRUE; } return FALSE; }

203 BOOL CALLBACK DlgProc2(HWND hdlg, UINT mensaje, WPARAM wparam, LPARAM lparam) { char texto[25]; } switch (mensaje) /* manipulador del mensaje */ { case WM_INITDIALOG: sprintf(texto, "Veces invocado: %d", lparam); SetWindowText(GetDlgItem(hDlg, TEXTO), texto); return TRUE; case WM_COMMAND: EndDialog(hDlg, FALSE); return TRUE; } return FALSE; A continuación se muestra la salida por pantalla tras la ejecución del código mostrado así como el comportamiento de la aplicación al pulsar cada una de las dos opciones del menú

204 Al pulsar la opción Diálogo del menú aparece el siguiente cuadro de mensaje: Y al pulsar la opción Con parámetro aparece el siguiente cuadro de mensaje que muestra el número de veces que se ha invocado: Si se pulsa más veces mostrará el número total de veces que se ha pulsado:

205 Capítulo 4 Creación de recursos mediante el editor de recursos

206 CAPÍTULO 4. Creación de recursos mediante el editor de recursos. En el presente capítulo se explica la creación de ficheros de recursos (extensión *.rc) mediante el editor de recursos de MinGW Developer Estos ficheros permiten crear de forma rápida y fácil recursos que se emplean posteriormente en aplicaciones gráficas tal y como se vio en el capítulo anterior con los menús y los cuadros de diálogo. Es precisamente estos dos tipos de recursos en los que se centrará la explicación dado que sus correspondientes ficheros de recursos ya se mostraron en el capítulo anterior. A la hora de crear un fichero de recursos (por medio del editor de recursos del compilador) lo primero que se debe hacer es abrir el editor de recursos de MinGW Developer Para ello se pulsa la opción Resource Editor del menú Tools o bien se pulsan simultáneamente las teclas Ctrl y R. Una vez que se ha abierto el editor de recursos, lo primero que se debe hacer es crear un proyecto nuevo o, en su defecto, abrir un proyecto ya existente. Para ello se pulsan las opciones New Project o Open Project del menú File. Los iconos de la barra de herramientas asociados a estas dos opciones son y respectivamente. Una vez abierto o creado un proyecto se mostrará en la esquina superior derecha de la aplicación la carpeta del proyecto que contendrá los distintos recursos asociados al proyecto. Si el proyecto es nuevo, se mostrará una carpeta vacía con la palabra Untitled ( Sin título ) ya que el proyecto aún no tiene nombre. A continuación ya se pueden asociar al proyecto los recursos que se deseen. Para ello, en la opción Project del menú del editor se listan las opciones de recursos que se pueden asociar: desde un menú o un diálogo (opciones Add Menu y Add Dialog) hasta recursos más complejos como un acelerador (opción

207 Add Accelerator) o un cuadro de versión (opción Add Versioninfo). Los recursos en los que se centrará la explicación serán los menús y los cuadros de diálogo. A la hora de crear un menú se debe pulsar la citada opción Add Menu situada en la opción Project del editor. Una vez pulsada aparecerá un cuadro en el que se podrán especificar una serie de parámetros como el nombre del menú, el identificador del menú o el identificador de comienzo de los ítems. Además, en este mismo cuadro se deben añadir los ítems que se quieran asociar al menú. Para cada ítem se debe especificar su nombre (Name), el nombre con que aparecerá al ejecutar la aplicación (Caption), así como su identificador. Además, el cuadro muestra otras opciones como si se quiere que aparezca deshabilitado (Disabled), marcado (Checked), si es de tipo String, Bitmap, etc. A continuación se muestra la captura de pantalla del cuadro Menu Editor necesario para crear el menú del ejemplo de menús del capítulo

208 Una vez creado el menú y guardado el proyecto se creará un fichero de recursos con extensión *.rc con el siguiente contenido: #define Menu 1000 #define ABRIR 1000 #define SALIR 1001 Menu MENUEX BEGIN MENUITEM "Abrir",ABRIR MENUITEM "",SEPARATOR MENUITEM "Salir",SALIR END A partir de este fichero ya se pueden realizar las modificaciones necesarias para adaptarlo a las necesidades del usuario. La primera de estas modificaciones consistiría en cortar las primeras líneas del fichero correspondientes a sentencias include de identificadores de recursos y pegarlas en el fichero de identificadores ids.h. El identificador correspondiente al menú es opcional por lo que será eliminado. Una vez creado el fichero ids.h con los identificadores de los ítems del menú éste podrá ser añadido al fichero de recursos mediante el comando Include file del menú Project. Una vez pulsado, se mostrará un cuadro llamado Included Files donde aparecerán todos los archivos asociados al fichero de recursos. Para asociar un nuevo fichero se pulsa el botón Add y se selecciona la ubicación del fichero mediante el botón situado a la derecha del nuevo registro de la pestaña Filename. Una vez seleccionado el fichero el cuadro tendrá el siguiente aspecto:

209 Finalmente, se pulsa el botón OK y el fichero ids.h ya quedará asociado al proyecto. Este hecho se puede visualizar en la zona de recursos ya que aparecerá el icono Include file tal y como se muestra a continuación: Otra modificación que se debe hacer en el fichero de recursos generado es borrar las comillas de texto vacío asociadas al ítem SEPARATOR. Recuérdese que este ítem se emplea para separar los diferentes ítems pertenecientes a un menú. Por ello, en su declaración no se debe incluir Caption alguna si bien el editor de recursos le asigna por defecto una cadena vacía. Por último, si desea dotar al menú de comportamiento tipo pop-up se tendrá que especificar este hecho manualmente dado que no hay ninguna opción en el editor que permita especificar esta propiedad. Recuérdese que este comportamiento permite agrupar sobre una misma opción del menú varias subopciones. Una vez modificado el fichero para habilitar el comportamiento pop-up y ordenadas las sentencias del mismo tendrá el siguiente aspecto: #include "ids.h" Menu MENUEX BEGIN POPUP "&Menú" BEGIN MENUITEM "Abrir",ABRIR MENUITEM SEPARATOR MENUITEM "Salir",SALIR END END

210 Los únicos aspectos diferentes al fichero mostrado en el ejemplo de menús del apartado serían la palabra clave MENUEX (mismo comportamiento que MENU) y la ausencia del símbolo & en los caption de los ítems del menú. Este símbolo indica que la siguiente letra puede usarse para activar la opción del menú desde el teclado, usando la tecla [ALT] más la letra que sigue al símbolo &. Para indicar dicha situación, en pantalla se muestra esa letra subrayada, por ejemplo Abrir. Este símbolo puede ser incluido de forma manual a elección del usuario. Una vez finalizada la creación del fichero de recursos utilizado en el ejemplo del apartado se procede a explicar la creación del fichero empleado en el ejemplo de cuadros de diálogo del apartado El proceso de creación de la parte del fichero de recursos necesaria para crear el menú desde el que se invocarán los cuadros de diálogo es igual a la explicada anteriormente en este capítulo por lo que se obvia esta explicación. Una vez creada esta parte, el fichero de recursos tendrá el siguiente contenido: #include "ids.h" Menu MENUEX BEGIN POPUP "&Menú" BEGIN MENUITEM "&Diálogo", DIALOGO1 MENUITEM "&Con parámetro", DIALOGO2 END END A continuación se añade al proyecto un cuadro de diálogo. Para ello se pulsa la opción Add Dialog del menú Project. Una vez pulsada, aparecerá en la zona de edición del editor un cuadro de diálogo vacío con el título IDD_DLG asignado por defecto. En la parte derecha del editor aparecerá una lista de propiedades del cuadro de diálogo que se pueden modificar. En principio, el nombre del cuadro de diálogo (Name), el título (Caption) y el identificador (ID) serán los tres parámetros a modificar así como eliminar los botones de maximizar, minimizar y cerrar poniendo a False la propiedad SysMenu. Sin

211 embargo, se pueden modificar otros muchos como la fuente del título (Font), el estilo (xstyle) o la altura (Height). La forma de modificar estos parámetros es muy sencilla salvo en el caso del estilo. En este caso, cuando se sitúa el cursor sobre la opción xstyle y se pulsa aparece un botón de flecha desplegable en la parte derecha del cuadro de texto que contiene un número en hexadecimal. Si se pulsa esta flecha desplegable aparece un pequeño cuadro con una secuencia de números en binario tal y como se muestra a continuación: Cada dígito del número binario será un estilo diferente cuyo nombre se mostrará bajo los tres botones de flechas. Si se quiere activar el estilo seleccionado, se pulsa el botón hasta que el correspondiente dígito se encuentre a 1. Para avanzar por los dígitos se emplean las otras dos flechas de dirección. Una vez que los estilos deseados se encuentren a 1 y el resto a cero se pulsa el botón Close. Una vez que los parámetros del cuadro de diálogo se encuentren definidos ya se puede comenzar a añadir al cuadro los controles que se deseen. Los diferentes controles que se pueden añadir se muestran en la zona izquierda del editor de recursos por medio de iconos. En cualquier caso, si se sitúa el cursor sobre un icono aparece el nombre del control asociado por lo que la búsqueda de controles resulta fácil e intuitiva. Los controles que se añadirán al cuadro de diálogo serán: un texto estático (control static) por medio del icono y un botón (control button) por medio del icono. A la hora de añadir el control de tipo static se pulsa sobre el icono correspondiente y se dibuja sobre el cuadro de diálogo el tamaño del control en

212 la posición que se desea colocar. Una vez dibujado el control, aparecerá en el lado derecho de la pantalla una lista de parámetros similar a la que aparecía al añadir el cuadro de diálogo. Los parámetros que se deben modificar son el nombre del control (Name), el texto de la etiqueta (Caption) y el identificador del control (ID). Además, se pueden modificar otros parámetros como la fuente del texto (Font), la alineación del texto (Alignment), el borde del control (Border), la altura (Height) o la anchura (Width). Una vez añadido, el aspecto del cuadro de diálogo es el siguiente: Ahora se procede a añadir el otro control, el botón. Para ello se pulsa el icono correspondiente y se dibuja en el cuadro tal y como se hizo al añadir el control static. Una vez añadido, se deben modificar los parámetros de la lista para cambiar el nombre, el identificador y el texto a mostrar en el botón así como otros parámetros que desee el usuario. Recuérdese que el nombre del botón será IDOK, que es el identificador que se usa para el botón de Aceptar. Por ello, se necesita incluir el fichero windows.h en el que se define dicha constante. Una vez añadido el botón, el cuadro de diálogo tomará su aspecto final:

TEMA 2 WINDOWS XP Lección 4 BLOC DE NOTAS

TEMA 2 WINDOWS XP Lección 4 BLOC DE NOTAS TEMA 2 WINDOWS XP Lección 4 BLOC DE NOTAS 1) EL PEQUEÑO EDITOR El Bloc de notas de Windows XP es un básico editor de texto con el que podemos escribir anotaciones, de hasta 1024 caracteres por línea y

Más detalles

La pestaña Inicio contiene las operaciones más comunes sobre copiar, cortar y pegar, además de las operaciones de Fuente, Párrafo, Estilo y Edición.

La pestaña Inicio contiene las operaciones más comunes sobre copiar, cortar y pegar, además de las operaciones de Fuente, Párrafo, Estilo y Edición. Microsoft Word Microsoft Word es actualmente (2009) el procesador de textos líder en el mundo gracias a sus 500 millones de usuarios y sus 25 años de edad. Pero hoy en día, otras soluciones basadas en

Más detalles

1.- MENU DE CONTROL O MENU VENTANA: permite cerrar la ventana cambiarla de tamaño y pasar a otra ventana

1.- MENU DE CONTROL O MENU VENTANA: permite cerrar la ventana cambiarla de tamaño y pasar a otra ventana EXCEL PRÓLOGO Microsoft Excel es una hoja de cálculo de gran capacidad y fácil uso. Excel no solo es una hoja de calculo, sino también tiene capacidad para diseñar bases de datos (listas) de forma totalmente

Más detalles

GENERACIÓN DE TRANSFERENCIAS

GENERACIÓN DE TRANSFERENCIAS GENERACIÓN DE TRANSFERENCIAS 1 INFORMACIÓN BÁSICA La aplicación de generación de ficheros de transferencias permite generar fácilmente órdenes para que la Caja efectúe transferencias, creando una base

Más detalles

Práctica 3: Introducción a Word

Práctica 3: Introducción a Word Departament d Enginyeria i Ciència dels Computadors Práctica 3: Introducción a Word B12. Informática I. Curso 2001/2002 Profesores: Julio Pacheco Juanjo Murgui Raul Montoliu Mª Carmen Ortiz Octubre 2001

Más detalles

Tutorial. Configuración del entorno de programación Code::Blocks.

Tutorial. Configuración del entorno de programación Code::Blocks. Tutorial Configuración del entorno de programación Code::Blocks. Code::Blocks es un entorno de desarrollo multiplataforma para programación en C/C++. Se encuentra bajo una licencia GNU, lo cual lo hace

Más detalles

INDICE. 1. Introducción... 4. 2. El panel Entities view... 5. 3. El panel grafico... 6. 4. Barra de botones... 6. 4.1. Botones de Behavior...

INDICE. 1. Introducción... 4. 2. El panel Entities view... 5. 3. El panel grafico... 6. 4. Barra de botones... 6. 4.1. Botones de Behavior... MANUAL DE USUARIO INDICE 1. Introducción... 4 2. El panel Entities view... 5 3. El panel grafico... 6 4. Barra de botones... 6 4.1. Botones de Behavior... 7 4.2. Botones de In-agents... 8 4.3. Botones

Más detalles

2_trabajar con calc I

2_trabajar con calc I Al igual que en las Tablas vistas en el procesador de texto, la interseccción de una columna y una fila se denomina Celda. Dentro de una celda, podemos encontrar diferentes tipos de datos: textos, números,

Más detalles

Capítulo 9. Archivos de sintaxis

Capítulo 9. Archivos de sintaxis Capítulo 9 Archivos de sintaxis El SPSS permite generar y editar archivos de texto con sintaxis SPSS, es decir, archivos de texto con instrucciones de programación en un lenguaje propio del SPSS. Esta

Más detalles

GUIA COMPLEMENTARIA PARA EL USUARIO DE AUTOAUDIT. Versión N 02 Fecha: 2011-Febrero Apartado: Archivos Anexos ARCHIVOS ANEXOS

GUIA COMPLEMENTARIA PARA EL USUARIO DE AUTOAUDIT. Versión N 02 Fecha: 2011-Febrero Apartado: Archivos Anexos ARCHIVOS ANEXOS ARCHIVOS ANEXOS Son los documentos, hojas de cálculo o cualquier archivo que se anexa a las carpetas, subcarpetas, hallazgos u otros formularios de papeles de trabajo. Estos archivos constituyen la evidencia

Más detalles

1. El entorno de desarrollo Eclipse

1. El entorno de desarrollo Eclipse Índice 1. El entorno de desarrollo Eclipse 1 1.1. Qué es Eclipse?........................................................ 1 1.2. Trabajando con Eclipse....................................................

Más detalles

Uso de Visual C++ Pre-Practica No. 3

Uso de Visual C++ Pre-Practica No. 3 Pre-Practica No. 3 Uso de Visual C++ Microsoft Visual C++ 2010 es una versión de Visual Studio específica para el lenguaje de programación C++. Es un entorno de desarrollo muy completo y profesional. Por

Más detalles

Comentario sobre el entorno de desarrollo Microsoft Visual Studio 2005 Juan Manuel Lucas

Comentario sobre el entorno de desarrollo Microsoft Visual Studio 2005 Juan Manuel Lucas Comentario sobre el entorno de desarrollo Microsoft Visual Studio 2005 Juan Manuel Lucas Introducción El entorno de desarrollo Visual Studio 2005 o 2008 es una potente herramienta desarrollada por Microsoft

Más detalles

WINDOWS. Iniciando Windows. El mouse

WINDOWS. Iniciando Windows. El mouse Windows es un sistema operativo, cuyo nombre lo debe al principal elemento de trabajo, la ventana - en inglés window -. Este tiene características como: Multitarea: durante una sesión de trabajo, es posible

Más detalles

UF0513 Gestión auxiliar de archivo en soporte convencional o informático

UF0513 Gestión auxiliar de archivo en soporte convencional o informático UF0513 Gestión auxiliar de archivo en soporte convencional o informático Tema 1. Sistemas operativos habituales Tema 2. Archivo y clasificación de documentación administrativa Tema 3. Base de datos Tema

Más detalles

Sesión No. 4. Contextualización INFORMÁTICA 1. Nombre: Procesador de Texto

Sesión No. 4. Contextualización INFORMÁTICA 1. Nombre: Procesador de Texto INFORMÁTICA INFORMÁTICA 1 Sesión No. 4 Nombre: Procesador de Texto Contextualización La semana anterior revisamos los comandos que ofrece Word para el formato del texto, la configuración de la página,

Más detalles

10. El entorno de publicación web (Publiweb)

10. El entorno de publicación web (Publiweb) 10. El entorno de publicación web (Publiweb) 10.1. Introducción El entorno de publicación Web es una herramienta que permite la gestión de nuestras páginas Web de una forma visual. Algunos ejemplos de

Más detalles

Herramientas Visuales de Programación

Herramientas Visuales de Programación Pág. 1 07/04/2013 Para la compilación y ejecución del código que se realizará a lo largo de este curso vamos a utilizar el entorno de programación de la Herramienta Visual Studio 2010. El entorno de programación

Más detalles

GENERACIÓN DE ANTICIPOS DE CRÉDITO

GENERACIÓN DE ANTICIPOS DE CRÉDITO GENERACIÓN DE ANTICIPOS DE CRÉDITO 1 INFORMACIÓN BÁSICA La aplicación de generación de ficheros de anticipos de crédito permite generar fácilmente órdenes para que la Caja anticipe el cobro de créditos

Más detalles

UNIDAD I PROCESADOR DE TEXTOS

UNIDAD I PROCESADOR DE TEXTOS UNIDAD I PROCESADOR DE TEXTOS 1. Entorno de Microsoft Word 2007 Lic. Silvia Mireya Hernández Hermosillo 1.1 INTRODUCCIÓN 1.1.1 Generalidades de Microsoft Word 2007 Microsoft Word 2007 es un procesador

Más detalles

CREACIÓN DEL PRIMER PROYECTO EN mikrobasic PRO for AVR

CREACIÓN DEL PRIMER PROYECTO EN mikrobasic PRO for AVR CREACIÓN DEL PRIMER PROYECTO EN mikrobasic PRO for AVR 2 Proyecto mikrobasic PRO for AVR organiza aplicaciones en los proyectos que consisten en un solo fichero de proyecto (fichero con extensión.mbpav)

Más detalles

TEMA 1. MANEJO DE PROCESADOR DE TEXTOS: Microsoft WORD 2003

TEMA 1. MANEJO DE PROCESADOR DE TEXTOS: Microsoft WORD 2003 TEMA 1. MANEJO DE PROCESADOR DE TEXTOS: Microsoft WORD 2003 TEMA 1. MANEJO DE PROCESADOR DE TEXTOS: MICROSOFT WORD 2003...1 1. ESTILOS Y FORMATOS...1 1.1. Estilos...1 1.2. Niveles...2 1.3. Secciones...2

Más detalles

PROYECTOS, FORMULACIÓN Y CRITERIOS DE EVALUACIÓN

PROYECTOS, FORMULACIÓN Y CRITERIOS DE EVALUACIÓN PROYECTOS, FORMULACIÓN Y CRITERIOS DE EVALUACIÓN GESTIÓN DE PROYECTOS CON PLANNER AVC APOYO VIRTUAL PARA EL CONOCIMIENTO GESTIÓN DE PROYECTOS CON PLANNER Planner es una poderosa herramienta de software

Más detalles

Instructivo - Instalación y Uso de PDF Creator

Instructivo - Instalación y Uso de PDF Creator Versión : 1.00 Preparado por : Subdirección de Innovación Tecnológica Preparado para : Dirección de Informática Autor : Juan Moyano González Fecha creación : 05 de Febrero de 2008 Última modificación :

Más detalles

Ministerio de Educación. Base de datos en la Enseñanza. Open Office. Módulo 5: Report Builder

Ministerio de Educación. Base de datos en la Enseñanza. Open Office. Módulo 5: Report Builder Ministerio de Educación Base de datos en la Enseñanza. Open Office Módulo 5: Report Builder Instituto de Tecnologías Educativas 2011 Informes con Oracle Report Builder En su configuración original, OpenOffice

Más detalles

Race Manager by Master Timing Guía del usuario GUIA RACE MANAGER. Eventronic, SL

Race Manager by Master Timing Guía del usuario GUIA RACE MANAGER. Eventronic, SL GUIA RACE MANAGER Eventronic, SL DESCRIPCIÓN DEL PROGRAMA El Race Manager es un programa que se creó para facilitar el trabajo de la dirección de carrera de un evento durante y después de una carrera.

Más detalles

MANUAL DE AYUDA MÓDULOS 2011 MACOS

MANUAL DE AYUDA MÓDULOS 2011 MACOS MANUAL DE AYUDA MÓDULOS 2011 MACOS Agencia Tributaria Centro de Atención Telefónica Departamento de INFORMÁTICA TRIBUTARIA ÍNDICE MÓDULOS 2011 INTRODUCCIÓN...3 Requisitos previos. Máquina Virtual de Java...

Más detalles

Operación Microsoft Access 97

Operación Microsoft Access 97 Trabajar con Controles Características de los controles Un control es un objeto gráfico, como por ejemplo un cuadro de texto, un botón de comando o un rectángulo que se coloca en un formulario o informe

Más detalles

CAPÍTULO 4. EL EXPLORADOR DE WINDOWS XP

CAPÍTULO 4. EL EXPLORADOR DE WINDOWS XP CAPÍTULO 4. EL EXPLORADOR DE WINDOWS XP Características del Explorador de Windows El Explorador de Windows es una de las aplicaciones más importantes con las que cuenta Windows. Es una herramienta indispensable

Más detalles

Guía de Aprendizaje No. 1

Guía de Aprendizaje No. 1 MICROSOFT WORD Fundamentos básicos, ejecutar Word, su ventana y sus barras de herramientas Objetivos de la Guía de Aprendizaje No. 1 Obtener fundamentos básicos sobre Procesador de Texto Microsoft Word

Más detalles

Microsoft Access proporciona dos métodos para crear una Base de datos.

Microsoft Access proporciona dos métodos para crear una Base de datos. Operaciones básicas con Base de datos Crear una Base de datos Microsoft Access proporciona dos métodos para crear una Base de datos. Se puede crear una base de datos en blanco y agregarle más tarde las

Más detalles

POWER POINT. Iniciar PowerPoint

POWER POINT. Iniciar PowerPoint POWER POINT Power Point es la herramienta de Microsoft Office para crear presentaciones que permiten comunicar información e ideas de forma visual y atractiva. Iniciar PowerPoint Coloque el cursor y dé

Más detalles

Windows Journal en dos patadas

Windows Journal en dos patadas Windows Journal en dos patadas Con el Windows Journal se pueden hacer muchas cosas, pero aquí vamos a aprender unas pocas: Conocer la interfaz y las herramientas. Escribir a mano (y borrar) en una nota

Más detalles

Apuntes de ACCESS. Apuntes de Access. Campos de Búsqueda:

Apuntes de ACCESS. Apuntes de Access. Campos de Búsqueda: Apuntes de ACCESS Campos de Búsqueda: Los campos de búsqueda permiten seleccionar el valor de un campo de una lista desplegable en lugar de tener que escribirlos. El usuario sólo tiene que elegir un valor

Más detalles

Tutorial: Cómo realizar tu primer programa en C++ En el Sistema Operativo Windows

Tutorial: Cómo realizar tu primer programa en C++ En el Sistema Operativo Windows Tutorial: Cómo realizar tu primer programa en C++ En el Sistema Operativo Windows Lo primero que hay que tener en cuenta para poder hacer nuestro primer programa en C++ es que necesitamos ciertas herramientas

Más detalles

Creado dentro de la línea de sistemas operativos producida por Microsoft Corporation.

Creado dentro de la línea de sistemas operativos producida por Microsoft Corporation. WINDOWS Windows, Es un Sistema Operativo. Creado dentro de la línea de sistemas operativos producida por Microsoft Corporation. Dentro de los tipos de Software es un tipo de software de Sistemas. Windows

Más detalles

Operación de Microsoft Word

Operación de Microsoft Word Generalidades y conceptos Combinar correspondencia Word, a través de la herramienta combinar correspondencia, permite combinar un documento el que puede ser una carta con el texto que se pretende hacer

Más detalles

GESTIÓN DOCUMENTAL PARA EL SISTEMA DE CALIDAD

GESTIÓN DOCUMENTAL PARA EL SISTEMA DE CALIDAD GESTIÓN DOCUMENTAL PARA EL SISTEMA DE CALIDAD Manual de usuario 1 - ÍNDICE 1 - ÍNDICE... 2 2 - INTRODUCCIÓN... 3 3 - SELECCIÓN CARPETA TRABAJO... 4 3.1 CÓMO CAMBIAR DE EMPRESA O DE CARPETA DE TRABAJO?...

Más detalles

Mi primer proyecto en Dev-C++

Mi primer proyecto en Dev-C++ Mi primer proyecto en Dev-C++ Para realizar esta actividad deberás disponer de un ordenador en el que esté instalado el Dev-C++. Debes ir realizando cada uno de los pasos indicados, en el mismo orden en

Más detalles

Guardar y abrir documentos

Guardar y abrir documentos Contenido 1. Guardar como... 2 2. Abrir... 4 3. Recuperar archivos... 5 4. Unidades, Archivos y Carpetas... 5 5. Estructura de archivos... 6 6. Diferentes visiones de la lista de Abrir... 7 7. Cambiar

Más detalles

Carrera: Analista de Sistemas. Asignatura: Resolución de Problemas y Algoritmos - 2008-

Carrera: Analista de Sistemas. Asignatura: Resolución de Problemas y Algoritmos - 2008- Universidad Nacional de la Patagonia Austral Unidad Académica Río Gallegos INSTRUCTIVO PARA EL USO DEL ENTORNO DE DESARROLLO ECLIPSE - 2008- 1) Creación de espacio o carpeta de trabajo (workspace) Primero,

Más detalles

Presentaciones. Con el estudio de esta Unidad pretendemos alcanzar los siguientes objetivos:

Presentaciones. Con el estudio de esta Unidad pretendemos alcanzar los siguientes objetivos: UNIDAD 8 Presentaciones Reunión. (ITE. Banco de imágenes) as presentaciones son documentos formados por una sucesión de páginas, llamadas diapositivas, que transmiten información estructurada de manera

Más detalles

Imprimir códigos de barras

Imprimir códigos de barras Imprimir códigos de barras Al igual que en Abies 1, podemos definir el papel de etiquetas que vamos a utilizar. Se nos dan tres tipos de etiquetas ya creadas, que podemos modificar o eliminar, para lo

Más detalles

WINDOWS 2008 5: TERMINAL SERVER

WINDOWS 2008 5: TERMINAL SERVER WINDOWS 2008 5: TERMINAL SERVER 1.- INTRODUCCION: Terminal Server proporciona una interfaz de usuario gráfica de Windows a equipos remotos a través de conexiones en una red local o a través de Internet.

Más detalles

ESTÁNDAR DESEMPEÑO BÁSICO Recopila información, la organiza y la procesa de forma adecuada, utilizando herramientas tecnológicas.

ESTÁNDAR DESEMPEÑO BÁSICO Recopila información, la organiza y la procesa de forma adecuada, utilizando herramientas tecnológicas. ESTÁNDAR DESEMPEÑO BÁSICO Recopila información, la organiza y la procesa de forma adecuada, utilizando herramientas tecnológicas. Sala de sistemas, Video proyector, Guías RECURSOS ACTIVIDADES PEDAGÓGICAS

Más detalles

Intego NetUpdate X4 Manual del usuario

Intego NetUpdate X4 Manual del usuario Intego NetUpdate X4 Manual del usuario Manual del usuario de Intego NetUpdate X4 Página 1 Intego NetUpdate X4 para Macintosh 2005 Intego. Reservados todos los derechos. Intego Austin, Texas 78746 Este

Más detalles

Práctica 00: Compilador

Práctica 00: Compilador Práctica 00: Compilador El objetivo de esta práctica es aprender a utilizar el compilador y el entorno de desarrollo instalado en las aulas de la Escuela Técnica Superior de Ingeniería ICAI. 1. Compiladores

Más detalles

Soporte y mantenimiento de base de datos y aplicativos

Soporte y mantenimiento de base de datos y aplicativos Soporte y mantenimiento de base de datos y aplicativos Las bases de datos constituyen la fuente de información primaria a todos los servicios que el centro de información virtual ofrece a sus usuarios,

Más detalles

Manual de Gunaguaro Instalación y Uso

Manual de Gunaguaro Instalación y Uso Manual de Gunaguaro Instalación y Uso Indice Que es cunaguaro?... 3 Como instalar cunaguaro?... 4 Comenzar a utilizar cunaguaro... 5 Elementos para Navegar... 6 Pestañas de Navegación... 8 Uso de marcadores...

Más detalles

Fundamentos CAPÍTULO 1. Contenido

Fundamentos CAPÍTULO 1. Contenido CAPÍTULO 1 Fundamentos En este capítulo encontrará instrucciones rápidas y sencillas que le permitirán poner manos a la obra de inmediato. Aprenderá también a utilizar la ayuda en pantalla, que le será

Más detalles

Kepler 8.0 USO DEL ERP

Kepler 8.0 USO DEL ERP Kepler 8.0 USO DEL ERP CONTENIDO 1. Introducción... 3 2. Inicio del sistema... 3 3. Pantalla inicial... 4 4. Barra de menús... 5 a) Menú archivo... 5 b) Menú edición... 6 c) Menú Ver... 6 5. Ayuda... 8

Más detalles

PowerPoint 2010 Introducción a Microsoft Office PowerPoint 2010

PowerPoint 2010 Introducción a Microsoft Office PowerPoint 2010 PowerPoint 2010 Introducción a Microsoft Office PowerPoint 2010 Contenido CONTENIDO... 1 DESCRIPCIÓN DE LA VENTANA PRINCIPAL... 2 INTRODUCCIÓN A POWERPOINT WEB APP... 8 1 Descripción de la ventana principal

Más detalles

Vamos a ver las dos formas básicas de arrancar PowerPoint.

Vamos a ver las dos formas básicas de arrancar PowerPoint. Iniciar Powerpoint Vamos a ver las dos formas básicas de arrancar PowerPoint. 1) Desde el botón Inicio situado, normalmente, en la esquina inferior izquierda de la pantalla. Coloca el cursor y haz clic

Más detalles

A continuación se describen cuáles son los elementos principales de las tablas, cómo crear una y cómo modificarla.

A continuación se describen cuáles son los elementos principales de las tablas, cómo crear una y cómo modificarla. 4. TABLAS A continuación se describen cuáles son los elementos principales de las tablas, cómo crear una y cómo modificarla. 4.1. Principales Elementos Al momento de generar y diseñar una tabla es importante

Más detalles

Elementos de Microsoft Word

Elementos de Microsoft Word Contenido 1. Distintas formas de iniciar Word 2007... 2 2. Ayuda de Word... 2 3. Las barras de herramientas... 3 4. Funcionamiento de las pestañas. Cómo funcionan?... 4 5. Personalizar barra de acceso

Más detalles

ESCUELA SUPERIOR DE INFORMATICA Prácticas de Estadística UNA SESIÓN EN SPSS

ESCUELA SUPERIOR DE INFORMATICA Prácticas de Estadística UNA SESIÓN EN SPSS UNA SESIÓN EN SPSS INTRODUCCIÓN. SPSS (Statistical Product and Service Solutions) es un paquete estadístico orientado, en principio, al ámbito de aplicación de las Ciencias sociales, es uno de las herramientas

Más detalles

MANUAL DE LA APLICACIÓN DE ENVÍO DE SMS

MANUAL DE LA APLICACIÓN DE ENVÍO DE SMS MANUAL DE LA APLICACIÓN DE ENVÍO DE SMS SEGUIMIENTO DE VERSIONES Versión Novedades respecto a la versión anterior Fecha Versión 1.0 14/03/2011 Página 2 ÍNDICE ÍNDICE... 3 1. INTRODUCCIÓN... 4 2. MÓDULO

Más detalles

Portal Del Emisor MANUAL DEL USUARIO. Plataforma de Facturación Electrónica

Portal Del Emisor MANUAL DEL USUARIO. Plataforma de Facturación Electrónica Portal Del Emisor MANUAL DEL USUARIO Plataforma de Facturación Electrónica 1. Índice 1. Índice... 2 2. Descripción General... 3 2.1. Alcance... 3 2.2. Flujo de navegación... 4 2.3. Perfil del Usuario...

Más detalles

Internet Information Server

Internet Information Server Internet Information Server Internet Information Server (IIS) es el servidor de páginas web avanzado de la plataforma Windows. Se distribuye gratuitamente junto con las versiones de Windows basadas en

Más detalles

El Entorno Integrado de Desarrollo Dev-C++ (Ayuda básica para las primeras sesiones de prácticas)

El Entorno Integrado de Desarrollo Dev-C++ (Ayuda básica para las primeras sesiones de prácticas) El Entorno Integrado de Desarrollo Dev-C++ (Ayuda básica para las primeras sesiones de prácticas) Sobre Dev-C++ Dev-C++ es un Entorno Integrado de Desarrollo para el lenguaje de programación C/C++ que

Más detalles

Guía N 1: Fundamentos básicos(i)

Guía N 1: Fundamentos básicos(i) 1 Guía N 1: Fundamentos básicos(i) Objetivos Generales: Ver una breve descripción de las capacidades más comunes de Excel Objetivos específicos: Descripción de los elementos de un libro: Hojas, iconos,

Más detalles

ELABORACIÓN DE TABLEROS DINÁMICOS DE COMUNICACIÓN CON EL PROGRAMA EDITOR TICO

ELABORACIÓN DE TABLEROS DINÁMICOS DE COMUNICACIÓN CON EL PROGRAMA EDITOR TICO ELABORACIÓN DE TABLEROS DINÁMICOS DE COMUNICACIÓN CON EL PROGRAMA (Tico 2.0) EDITOR TICO La idea principal que motivo este proyecto fue trasladar la definición tradicional de tablero de comunicación en

Más detalles

Conociendo el ambiente de programación de Java. M. en C. Erika Vilches

Conociendo el ambiente de programación de Java. M. en C. Erika Vilches Conociendo el ambiente de programación de Java M. en C. Erika Vilches La variable PATH Una vez que se ha aceptado la licencia del JDK y que se ha instalado satisfactoriamente y antes de poder utilizarlo,

Más detalles

MUNIA Manual de usuario

MUNIA Manual de usuario MUNIA Manual de usuario by Daisoft www.daisoft.it 2 La tabla de contenido I II 2.1 2.2 2.3 2.4 2.5 2.6 III 3.1 3.2 3.3 IV 4.1 4.2 V 5.1 5.2 5.3 Introducción... 3 Vencimientos... 6 Tipos... de vencimientos

Más detalles

ORGANIZAR LA INFORMACIÓN: EL EXPLORADOR DE WINDOWS

ORGANIZAR LA INFORMACIÓN: EL EXPLORADOR DE WINDOWS ORGANIZAR LA INFORMACIÓN: EL EXPLORADOR DE WINDOWS Organizar la información: El explorador de Windows... 1 Introducción... 1 Explorador de Windows... 2 Ejercicio práctico del explorador de Windows... 5

Más detalles

Guía de instalación de la carpeta Datos de IslaWin

Guía de instalación de la carpeta Datos de IslaWin Guía de instalación de la carpeta Datos de IslaWin Para IslaWin Gestión CS, Classic o Pyme a partir de la revisión 7.00 (Revisión: 10/11/2011) Contenido Introducción... 3 Acerca de este documento... 3

Más detalles

Inicio con Microsoft Access 2007

Inicio con Microsoft Access 2007 Inicio con Microsoft Access 2007 Como paquete integrador de herramientas de productividad, Office 2007 Professional, además de contar con el Procesador de textos, el administrador de Libros de Cálculo,

Más detalles

vbnmqwertyuiopasdfghjklzxcvbnmrty uiopasdfghjklzxcvbnmqwertyuiopasdf ghjklzxcvbnmqwertyuiopasdfghjklzxc

vbnmqwertyuiopasdfghjklzxcvbnmrty uiopasdfghjklzxcvbnmqwertyuiopasdf ghjklzxcvbnmqwertyuiopasdfghjklzxc vbnmqwertyuiopasdfghjklzxcvbnmrty uiopasdfghjklzxcvbnmqwertyuiopasdf ghjklzxcvbnmqwertyuiopasdfghjklzxc COMBINACIÓN DE CARTAS Y CORRSPONDENCIA vbnmqwertyuiopasdfghjklzxcvbnmqw ertyuiopasdfghjklzxcvbnmqwertyuiop

Más detalles

Guía rápida de CX-Programmer

Guía rápida de CX-Programmer Guía rápida de CX-Programmer Esta guía pretende dar al lector los conocimientos más básicos para la programación de un controlador lógico secuencia en el autómata CQM1 de Omron, usando el software CX-Programmer

Más detalles

AGREGAR COMPONENTES ADICIONALES DE WINDOWS

AGREGAR COMPONENTES ADICIONALES DE WINDOWS INSTALACIÓN DE IIS EN WINDOWS XP El sistema está desarrollado para ejecutarse bajo la plataforma IIS de Windows XP. Por esta razón, incluimos la instalación de IIS (Servidor de Web) para la correcta ejecución

Más detalles

Conocer la interfaz de Office 2010

Conocer la interfaz de Office 2010 Conocer la interfaz de Office 00 Como novedad de la suite de Microsoft Office 00 encontramos la posibilidad de cancelar el proceso de apertura de las aplicaciones. Al iniciar cualquiera de los programas

Más detalles

APUNTES DE WINDOWS. Windows y sus Elementos INSTITUTO DE CAPACITACIÓN PROFESIONAL. Elementos de Windows

APUNTES DE WINDOWS. Windows y sus Elementos INSTITUTO DE CAPACITACIÓN PROFESIONAL. Elementos de Windows 1 APUNTES DE WINDOWS Unidad 1: Windows y sus Elementos Elementos de Windows Escritorio: Es la pantalla que aparece cuando se inicia una sesión con Windows, desde aquí es de donde se administra el computador.

Más detalles

9233506 Edición 1 ES. Nokia y Nokia Connecting People son marcas comerciales registradas de Nokia Corporation

9233506 Edición 1 ES. Nokia y Nokia Connecting People son marcas comerciales registradas de Nokia Corporation 9233506 Edición 1 ES Nokia y Nokia Connecting People son marcas comerciales registradas de Nokia Corporation Guía del usuario de Zip Manager Guía del usuario de Zip Manager Vaya a Zip Manager Pro. Nota:

Más detalles

Trabajar con diapositivas

Trabajar con diapositivas Trabajar con diapositivas INFORMÁTICA 4º ESO POWERPOINT Una vez creada una presentación podemos modificarla insertando, eliminando, copiando diapositivas, Insertar una nueva diapositiva.- Para insertar

Más detalles

Integración de Toolchain PTXdist sobre IDE gráfico basado en Eclipse

Integración de Toolchain PTXdist sobre IDE gráfico basado en Eclipse Integración de Toolchain PTXdist sobre IDE gráfico basado en Eclipse Objetivos Integrar un toolchain basado en PTXdist sobre un IDE gráfico basado en Eclipse. Creación y compilación de un pequeño proyecto.

Más detalles

Introducción a Mozilla Navegador

Introducción a Mozilla Navegador 20021125 Universidad de Navarra Introducción a Mozilla Navegador Versión 1.1. cti Centro de Tecnología Informática Tabla de contenidos 1. Mozilla Navegador...3 1.1.Establecer las preferencias de Navigator...4

Más detalles

LabelLogic GUÍA DE USUARIO. Contenidos. www.planglow.com info@planglow.com. Label Choices. Data Library. Print Centre.

LabelLogic GUÍA DE USUARIO. Contenidos. www.planglow.com info@planglow.com. Label Choices. Data Library. Print Centre. www.planglow.com info@planglow.com Contenidos Label Choices Data Library Cómo añadir la etiqueta Cómo añadir los datos del sándwich Print Centre Design Centre Cómo imprimir las etiquetas Cómo modificar

Más detalles

El programa Minitab: breve introducción a su funcionamiento. Para mostrar la facilidad con la que se pueden realizar los gráficos y cálculos

El programa Minitab: breve introducción a su funcionamiento. Para mostrar la facilidad con la que se pueden realizar los gráficos y cálculos El programa Minitab: breve introducción a su funcionamiento Para mostrar la facilidad con la que se pueden realizar los gráficos y cálculos estadísticos en la actualidad, el libro se acompaña, en todo

Más detalles

MANUAL DE USUARIO FACTURACIÓN ELECTRÓNICA

MANUAL DE USUARIO FACTURACIÓN ELECTRÓNICA MANUAL DE USUARIO FACTURACIÓN ELECTRÓNICA Proveedores PLATAFORMA FACTURACIÓN ELECTRÓNICA PARA PROVEEDORES DE LA JUNTA DE COMUNIDADES DE CASTILLA LA MANCHA. Índice 1. INTRODUCCIÓN... 3 2. ACCESO A LA PLATAFORMA

Más detalles

Operación de Microsoft Excel

Operación de Microsoft Excel Representación gráfica de datos Generalidades Excel puede crear gráficos a partir de datos previamente seleccionados en una hoja de cálculo. El usuario puede incrustar un gráfico en una hoja de cálculo,

Más detalles

PLANTILLAS EN MICROSOFT WORD

PLANTILLAS EN MICROSOFT WORD PLANTILLAS EN MICROSOFT WORD Una plantilla es un modelo o patrón para crear nuevos documentos. En una plantilla se guarda internamente el formato utilizado, es decir, el estilo de la fuente, el tamaño,

Más detalles

Guí a Ra pida Dropbox.

Guí a Ra pida Dropbox. Guí a Ra pida Dropbox. Software desarrollado para alojar y compartir archivos vía WEB. Ing. Verónica Lisset Nieto Quintanilla vlnietoq@gmail.com http://www.veronicalnieto.blogspot.com/ www.vlnieto.wikispaces.com

Más detalles

Ministerio de Educación. Diseño de Presentaciones en la Enseñanza. Módulo 9: Imprimir

Ministerio de Educación. Diseño de Presentaciones en la Enseñanza. Módulo 9: Imprimir Ministerio de Educación Diseño de Presentaciones en la Enseñanza Módulo 9: Imprimir Instituto de Tecnologías Educativas 2011 Diseño de Presentaciones en la Enseñanza (OpenOffice) Imprimir Imprimir una

Más detalles

Para ingresar a la aplicación Microsoft PowerPoint 97, los pasos que se deben seguir pueden ser los siguientes:

Para ingresar a la aplicación Microsoft PowerPoint 97, los pasos que se deben seguir pueden ser los siguientes: Descripción del ambiente de trabajo Entrar y salir de la aplicación Para ingresar a la aplicación Microsoft PowerPoint 97, los pasos que se deben seguir pueden ser los siguientes: A través del botón :

Más detalles

Operación Microsoft PowerPoint 97

Operación Microsoft PowerPoint 97 Ejecución y control de una presentación Formas de ejecutar una presentación En función de las necesidades, una presentación con diapositivas puede ejecutarse de tres formas diferentes. A través de la opción

Más detalles

Accede a su DISCO Virtual del mismo modo como lo Hace a su disco duro, a través de:

Accede a su DISCO Virtual del mismo modo como lo Hace a su disco duro, a través de: Gemelo Backup Online DESKTOP Manual DISCO VIRTUAL Es un Disco que se encuentra en su PC junto a las unidades de discos locales. La información aquí existente es la misma que usted ha respaldado con su

Más detalles

Manual de ayuda. Índice: 1. Definición.. Pág. 2 2. Conceptos básicos... Pág. 3 3. Navegación.. Pág. 5 4. Operativa más habitual.. Pág.

Manual de ayuda. Índice: 1. Definición.. Pág. 2 2. Conceptos básicos... Pág. 3 3. Navegación.. Pág. 5 4. Operativa más habitual.. Pág. Manual de ayuda Índice: 1. Definición.. Pág. 2 2. Conceptos básicos... Pág. 3 3. Navegación.. Pág. 5 4. Operativa más habitual.. Pág. 14 Página 1 de 19 1. DEFINICIÓN El Broker Bankinter (BrokerBK) es una

Más detalles

Creación un instalador con Visual Studio.NET. Irene Sobrón. Ingeniero de Telecomunicaciones por la Escuela Técnica Superior de Bilbao

Creación un instalador con Visual Studio.NET. Irene Sobrón. Ingeniero de Telecomunicaciones por la Escuela Técnica Superior de Bilbao Creación un instalador con Visual Studio.NET Irene Sobrón Ingeniero de Telecomunicaciones por la Escuela Técnica Superior de Bilbao Diferencia entre Debug y Release Existen dos configuraciones para realizar

Más detalles

Manual de NetBeans y XAMPP

Manual de NetBeans y XAMPP Three Headed Monkey Manual de NetBeans y XAMPP Versión 1.0 Guillermo Montoro Delgado Raúl Nadal Burgos Juan María Ruiz Tinas Lunes, 22 de marzo de 2010 Contenido NetBeans... 2 Qué es NetBeans?... 2 Instalación

Más detalles

TEMA 20 EXP. WINDOWS PROC. DE TEXTOS (1ª PARTE)

TEMA 20 EXP. WINDOWS PROC. DE TEXTOS (1ª PARTE) 1. Introducción. TEMA 20 EXP. WINDOWS PROC. DE TEXTOS (1ª PARTE) El Explorador es una herramienta indispensable en un Sistema Operativo ya que con ella se puede organizar y controlar los contenidos (archivos

Más detalles

Acronis License Server. Guía del usuario

Acronis License Server. Guía del usuario Acronis License Server Guía del usuario TABLA DE CONTENIDO 1. INTRODUCCIÓN... 3 1.1 Generalidades... 3 1.2 Política de licencias... 3 2. SISTEMAS OPERATIVOS COMPATIBLES... 4 3. INSTALACIÓN DE ACRONIS LICENSE

Más detalles

UNIDESYS UNIVERSAL BUSINESS SYSTEMS INSTALACIÓN NUEVO PUESTO DE TRABAJO

UNIDESYS UNIVERSAL BUSINESS SYSTEMS INSTALACIÓN NUEVO PUESTO DE TRABAJO www.ubs-systems.com Teléfono: 91 3681185 UNIDESYS UNIVERSAL BUSINESS SYSTEMS INSTALACIÓN NUEVO PUESTO DE TRABAJO Unidesys Versión 2011 1 CONTENIDO 1 INTRODUCCIÓN 3 2 FUENTES DE DATOS 4 3 INSTALACIÓN DEL

Más detalles

Mando a distancia. Manual en español. Última actualización: 01.10.04

Mando a distancia. Manual en español. Última actualización: 01.10.04 Mando a distancia Manual en español Última actualización: 01.10.04 Contenido El editor del control remoto... 3 Instalación... 3 El menú... 4 Los conjuntos de órdenes... 5 1. Seleccionar una aplicación...

Más detalles

Sistema de Gestión Portuaria Sistema de Gestión Portuaria Uso General del Sistema

Sistema de Gestión Portuaria Sistema de Gestión Portuaria Uso General del Sistema Sistema de Gestión Portuaria Uso General del Sistema Uso General del Sistema Página 1 de 21 Contenido Contenido... 2 1.Ingreso al Sistema... 3 2.Uso del Menú... 6 3.Visualizar Novedades del Sistema...

Más detalles

TUTORIAL ACADÉMICO. Programación II- Taller de Programación I Fa.CENA. UNNE

TUTORIAL ACADÉMICO. Programación II- Taller de Programación I Fa.CENA. UNNE TUTORIAL ACADÉMICO Programación II- Taller de Programación I Fa.CENA. UNNE Eclipse, es un Entorno de Desarrollo Profesional y Gratuito, que puede ser utilizado para varios lenguajes Java, C, C++, PHP,

Más detalles

Cómo creo las bandejas del Registro de Entrada /Salida y de Gestión de Expedientes?

Cómo creo las bandejas del Registro de Entrada /Salida y de Gestión de Expedientes? Preguntas frecuentes Cómo creo las bandejas del Registro de Entrada /Salida y de Gestión de Expedientes? Atención! Esta opción es de configuración y solamente la prodrá realizar el administrador de la

Más detalles

Prácticas de programación en C con MinGW Developer Studio

Prácticas de programación en C con MinGW Developer Studio Prácticas de programación en C con MinGW Developer Studio MinGW Developer Studio es un entorno de desarrollo integrado (IDE) para la programación en lenguaje C gratuito y cómodo de usar. Se ejecuta en

Más detalles

COMBINAR CORRESPONDENCIA EN MICROSOFT WORD

COMBINAR CORRESPONDENCIA EN MICROSOFT WORD COMBINAR CORRESPONDENCIA EN MICROSOFT WORD Combinar documentos consiste en unir dos documentos diferentes sin que se modifiquen los datos que aparecen en ellos. Esta operación es muy útil y muy frecuente

Más detalles

Introducción a Google Calendar Breve guía sobre algunas de sus funcionalidades destacables.

Introducción a Google Calendar Breve guía sobre algunas de sus funcionalidades destacables. Introducción a Google Calendar Breve guía sobre algunas de sus funcionalidades destacables. 28/03/2011 Centro de Servicios de Informática y Redes de Comunicaciones Nodo Cartuja Contenido 1. Introducción...

Más detalles