desarrollo de aplicaciones windows. aspectos avanzados (ejemplo)

Upload: andycesar

Post on 17-Jul-2015

97 views

Category:

Documents


3 download

TRANSCRIPT

Desarrollo de aplicaciones Windows. Aspectos avanzados

Luis Miguel Blanco

SipnosisTexto dirigido a aquellas personas que quieran iniciarse en la creacin de aplicaciones para entorno Windows, empleando Visual Studio 2005. Como lenguajes de programacin se utilizan Visual Basic y C#. Se trata de una obra organizada alrededor de tres bloques principales de contenidos. El primer bloque abarca los captulos versados en la creacin de proyectos sencillos, utilizando Visual Studio 2005 como herramienta de desarrollo. El segundo bloque se adentra en los dos lenguajes de programacin, explicando aquellas caractersticas ms importantes de cada uno. Finalmente, el tercer bloque se encuentra enfocado en el diseo e implementacin de aplicaciones Windows, haciendo uso del conjunto de tipos ofrecidos por la plataforma .NET Framework al programador, as como del numeroso grupo de diseadores y asistentes del entorno de desarrollo. A lo largo de todo el texto, el lector encontrar un gran nmero de ejemplos prcticos que le permitirn aplicar de forma inmediata todos aquellos conceptos aprendidos en los diferentes captulos de que se compone esta obra.

Luis Miguel Blanco trabaja como Arquitecto de Software en Alhambra Eidos, siendo uno de los titulados MCSD de reconocido prestigio entre el colectivo de desarrolladores .NET en Espaa y Latinoamerica. Desde su posicin en la compaa ha partipado en numerosos proyectos de desarrollo de software, tanto para la administracin pblica como para la empresa privada. En lneas generales, sus reas de especializacin abarcan Visual Basic .NET, ASP.NET y SQL Server en sus aspectos relacionados con los servicios OLAP y Reporting Services. Mantiene un blog relacionado con diversos aspectos del desarrollo en la plataforma .NET, tales como ASP.NET, AJAX, Silverlight, etc., en la direccin: http://geeks.ms/blogs/lmblanco/.

Luarna

Desarrollo de Aplicaciones Windows. Aspectos Avanzados Luis Miguel Blanco Alhambra Eidos De esta edicin: 2009, Luarna Ediciones, S.L. www.luarna.com

Madrid, septiembre de 2009 ISBN: 978-84-92684-52-6 Versin 1.0 (27-09-2009)

Cualquier forma de reproduccin, distribucin, comunicacin pblica o transformacin de esta obra solo puede ser realizada con la autorizacin de sus titulares, salvo excepcin prevista por la ley. Dirjase a CEDRO (Centro Espaol de Derechos Reprogrficos, www.cedro.org) si necesita fotocopiar, escanear o hacer copias digitales de algn fragmento de esta obra.

A mi hijo David, un muchacho valiente a pesar de su juventud, cuya contagiosa alegra llena de felicidad mis das. A mi esposa Olga, la mejor compaera que nadie podra desear para recorrer el viaje de la vida. Su compaa hace que el camino sea ms liviano y alegre. A mi madre Antonia, por todos los nimos que me ha dado siempre que me he embarcado en la dura, pero gratificante labor de escribir un libro. A mi hermano Carlos, por su admirable espritu libre e indmito. A mi hermano Roberto, del que espero cumpla su sueo de viajar al pas del sol naciente. Ha trabajado para ello como pocos, y se lo merece ms que muchos. A mi padre Isaas, por transmitirme la aficin al sptimo arte.

DESARROLLO DE APLICACIONES WINDOWS. ASPECTOS AVANZADOSLuis Miguel Blanco

IndiceIntroduccin .................................................................................................................................... 12 Caractersticas avanzadas, pero en gran medida necesarias ............................................................ 12 GDI+ y construccin de controles personalizados .......................................................................... 12 ADO.NET y el enlace de datos a controles .................................................................................... 12 Creacin de informes .................................................................................................................... 13 Flujos de datos y manipulacin de archivos ................................................................................... 13 Utilizacin del Portapapeles y de las operaciones de Arrastrar y soltar .......................................13 Programacin de procesos asncronos y multihebra ....................................................................... 13 Instalacin de aplicaciones ............................................................................................................ 13 GDI+. Manipulacin de grficos en .NET Framework .................................................................14 System.Drawing............................................................................................................................ 15 La clase Graphics .......................................................................................................................... 15 Especificando coordenadas. La clase Point .................................................................................... 15 Definiendo tamaos. La clase Size ................................................................................................ 16 Combinando coordenadas y tamaos. La clase Rectangle .............................................................. 16 La clase Pen. Componiendo todo para dibujar ............................................................................... 17 La estructura Color ....................................................................................................................... 18 Repintado de reas invalidadas ......................................................................................................18 Dibujo de figuras varias con la clase Pen ....................................................................................... 19 La clase Brush .............................................................................................................................. 23 Creacin de figuras complejas con la clase GraphicsPath .............................................................. 25 Aplicacin de efectos avanzados con la clase Brush ...................................................................... 27 Objetos grficos con caractersticas del sistema ............................................................................. 29 Dibujo de texto en el formulario .................................................................................................... 30 Personalizacin de la imagen de fondo del formulario ................................................................... 31 Manipulacin de los eventos de pintado en la clase form ........................................................... 31 El control picturebox ................................................................................................................. 32 Manipulando el grado de opacidad del formulario ......................................................................... 33 Creacin de formularios con formas irregulares ............................................................................. 37 Usando la clase region............................................................................................................... 37 Usando una imagen para definir la superficie del formulario ...................................................... 40 Dibujo manual de elementos de un control .................................................................................... 44 La clase ToolStripRenderer.Aplicando GDI+ en la presentacin de la barra de herramientas ......... 49 Caso prctico. Creacin y aplicacin de un degradado de colores .................................................. 55 Creacin de controles de usuario....................................................................................................56 Crear una clase derivada de un control concreto ............................................................................ 56 Provocar por cdigo un evento del control ................................................................................. 59 Creacin de controles de usuario. Heredando de UserControl ........................................................ 61 Diseo visual ............................................................................................................................ 62 Probando el control en el formulario.......................................................................................... 63 Agregando propiedades al control ............................................................................................. 65 Codificacin de los mtodos ...................................................................................................... 67 Redimensionamiento de los controles constituyentes ................................................................. 68 Proporcionar informacin adicional al control mediante atributos .............................................. 70 Asignacin de una imagen para el cuadro de herramientas ......................................................... 73 Caso prctico. Desarrollo y utilizacin de un control de usuario .................................................... 75

Pgina |6

Creacin de controles personalizados ............................................................................................ 77 Heredando de la clase Control ....................................................................................................... 77 El control a crear ........................................................................................................................... 77 Creacin del proyecto ................................................................................................................... 78 La clase del control personalizado y la clase Control, muchos aspectos en comn.......................... 79 El rombo para la casilla de marcado ..............................................................................................80 Dibujando el resto de elementos de la casilla ................................................................................. 82 Visualizando el literal del ttulo ..................................................................................................... 84 Organizando las operaciones de dibujo en el cdigo de la clase ..................................................... 86 Controlando por cdigo el marcado de la casilla ............................................................................ 89 Refinando el marcado inicial de la casilla ...................................................................................... 91 Marcando la casilla con el ratn ....................................................................................................92 La barra espaciadora tambin cambia el estado de la casilla ...........................................................95 Detectando el estado desde el cdigo cliente ................................................................................. 95 Indicacin visual de la captura del foco ......................................................................................... 96 Cambiando la alineacin de la casilla ............................................................................................ 99 Coloreando el rombo ................................................................................................................... 107 Creacin de formularios derivados .............................................................................................. 110 El selector de herencia de VS 2005 ............................................................................................. 110 Desarrollo del formulario base .................................................................................................... 110 Creacin del formulario derivado mediante el selector de herencia .............................................. 112 Tratamiento de errores ................................................................................................................. 116 Errores, ese mal comn ............................................................................................................... 116 Errores de escritura ................................................................................................................. 116 Errores de ejecucin ................................................................................................................ 117 Errores lgicos ........................................................................................................................ 118 Errores y excepciones ................................................................................................................. 118 Manipuladores de excepciones .................................................................................................... 118 Manipulacin estructurada de errores .......................................................................................... 118 La estructura try...end try / try {} ......................................................................................... 118 La clase exception ................................................................................................................... 122 Captura de excepciones de diferente tipo en el mismo controlador de errores ........................... 123 Establecer en vb una condicin para un manipulador de excepciones ....................................... 125 La influencia del orden de los manipuladores de excepciones .................................................. 127 Forzar la salida de un controlador de errores en vb mediante exit try........................................ 129 Manipulacin no estructurada de errores en VB........................................................................... 132 El objeto err ............................................................................................................................ 133 On error .................................................................................................................................. 133 On error goto etiqueta ............................................................................................................. 133 On error resume next ............................................................................................................... 134 Creacin de errores con el objeto err........................................................................................ 134 On error goto 0 ........................................................................................................................ 135 Manipulacin de datos con ADO.NET ......................................................................................... 136 Aplicaciones de gestin de datos ................................................................................................. 136 El acceso a datos desde ADO.NET.............................................................................................. 136 Trabajo con datos en modo conectado ......................................................................................... 138 Crear una copia de la base de datos ............................................................................................. 138 Conexin con un origen de datos. La clase Connection................................................................ 142 Ejecutando sentencias. La clase Command .................................................................................. 144 Recorriendo conjuntos de resultados. La clase DataReader .......................................................... 149 Trabajo con datos en modo desconectado .................................................................................... 153 Estructuras de datos en memoria. La clase DataSet y sus complementarias .................................. 154

Pgina |7

Adaptadores de datos. La clase DataAdapter ............................................................................... 157 Creacin de mantenimientos de datos .......................................................................................... 162 Mantenimiento de datos en modo desconectado .......................................................................... 162 Creacin de un mantenimiento manual ........................................................................................ 163 Agregar seleccin de valores desde tablas catlogo...................................................................... 172 Mantenimiento con enlace automtico de controles a datos. Data Binding ................................... 179 Controlar errores de edicin mediante un componente ErrorProvider ........................................... 185 Creacin manual del enlace entre controles y datos ..................................................................... 188 Enlazar controles con campos de valores especiales .................................................................... 191 Bsquedas y vistas de datos .......................................................................................................... 194 Proporcionar capacidades de bsqueda, filtro y ordenacin de registros ....................................... 194 Crear un sistema de bsqueda mediante el componente TableAdapter ......................................... 194 Invocar la consulta por cdigo ................................................................................................. 196 Obtener varios registros de la consulta..................................................................................... 197 Restaurar el conjunto de registros inicial ................................................................................. 197 Vistas de datos. La clase DataView ............................................................................................. 198 Vista bsica y predeterminada ................................................................................................. 199 Creacin de un filtro mediante una vista .................................................................................. 200 Vistas simultneas de la misma tabla ....................................................................................... 202 Ordenacin de registros ........................................................................................................... 203 Caso prctico. Realizacin de un mantenimiento de datos con Data Binding automtico .............. 205 El control DataGridView. Diseo visual ...................................................................................... 206 Creacin y diseo visual ............................................................................................................. 206 Agregar y eliminar columnas ...................................................................................................... 207 Configuracin de slo consulta.................................................................................................... 209 Cambiar las posiciones originales de las columnas ...................................................................... 210 Establecer columnas fijas ............................................................................................................ 210 Ordenar columnas ....................................................................................................................... 211 Estilo de cabeceras de columna ................................................................................................... 211 Estilo y propiedades de celdas ..................................................................................................... 212 Estilo de cabeceras de fila ........................................................................................................... 214 Estilo de seleccin de columna .................................................................................................... 214 Visualizacin de filas con colores alternos................................................................................... 215 Visualizacin de campos de tipo imagen ..................................................................................... 216 El control DataGridView. Manipulacin por cdigo .................................................................. 218 Creacin y manipulacin por cdigo ........................................................................................... 218 Manejo bsico de columnas y ordenacin .................................................................................... 218 Creacin de estilos y aplicacin de formatos ............................................................................... 221 Pintado manual de celdas. El evento CellPainting, la clase DataGridViewCellPaintingEventArgs y la clase TextRenderer .................................................... 224 Dividiendo el texto de la celda en varias lneas ........................................................................ 228 Edicin de datos .......................................................................................................................... 231 Obtener informacin relativa a la fila y columna actual. El evento cellenter ............................. 233 Borrando filas. El evento userdeletingrow ............................................................................... 234 Manejo de errores de edicin. El evento dataerror.................................................................... 235 Validacin de celdas. Los eventos cellvalidating y rowvalidating ............................................ 236 Tipos de columna del control DataGridView ............................................................................... 238 DataGridViewCheckBoxColumn ............................................................................................ 239 DataGridViewButtonColumn .................................................................................................. 240 DataGridViewComboBoxColumn ........................................................................................... 244 DataGridViewImageColumn ................................................................................................... 248 DataGridViewLinkColumn ..................................................................................................... 251

Pgina |8

Construccin de un formulario de consulta maestro/detalle utilizando controles DataGridView ... 254 Caso prctico. Visualizacin de datos mediante el control DataGridView .................................... 258 Impresin y generacin de informes ............................................................................................ 260 El proceso de impresin en la plataforma .NET Framework ........................................................ 260 La clase PrintDocument .............................................................................................................. 260 El mecanismo de impresin......................................................................................................... 261 Impresin de una lnea de texto ................................................................................................... 261 Visualizacin previa de la impresin ........................................................................................... 263 Previsualizando mediante PrintPreviewDialog......................................................................... 263 Previsualizar manualmente con el control PrintPreviewControl ............................................... 264 Impresin de varias lneas de texto .............................................................................................. 266 Configuracin del trabajo de impresin ....................................................................................... 270 Configuracin de la pgina a imprimir ........................................................................................ 272 Impresin de grficos .................................................................................................................. 274 Impresin de grficos a color................................................................................................... 276 El control ReportViewer ............................................................................................................. 278 Imprimir con Crystal Reports para Visual Studio .NET ............................................................... 280 Espacios de nombres de Crystal Reports para Visual Studio 2005 ............................................... 281 Creacin de un informe con el asistente de Crystal Reports ......................................................... 281 El diseador de informes ............................................................................................................. 286 El control CrystalReportViewer .................................................................................................. 288 Establecer por cdigo la informacin de conexin al origen de datos ........................................... 291 Caso prctico. Impresin de un archivo de texto .......................................................................... 292 Flujos de datos .............................................................................................................................. 294 El espacio de nombres System.IO ............................................................................................... 294 Objetos Stream ........................................................................................................................... 294 Las clases TextReader y TextWriter ............................................................................................ 295 La clase StreamWriter ................................................................................................................. 295 La clase StreamReader ................................................................................................................ 297 Las clases StringWriter y StringReader ....................................................................................... 300 La clase Stream........................................................................................................................... 300 La clase FileStream ..................................................................................................................... 301 Grabacin y recuperacin de documentos en una base de datos................................................ 303 Manejo de datos binarios ............................................................................................................. 306 Caso prctico. Lectura y escritura de archivos mediante flujos de datos ....................................... 307 Manipulacin del sistema de archivos .......................................................................................... 308 Manipulacin de archivos mediante File y FileInfo ..................................................................... 308 Manipulacin de directorios mediante Directory y DirectoryInfo ................................................. 311 La clase Path ............................................................................................................................... 315 El control SplitContainer ............................................................................................................. 315 El componente ImageList ............................................................................................................ 316 El control TreeView .................................................................................................................... 317 Creacin y diseo .................................................................................................................... 318 Manipulacin por cdigo ......................................................................................................... 321 Creacin a partir de un origen de datos XML........................................................................... 328 El control ListView ..................................................................................................................... 331 Creacin y diseo .................................................................................................................... 332 Manipulacin por cdigo ......................................................................................................... 337 Cuadros de dilogo para la gestin del sistema de archivos .......................................................... 343 OpenFileDialog ....................................................................................................................... 344 FolderBrowserDialog .............................................................................................................. 346 SaveFileDialog........................................................................................................................ 347 El componente FileSystemWatcher. Monitorizacin del sistema de archivos ............................... 349

Pgina |9

Deteccin con espera, de eventos producidos sobre archivos ................................................... 352 Manipulacin de archivos mediante funciones de VB .................................................................. 353 Caso prctico. Creacin de un formulario de navegacin por tipo de archivo ............................... 354 Manejo del Portapapeles y procesos de Arrastrar y soltar ...................................................... 355 El Portapapeles del sistema. Un medio efectivo para intercambiar informacin ........................... 355 Situar informacin en el Portapapeles .......................................................................................... 355 Obtener contenidos del Portapapeles ........................................................................................... 356 Manipulando un objeto propio en el Portapapeles ........................................................................ 357 Desplazamiento de informacin mediante Arrastrar y soltar ..................................................... 359 Creacin de una operacin de arrastrar y soltar sencilla ........................................................... 360 Comienzo de la operacin. Arrastrar un valor ...................................................................... 360 Fin de la operacin. Soltar el valor ....................................................................................... 361 Copiar y mover datos al arrastrar y soltar................................................................................. 362 Copiar archivos mediante un formulario explorador propio...................................................... 366 Caso prctico. Desarrollo de un proceso de arrastrar y soltar........................................................ 369 Programacin de procesos asncronos. Manipulacin de hebras de ejecucin ........................... 370 El problema en la ejecucin de tareas simultneas ....................................................................... 370 BackgroundWorker ..................................................................................................................... 371 Controlando el progreso de la ejecucin en segundo plano....................................................... 376 Cancelando la ejecucin de la tarea en segundo plano.............................................................. 379 Manejo de controles con soporte de funcionamiento asncrono .................................................... 381 Hebras de ejecucin .................................................................................................................... 383 La clase Thread ........................................................................................................................... 383 Ejecucin de procesos en hebras.................................................................................................. 384 La clase manipuladora de hebras ............................................................................................. 384 Comunicacin entre hebras y formulario ................................................................................. 390 Creacin y ejecucin de hebras desde el propio formulario .......................................................... 395 Control de procesos indefinidos .................................................................................................. 397 Ejecucin multihebra .................................................................................................................. 400 Ejecucin multihebra de mltiples procesos ................................................................................ 402 Creando un proceso de monitorizacin ........................................................................................ 412 Inicios de aplicacin con dos formularios empleando hebras ....................................................... 415 Caso prctico. Ejecucin de una tarea en segundo plano .............................................................. 417 Configuracin de programas mediante ajustes de aplicacin ..................................................... 418 Configurando la aplicacin desde el exterior ............................................................................... 418 Creacin de ajustes de aplicacin ................................................................................................ 419 Creacin de un ajuste de aplicacin desde la ventana de propiedades del formulario ................ 419 Creacin de un ajuste de aplicacin desde la ventana de propiedades del proyecto ................... 421 El contenido del archivo de configuracin ................................................................................... 422 Modificacin de ajustes de aplicacin ......................................................................................... 423 Manteniendo los cambios realizados a los ajustes ........................................................................ 424 Restaurando los valores originales de los ajustes ......................................................................... 424 Enlace entre ajustes de aplicacin y propiedades de objetos ......................................................... 425 Caso prctico. Creacin de ajustes de aplicacin ......................................................................... 427 El control PropertyGrid ............................................................................................................... 428 Edicin visual de propiedades con PropertyGrid.......................................................................... 428 Cambiando la presentacin del control PropertyGrid ............................................................... 436 Caso prctico. Configuracin de las propiedades de un objeto mediante el control PropertyGrid .. 438 Resolucin Casos prcticos ........................................................................................................... 439 Captulo 2 ................................................................................................................................... 439 Captulo 3 ................................................................................................................................... 442

P g i n a | 10

Captulo 9 ................................................................................................................................... 450 Captulo 11 ................................................................................................................................. 456 Captulo 12 ................................................................................................................................. 460 Captulo 13 ................................................................................................................................. 464 Captulo 14 ................................................................................................................................. 466 Captulo 15 ................................................................................................................................. 470 Captulo 16 ................................................................................................................................. 472 Captulo 17 ................................................................................................................................. 477 Captulo 18 ................................................................................................................................. 480

P g i n a | 11

IntroduccinCaractersticas avanzadas, pero en gran medida necesariasEn el presente texto realizaremos un recorrido por aquellos aspectos avanzados de la programacin con formularios Windows, lo cual no significa que algunos de ellos no se encuentren entre las caractersticas que debemos implementar en la mayora de las aplicaciones que habitualmente desarrollamos. A grandes rasgos, los siguientes apartados describen las reas del desarrollo que abordaremos en la actual obra.

GDI+ y construccin de controles personalizadosGDI+ representa la API de programacin grfica de la plataforma .NET, mediante la cual podremos dotar a nuestras aplicaciones de notables efectos visuales. Tambin nos permitir aplicar su potencial en la creacin de controles de usuario derivados de los ya existentes, o bien en el desarrollo de nuevos controles creados a partir de cero, sin olvidar la herencia visual de formularios, un aspecto del desarrollo que facilita la creacin visual de formularios derivados.

ADO.NET y el enlace de datos a controlesEn el apartado de los mantenimientos de datos con ADO.NET, el enlace entre orgenes de datos y controles Data Binding- incorpora nuevas clases y componentes, destinados a facilitar la labor del

P g i n a | 12

programador en el tratamiento de la informacin. El nuevo control DataGridView, sucesor de DataGrid, ofrece un elevado nmero de caractersticas que le confieren una potencia en la presentacin y edicin de datos muy superior a su antecesor.

Creacin de informesLa gestin de los procesos de impresin y generacin de informes tambin es abordada en esta obra, donde se tratan tanto las tcnicas para la impresin manual de documentos mediante los tipos disponibles en .NET Framework-, como a travs del control ReportViewer, que permite el diseo de informes para SQL Server Reporting Services, y el tambin generador de informes Crystal Reports.

Flujos de datos y manipulacin de archivosMediante el conjunto de clases de tipo Stream, manejaremos flujos de datos que nos permitirn la lectura y escritura de informacin en el sistema de archivos de la mquina, pudiendo desarrollar procesos de monitorizacin en dicho sistema, que nos permitan rastrear los cambios a nivel de archivos y directorios que se produzcan.

Utilizacin del Portapapeles y de las operaciones de Arrastrar y soltarLa plataforma .NET ofrece soporte para implementar en nuestras aplicaciones dos de las caractersticas de mayor uso entre los usuarios de sistemas Windows, como son el Portapapeles y Arrastrar y soltar, que nos permiten realizar intercambio de informacin entre diferentes aplicaciones. Con ello, nuestros desarrollos ganarn en productividad y facilidad de manejo.

Programacin de procesos asncronos y multihebraCon el fin de poder ejecutar ms de una tarea simultneamente, disponemos de un conjunto de clases y componentes, que nos permitirn implementar en un proyecto capacidades de ejecucin asncrona, de manera que podemos lanzar la ejecucin de un proceso en una hebra aparte, impidiendo que los controles del formulario de trabajo queden bloqueados debido a tareas intensivas que realicen un gran consumo de recursos del sistema.

Instalacin de aplicacionesGracias a la tecnologa ClickOnce, el despliegue e instalacin de una aplicacin se simplifica enormemente. Podemos configurar un proyecto de instalacin desde variados orgenes: ruta de archivo tradicional, sitio Web, servidor FTP, etc., lo cual facilita y flexibiliza las posibilidades de distribucin del programa. Tambin es posible configurar el despliegue de una aplicacin para que su ejecucin se realice desde un servidor centralizado, o sea descargada en las mquinas cliente del usuario, as como efectuar actualizaciones peridicas de dicha aplicacin.

P g i n a | 13

GDI+. Manipulacin de grficos en .NET FrameworkGDI+ (Graphics Device Interface) representa aquella parte en la arquitectura de la plataforma .NET encargada de la comunicacin con el motor grfico del sistema operativo. Se trata de una interfaz de programacin independiente del dispositivo fsico sobre el que se van a generar los grficos; con ello, el programador gana en flexibilidad, ya que no debe preocuparse de si el grfico generado se va a mostrar por el monitor, impresora, etc., siendo esta una labor resuelta por GDI+, que asla el programa del hardware a manejar. Se trata de un subsistema grfico que ha evolucionado del antiguo GDI, perteneciente a versiones anteriores de Windows, por lo que incluye una gran cantidad de mejoras y potencia en el tratamiento de imgenes, texto, etc., con respecto a su predecesor. GDI+ divide su campo de trabajo en tres reas principales. Generacin de grficos vectoriales 2D Manipulacin de imgenes en los formatos grficos ms habituales. Visualizacin de texto en un amplio abanico de tipos de letra.

Si somos programadores de VB, recordaremos que en las versiones de este lenguaje anteriores a .NET, el objeto Form dispona de una serie de mtodos y controles para el dibujo sobre la superficie del formulario. La mayor parte de esos elementos han desaparecido en la versin de VB para .NET, integrndose todas las operaciones de dibujo en los diversos tipos de la plataforma .NET Framework relacionados con el apartado grfico; gracias a esta caracterstica, lo que aprendamos trabajando con grficos en un lenguaje orientado a .NET utilizando GDI+, nos servir igualmente si en un futuro

P g i n a | 14

debemos abordar un proyecto en otro lenguaje de la plataforma, ya que las clases pertenecen a .NET Framework y no a un lenguaje en particular. Otro problema con el que nos enfrentbamos anteriormente era el hecho de que al necesitar alguna manipulacin grfica especial, tenamos que recurrir al acceso directo a la API de Windows, con las complejidades que ello comportaba. A partir de ahora esto no ser necesario, ya que como hemos comentado, es el propio entorno de ejecucin de .NET el que nos proporciona dicho acceso, por lo que no ser necesario acudir a la API del sistema operativo.

System.DrawingSe trata del espacio de nombres contenedor de los tipos principales para el trabajo con grficos en NET, por lo que deberemos declararlo al comienzo de nuestros archivos de cdigo, o especificarlo al acceder a cualquiera de sus clases, estructuras, etc. System.Drawing contiene el conjunto de tipos principales, aunque no es el nico espacio de nombres de GDI+. Para tareas de mayor especializacin con grficos deberemos recurrir a otros espacios de nombres que tambin estn dentro de System.Drawing: Drawing2D (generacin de grficos complejos), Imaging (tratamiento de archivos de imagen), Text (manipulacin de texto), Printing (impresin de grficos), etc.

La clase GraphicsLa clase Graphics representa el denominado Contexto de dispositivo grfico (Graphics device context), o elemento (objeto) sobre el que se va a realizar una operacin de dibujo, por ejemplo, el formulario. Debido a la arquitectura del sistema grfico, no es posible tomar un objeto Form y realizar una operacin directa de dibujo sobre el mismo, sino que precisamos en primer lugar, obtener una referencia hacia el rea de dibujo de dicho formulario, o contexto grfico, y una vez obtenida esa referencia, efectuar el dibujo. Esta rea la vamos a obtener mediante el mtodo CreateGraphics() de la clase Form, que devuelve un objeto Graphics con la informacin del contexto de dispositivo grfico del formulario. Ver el Cdigo fuente 1.Dim oGraphics As Graphics oGraphics = Me.CreateGraphics() Graphics oGraphics; oGraphics=this.CreateGraphics(); Cdigo fuente 1

Obtenido el contexto grfico sobre el que vamos a dibujar, ya podemos generar grficos en el formulario utilizando alguno de los mtodos de esta clase, como veremos posteriormente.

Especificando coordenadas. La clase PointEsta clase nos permite especificar puntos o coordenadas en las que se dibujarn los grficos. Se trata de una clase auxiliar, que deberemos utilizar con diversos objetos de dibujo para indicar dnde dibujaremos un objeto grfico.

P g i n a | 15

Point trabaja con valores enteros, pero si necesitamos ser ms precisos al indicar las coordenadas de dibujo, disponemos tambin de la clase PointF, que nos permite establecer coordenadas con precisin decimal. Ver el Cdigo fuente 2.Dim oPuntoUno As New Point(10, 150) Dim oPuntoDos As PointF oPuntoDos = New PointF(45.6, 88.2) Point oPuntoUno = new Point(10, 150); PointF oPuntoDos; oPuntoDos = new PointF(45.6, 88.2); Cdigo fuente 2

Definiendo tamaos. La clase SizeAl igual que la clase anterior, Size es una clase auxiliar, que nos permite definir tamaos y que utilizaremos en diversas situaciones durante nuestro trabajo manipulando grficos. Podemos crear objetos Size con tamaos basados en valores enteros, o bien usar la clase SizeF para definir tamaos con valores de precisin decimal. Ver el Cdigo fuente 3.Dim oSize As New Size(50, 100) Dim oSizeF As SizeF oSizeF = New SizeF(58.4, 125.6) Size oSize = new Size(50,100); SizeF oSizeF; oSizeF = new SizeF(58.4, 125.6); Cdigo fuente 3

Combinando coordenadas y tamaos. La clase RectanglePara dibujar un objeto grfico debemos especificar un rea rectangular, dentro de la cual ser dibujado el grfico. Esto lo conseguiremos mediante la clase Rectangle o RectangleF, a cuyos constructores pasaremos valores numricos (enteros o decimales), o bien sendos objetos Point y Size. Ver el Cdigo fuente 4.Dim oRect As Rectangle oRect = New Rectangle(New Point(10, 40), New Size(100, 120)) Dim oRectF As New RectangleF(10.5, 40.8, 100.6, 120.9) Rectangle oRect; oRect = new Rectangle(new Point(10,40), new Size(100,120)); RectangleF oRectF = new RectangleF(10.5, 40.8, 100.6, 120.9); Cdigo fuente 4

P g i n a | 16

La clase Pen. Componiendo todo para dibujarLa clase Pen representa un objeto de tipo lapicero, que con un determinado color y grosor, utilizar los mtodos DrawTipoObjeto() de un objeto Graphics para dibujar lneas y formas sobre un contexto de dispositivo, es decir, el formulario. El Cdigo fuente 5 muestra un ejemplo de dibujo de un crculo sobre el formulario utilizando el mtodo DrawEllipse() de la clase Graphics. Este mtodo recibe como parmetro un objeto Pen con un color y grosor determinados, y un objeto Rectangle con las coordenadas y medidas necesarias para dibujar el crculo. Finalizado el dibujo, y ya que las operaciones grficas consumen gran cantidad de recursos, es recomendable llamar al mtodo Dispose() de la clase Graphics, para poder liberar correctamente los recursos que est utilizando.' crear objeto Pen Dim oPen As New Pen(Color.DeepPink, 10) ' obtener el contexto de dispositivo ' grfico del formulario Dim oGraphics As Graphics = Me.CreateGraphics() ' dibujar en el formulario oGraphics.DrawEllipse(oPen, New Rectangle(150, 20, 100, 100)) oGraphics.Dispose() // crear objeto Pen Pen oPen = new Pen(Color.DeepPink,10); // obtener el contexto de dispositivo // grfico del formulario Graphics oGraphics = this.CreateGraphics(); // dibujar en el formulario oGraphics.DrawEllipse(oPen, new Rectangle(150, 20, 100, 100)); oGraphics.Dispose(); Cdigo fuente 5

Asociando este cdigo a la pulsacin de un botn en el formulario, el resultado ser el dibujo del crculo mostrado en la Figura 1.

Figura 1. Dibujar un crculo con un objeto Pen.

P g i n a | 17

La estructura ColorEsta estructura nos permite seleccionar los colores existentes y definir colores personalizados. Su uso ms simple consiste en escribir su nombre seguido del operador punto y el nombre del color a utilizar, tal y como acabamos de comprobar en el ejemplo previo. Tambin posible la creacin de un color mediante su mtodo FromArgb(), en el que definimos un color mediante un conjunto de valores numricos que permiten especificar el grado de transparencia (Alpha) y los colores bsicos rojo, verde y azul. El parmetro Alpha es opcional, no siendo necesario su uso si no necesitamos usar el grado de transparencia. Otros mtodos disponibles para la creacin de un color son FromName(), que recibe una cadena con el nombre del color a crear, y FromKnownColor(), al que pasamos un valor de la enumeracin KnownColor, que contiene un conjunto de colores predefinidos. Veamos unos ejemplos en el Cdigo fuente 6.Dim oColor As Color oColor = Color.FromArgb(140, 200, 30, 60) oColor = Color.FromName("Yellow") oColor = Color.FromKnownColor(KnownColor.Firebrick) Color oColor; oColor = Color.FromArgb(140, 200, 30, 60); oColor = Color.FromName("Yellow"); oColor = Color.FromKnownColor(KnownColor.Firebrick); Cdigo fuente 6

Repintado de reas invalidadasEl dibujo de figuras en la forma que acabamos de describir tiene un inconveniente: si la figura que hemos dibujado queda oculta parcial o totalmente por otro formulario o elemento de la interfaz de usuario, dicha zona ocultada ser borrada. Al rea de un formulario que queda oculta de esta manera se le denomina zona invalidada, requiriendo ser repintada para poder recuperar su aspecto original. Esta es una labor que actualmente no realizamos en el cdigo del formulario. Para mantener las figuras dibujadas en todo momento en el formulario, debemos recurrir al evento Paint() de la clase Form. Dicho evento se produce cada vez que el formulario necesita repintarse, debido a que parte o la totalidad de su superficie ha quedado invalidada Vamos por lo tanto a solucionar este problema, escribiendo un mtodo manipulador para el mencionado evento Paint(), en el que dibujaremos un rectngulo mediante el mtodo Graphics.DrawRectangle(). Como puede observar el lector, este evento recibe un parmetro de tipo PaintEventArgs, que utilizaremos para obtener el objeto Graphics con el que realizar el dibujo de la figura. Ver el Cdigo fuente 7.Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint ' crear objeto Pen Dim oPen As New Pen(Color.MediumVioletRed, 6) ' ' ' ' ' obtener el contexto de dispositivo grfico del formulario; en este caso usaremos el objeto que contiene los argumentos de evento para obtener dicho contexto de dispositivo

P g i n a | 18

Dim oGraph As Graphics = e.Graphics ' dibujar en el formulario oGraph.DrawRectangle(oPen, New Rectangle(40, 80, 70, 70)) oGraph.Dispose() End Sub private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { // crear objeto Pen Pen oPen = new Pen(Color.MediumVioletRed, 6); // obtener el contexto de dispositivo // grfico del formulario; // en este caso usaremos el objeto que contiene // los argumentos de evento para obtener dicho // contexto de dispositivo Graphics oGraph = e.Graphics; // dibujar en el formulario oGraph.DrawRectangle(oPen, new Rectangle(40, 80, 70, 70)); Cdigo fuente 7

}

Al ejecutar el programa, el rectngulo ser mostrado en todo momento, aunque minimicemos el formulario, lo ocultemos parcial o totalmente, etc., ya que este evento se ejecuta automticamente cada vez que el formulario detecta que su superficie ha quedado invalidada y necesita repintarse. Ver la Figura 2.

Figura 2. Figura persistente en la superficie del formulario gracias al evento Paint.

Dibujo de figuras varias con la clase PenEn este apartado veremos diversos mtodos que tambin ofrece la clase Pen para el dibujo de otros tipos de figuras. Para organizar el cdigo, aadiremos un men al formulario, creando una opcin de men por cada operacin de dibujo. En primer lugar volveremos a utilizar el mtodo DrawEllipse() para dibujar una figura de este tipo con forma alargada. Ver el Cdigo fuente 8.Private Sub mnuElipse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuElipse.Click ' crear objeto Pen Dim oPen As New Pen(Color.DarkTurquoise, 2)

P g i n a | 19

' obtener el contexto de dispositivo ' grfico del formulario Dim oGraphics As Graphics = Me.CreateGraphics() ' dibujar en el formulario oGraphics.DrawEllipse(oPen, New Rectangle(250, 150, 65, 120)) oGraphics.Dispose() End Sub private void mnuElipse_Click(object sender, EventArgs e) { // crear objeto Pen Pen oPen = new Pen(Color.DarkTurquoise, 2); // obtener el contexto de dispositivo // grfico del formulario Graphics oGraphics = this.CreateGraphics(); // dibujar en el formulario oGraphics.DrawEllipse(oPen, new Rectangle(250, 150, 65, 120)); oGraphics.Dispose(); Cdigo fuente 8

}

Al dibujar un rectngulo vamos a modificar el estilo de lnea mediante la propiedad DashStyle. Esta propiedad contiene una enumeracin con la que podemos hacer que la lnea se muestre como guiones, guiones y puntos, etc. Ver el Cdigo fuente 9.Private Sub mnuRectangulo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuRectangulo.Click ' crear objeto Pen Dim oPen As New Pen(Color.Firebrick, 4) ' aplicar un estilo de lnea con la propiedad ' DashStyle --> guin, punto oPen.DashStyle = Drawing.Drawing2D.DashStyle.DashDot ' obtener el contexto de dispositivo ' grfico del formulario Dim oGraphics As Graphics = Me.CreateGraphics() ' dibujar en el formulario oGraphics.DrawRectangle(oPen, New Rectangle(280, 75, 120, 40)) oGraphics.Dispose() End Sub private void mnuRectangulo_Click(object sender, EventArgs e) { // crear objeto Pen Pen oPen = new Pen(Color.Firebrick, 4); // aplicar un estilo de lnea con la propiedad // DashStyle --> guin, punto oPen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot; // obtener el contexto de dispositivo // grfico del formulario Graphics oGraphics = this.CreateGraphics(); // dibujar en el formulario oGraphics.DrawRectangle(oPen, new Rectangle(280, 75, 120, 40)); oGraphics.Dispose(); Cdigo fuente 9

}

P g i n a | 20

Si queremos aplicar ms estilos a la lnea del objeto Pen, disponemos tambin de las propiedades StartCap, EndCap, DashCap. El Cdigo fuente 10 muestra el dibujo de una curva con varios efectos de lnea. Al dibujar una curva, necesitamos pasar al mtodo DrawCurve() un array de tipos Point, con las coordenadas de referencia a usar para el dibujo de este tipo de figura.Private Sub mnuCurva_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuCurva.Click ' crear objeto Pen Dim oPen As New Pen(Color.MediumPurple, 5) ' configurar estilo de lnea oPen.DashStyle = Drawing.Drawing2D.DashStyle.DashDot oPen.StartCap = Drawing.Drawing2D.LineCap.Triangle oPen.EndCap = Drawing.Drawing2D.LineCap.DiamondAnchor oPen.DashCap = Drawing.Drawing2D.DashCap.Triangle ' obtener el contexto de dispositivo ' grfico del formulario Dim oGraphics As Graphics = Me.CreateGraphics() ' crear un array de puntos-coordenadas necesario ' para dibujar una curva Dim oPuntos(4) As Point oPuntos(0) = New Point(10, 300) oPuntos(1) = New Point(40, 200) oPuntos(2) = New Point(100, 175) oPuntos(3) = New Point(130, 200) oPuntos(4) = New Point(200, 300) ' dibujar en el formulario oGraphics.DrawCurve(oPen, oPuntos) oGraphics.Dispose() End Sub private void mnuCurva_Click(object sender, EventArgs e) { // crear objeto Pen Pen oPen = new Pen(Color.MediumPurple, 5); // configurar estilo de lnea oPen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot; oPen.StartCap = System.Drawing.Drawing2D.LineCap.Triangle; oPen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor; oPen.DashCap = System.Drawing.Drawing2D.DashCap.Triangle; // obtener el contexto de dispositivo // grfico del formulario Graphics oGraphics = this.CreateGraphics(); // crear un array de puntos-coordenadas necesario // para dibujar una curva Point[] oPuntos = new Point[5]; oPuntos[0] = new Point(10, 300); oPuntos[1] = new Point(40, 200); oPuntos[2] = new Point(100, 175); oPuntos[3] = new Point(130, 200); oPuntos[4] = new Point(200, 300); // dibujar en el formulario oGraphics.DrawCurve(oPen, oPuntos); oGraphics.Dispose(); Cdigo fuente 10

}

En cuanto a las curvas de tipo Bezier, el mtodo DrawBezier() recibe como parmetros un objeto Pen y una lista de coordenadas para el dibujo. Ver el Cdigo fuente 11.

P g i n a | 21

Private Sub mnuBezier_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBezier.Click ' dibujar curva estilo Bezier Dim oGraphics As Graphics = Me.CreateGraphics() oGraphics.DrawBezier(New Pen(Color.MediumSeaGreen, 2), 20, 45, 100, 90, 140, 200, 300, 25) oGraphics.Dispose() End Sub private void mnuBezier_Click(object sender, EventArgs e) { // dibujar curva estilo Bezier Graphics oGraphics = this.CreateGraphics(); oGraphics.DrawBezier(new Pen(Color.MediumSeaGreen, 2), 20, 45, 100, 90, 140, 200, 300, 25); oGraphics.Dispose(); } Cdigo fuente 11

Para dibujar una figura con forma irregular utilizaremos el mtodo DrawPolygon(), en el que al igual que con el dibujo de curvas, debemos pasarle un objeto Pen y un array de puntos. Ver el Cdigo fuente 12.Private Sub mnuPoligono_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuPoligono.Click Dim oGraphics As Graphics = Me.CreateGraphics() Dim oPuntos(5) As Point oPuntos(0) = New Point(30, 70) oPuntos(1) = New Point(90, 115) oPuntos(2) = New Point(220, 90) oPuntos(3) = New Point(120, 80) oPuntos(4) = New Point(100, 100) oPuntos(5) = New Point(110, 65) oGraphics.DrawPolygon(New Pen(Color.SandyBrown, 3), oPuntos) oGraphics.Dispose() End Sub private void mnuPoligono_Click(object sender, EventArgs e) { Graphics oGraphics = this.CreateGraphics(); Point[] oPuntos = new Point[6]; oPuntos[0] = new Point(30, 70); oPuntos[1] = new Point(90, 115); oPuntos[2] = new Point(220, 90); oPuntos[3] = new Point(120, 80); oPuntos[4] = new Point(100, 100); oPuntos[5] = new Point(110, 65); oGraphics.DrawPolygon(new Pen(Color.SandyBrown, 3), oPuntos); oGraphics.Dispose(); Cdigo fuente 12

}

La Figura 3 muestra el resultado de la ejecucin de los anteriores ejemplos de cdigo.

P g i n a | 22

Figura 3. Figuras dibujadas con objetos de la clase Pen.

Si en un momento dado, necesitamos borrar los elementos grficos dibujados en la superficie del formulario, utilizaremos el mtodo Invalidate() de la clase Form, tal como vemos en el Cdigo fuente 13.Private Sub mnuBorrar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBorrar.Click ' borrar las figuras dibujadas en el formulario Me.Invalidate() End Sub private void mnuBorrar_Click(object sender, System.EventArgs e) { // borrar las figuras dibujadas en el formulario this.Invalidate(); } Cdigo fuente 13

La clase BrushEsta clase representa un objeto de tipo pincel, utilizado para rellenar las figuras dibujadas sobre el formulario. Se trata de una clase abstracta, por lo que tendremos que utilizar alguna de sus diversas clases derivadas, segn el estilo de pincel que necesitemos aplicar. Debido a las caractersticas 2D de algunas de estas clases, ser necesario declarar en nuestro cdigo el espacio de nombres Drawing2D. Los mtodos de la clase Graphics que utilizaremos para dibujar con pinceles sern los que comienzan por el nombre FillTipoObjeto(). La clase ms bsica es SolidBrush, que permite rellenar en un estilo sencillo un rea dibujada. Ver el Cdigo fuente 14.Private Sub mnuBrushSolid_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBrushSolid.Click Dim oBrush As New SolidBrush(Color.MidnightBlue) Dim oGraphics As Graphics = Me.CreateGraphics()

P g i n a | 23

oGraphics.FillRectangle(oBrush, New Rectangle(150, 160, 150, 50)) oGraphics.Dispose() End Sub private void mnuBrushSolid_Click(object sender, EventArgs e) { SolidBrush oBrush = new SolidBrush(Color.MidnightBlue); Graphics oGraphics = this.CreateGraphics(); oGraphics.FillRectangle(oBrush, new Rectangle(150, 160, 150, 50)); oGraphics.Dispose(); } Cdigo fuente 14

A continuacin tenemos la clase HatchBrush, que permite la creacin de pinceles que al pintar aplican un efecto de tramado, con un color de fondo y otro de frente. Ver el Cdigo fuente 15.Imports System.Drawing.Drawing2D '.... Private Sub mnuBrushHatch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBrushHatch.Click ' pintar con pincel de tipo hatch; ' para utilizar este tipo de pincel ' necesitamos importar System.Drawing.Drawind2D ' crear objeto HatchBrush Dim oHatchBrush As New HatchBrush(HatchStyle.Vertical, Color.Fuchsia, Color.Aqua) ' dibujar y pintar un polgono Dim oGraphics As Graphics = Me.CreateGraphics() oGraphics.FillEllipse(oHatchBrush, New Rectangle(25, 40, 150, 50)) oGraphics.Dispose() End Sub using System.Drawing.Drawing2D; //.... private void mnuBrushHatch_Click(object sender, EventArgs e) { // pintar con pincel de tipo hatch; // para utilizar este tipo de pincel // necesitamos usar System.Drawing.Drawind2D // crear objeto HatchBrush HatchBrush oHatchBrush = new HatchBrush(HatchStyle.Vertical, Color.Fuchsia, Color.Aqua); // dibujar y pintar un polgono Graphics oGraphics = this.CreateGraphics(); oGraphics.FillEllipse(oHatchBrush, new Rectangle(25, 40, 150, 50)); oGraphics.Dispose(); Cdigo fuente 15

}

Podemos emplear un bitmap como base para la zona de relleno que tendr que pintarse, para ello usaremos la clase TextureBrush, pasndole como parmetro un objeto Bitmap, que previamente habremos creado a partir de un archivo grfico que contenga la textura necesaria. Ver el Cdigo fuente 16.Private Sub mnuBrushTexture_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBrushTexture.Click ' crear un bitmap Dim oBitmap As New Bitmap("textura1.bmp") ' crear una brocha de textura Dim oTextureBrush As New TextureBrush(oBitmap)

P g i n a | 24

' dibujar una figura y pintarla con la brocha de textura Dim oGraphics As Graphics = Me.CreateGraphics() oGraphics.FillEllipse(oTextureBrush, New Rectangle(220, 50, 100, 75)) oGraphics.Dispose() End Sub private void mnuBrushTexture_Click(object sender, EventArgs e) { // crear un bitmap Bitmap oBitmap = new Bitmap("textura1.bmp"); // crear una brocha de textura TextureBrush oTextureBrush = new TextureBrush(oBitmap); // dibujar una figura y pintarla con la brocha de textura Graphics oGraphics = this.CreateGraphics(); oGraphics.FillEllipse(oTextureBrush, new Rectangle(220, 50, 100, 75)); oGraphics.Dispose(); Cdigo fuente 16

}

La Figura 4 muestra estas figuras con el relleno correspondiente.

Figura 4. Figuras con efecto de relleno.

Creacin de figuras complejas con la clase GraphicsPathLa clase GraphicsPath nos permite la generacin de dibujos ms complejos que los conseguidos hasta ahora con la clase Graphics. Un objeto GraphicsPath consiste en un contenedor de figuras, las cuales iremos aadiendo mediante los mtodos AddTipoObjeto() de esta clase, hasta conseguir el grfico final resultante. Ver el Cdigo fuente 17.Private Sub mnuGPathAbierta_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuGPathAbierta.Click ' crear el objeto GraphicsPath Dim oGraphPath As New GraphicsPath ' aadir figuras dentro del objeto oGraphPath.AddEllipse(40, 40, 100, 100) oGraphPath.AddLine(New Point(50, 70), New Point(115, 70)) oGraphPath.AddCurve(New Point() {New Point(60, 90), New Point(70, 125), New Point(100, 100)})

P g i n a | 25

' dibujar el GraphicsPath en el formulario Dim oGraph As Graphics = Me.CreateGraphics oGraph.DrawPath(New Pen(Color.DarkTurquoise, 8), oGraphPath) oGraph.Dispose() End Sub private void mnuGPathAbierta_Click(object sender, EventArgs e) { // crear el objeto GraphicsPath GraphicsPath oGraphPath = new GraphicsPath(); // aadir figuras dentro del objeto oGraphPath.AddEllipse(40,40 , 100, 100); oGraphPath.AddLine(new Point(50,70), new Point(115,70)); oGraphPath.AddCurve(new Point[] {new Point(60,90), new Point(70, 125), new Point(100, 100)}); // dibujar el GraphicsPath en el formulario Graphics oGraph = this.CreateGraphics(); oGraph.DrawPath(new Pen(Color.DarkTurquoise, 8), oGraphPath); oGraph.Dispose(); Cdigo fuente 17

}

La Figura 5 muestra el resultado de una figura creada con GraphicsPath.

Figura 5. Imagen generada con un objeto GraphicsPath.

Si queremos que las figuras aadidas al objeto GraphicsPath, queden unidas desde el punto inicial de la primera figura hasta el punto final de la ltima, llamaremos al mtodo StartFigure() antes de empezar a aadir la primera figura, y a CloseFigure() despus de aadir la ltima. Ver el Cdigo fuente 18.Private Sub mnuGPathCerrada_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuGPathCerrada.Click ' crear el objeto GraphicsPath Dim oGraphPath As New GraphicsPath ' comenzar a aadir figuras dentro del objeto oGraphPath.StartFigure() oGraphPath.AddEllipse(40, 40, 120, 100) oGraphPath.AddLine(New Point(30, 30), New Point(90, 30)) oGraphPath.AddCurve(New Point() {New Point(40, 40), New Point(70, 110), New Point(100, 60)}) ' cerrar el objeto oGraphPath.CloseFigure() ' dibujar el GraphicsPath en el formulario Dim oGraph As Graphics = Me.CreateGraphics oGraph.DrawPath(New Pen(Color.LightSteelBlue, 5), oGraphPath) oGraph.Dispose() End Sub

P g i n a | 26

private void mnuGPathCerrada_Click(object sender, System.EventArgs e) { // crear el objeto GraphicsPath GraphicsPath oGraphPath = new GraphicsPath(); // comenzar a aadir figuras dentro del objeto oGraphPath.StartFigure(); oGraphPath.AddEllipse(40, 40, 120, 100); oGraphPath.AddLine(new Point(30, 30), new Point(90, 30)); oGraphPath.AddCurve(new Point[] {new Point(40, 40), new Point(70, 110), new Point(100, 60)}); // cerrar el objeto oGraphPath.CloseFigure(); // dibujar el GraphicsPath en el formulario Graphics oGraph = this.CreateGraphics(); oGraph.DrawPath(new Pen(Color.LightSteelBlue, 5), oGraphPath); oGraph.Dispose(); Cdigo fuente 18

}

La Figura 6 muestra un conjunto de imgenes unidas por todos sus puntos, creadas con GraphicsPath.

Figura 6. Imgenes unidas creadas con un objeto GraphicsPath.

Aplicacin de efectos avanzados con la clase BrushPara efectos avanzados de relleno, consistentes en degradados de colores, utilizaremos las clases LinearGradientBrush y PathGradientBrush. Una vez instanciado un objeto de estas clases, aplicaremos un conjunto de colores, que sern mezclados para crear un efecto de degradado o fundido en el rea a pintar, utilizando el constructor y/o las propiedades de la clase que corresponda. Ver el Cdigo fuente 19.Private Sub mnuBrushLinearGradient_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBrushLinearGradient.Click ' crear pincel de tipo LinearGradient Dim oLGB As New LinearGradientBrush(New Rectangle(10, 50, 40, 60), Color.Aquamarine, Color.Azure, LinearGradientMode.Horizontal) ' crear array de coordenadas Dim oPuntos(2) As Point oPuntos(0) = New Point(20, 200) oPuntos(1) = New Point(75, 100) oPuntos(2) = New Point(140, 220) ' obtener contexto grfico Dim oGraphics As Graphics = Me.CreateGraphics() ' dibujar y pintar una curva cerrada

P g i n a | 27

oGraphics.FillClosedCurve(oLGB, oPuntos) oGraphics.Dispose() End Sub '-----------------------------------Private Sub mnuBrushPathGradient_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBrushPathGradient.Click ' array de coordenadas Dim oPuntos(2) As Point oPuntos(0) = New Point(150, 150) oPuntos(1) = New Point(225, 80) oPuntos(2) = New Point(260, 150) ' crear pincel de tipo PathGradient, ' y configurar el objeto Dim oPGB As New PathGradientBrush(oPuntos) oPGB.CenterColor = Color.Indigo oPGB.SurroundColors = New Color() {Color.Beige, Color.LightGreen} ' crear grfico y pintar polgono Dim oGraphics As Graphics = Me.CreateGraphics() oGraphics.FillPolygon(oPGB, oPuntos) oGraphics.Dispose() End Sub private void mnuBrushLinearGradient_Click(object sender, EventArgs e) { // crear brocha de tipo LinearGradient LinearGradientBrush oLGB = new LinearGradientBrush(new Rectangle(10, 50, 40, 60), Color.Aquamarine, Color.Azure, LinearGradientMode.Horizontal); // crear array de coordenadas Point[] oPuntos = new Point[3]; oPuntos[0] = new Point(20, 200); oPuntos[1] = new Point(75, 100); oPuntos[2] = new Point(140, 220); // obtener contexto grfico Graphics oGraphics = this.CreateGraphics(); // dibujar y pintar una curva cerrada oGraphics.FillClosedCurve(oLGB, oPuntos); oGraphics.Dispose();

} //-----------------------------------private void mnuBrushPathGradient_Click(object sender, EventArgs e) { // array de coordenadas Point[] oPuntos = new Point[3]; oPuntos[0] = new Point(150, 150); oPuntos[1] = new Point(225, 80); oPuntos[2] = new Point(260, 150); // crear brocha de tipo PathGradient, // y configurar el objeto PathGradientBrush oPGB = new PathGradientBrush(oPuntos); oPGB.CenterColor = Color.Indigo; oPGB.SurroundColors = new Color[] { Color.Beige, Color.LightGreen }; // crear grfico y pintar polgono Graphics oGraphics = this.CreateGraphics(); oGraphics.FillPolygon(oPGB, oPuntos); oGraphics.Dispose(); Cdigo fuente 19

}

La Figura 7 muestra alguna de las formas dibujadas utilizando objetos con efecto de gradiente

P g i n a | 28

Figura 7. Figuras con efecto de gradiente.

Objetos grficos con caractersticas del sistemaLas clases SystemPens, SystemBrushes y SystemColors, nos permiten crear y manipular elementos grficos con la particularidad de que algunas de sus caractersticas sern iguales a las definidas para el sistema operativo. El Cdigo fuente 20 muestra unos ejemplos en los que creamos un objeto Pen del sistema, y un objeto Brush que tiene un color del sistema.Private Sub mnuPenSistema_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuPenSistema.Click ' crear objeto Pen del sistema Dim oPen As Pen oPen = SystemPens.ControlDark ' obtener el contexto de dispositivo ' grfico del formulario Dim oGraphics As Graphics = Me.CreateGraphics() ' dibujar en el formulario oGraphics.DrawEllipse(oPen, New Rectangle(150, 120, 100, 100)) oGraphics.Dispose() End Sub '-----------------------------------Private Sub mnuBrushSistema_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuBrushSistema.Click ' crear un objeto brush con un color de sistema Dim oBrush As New SolidBrush(SystemColors.ControlDark) Dim oGraphics As Graphics = Me.CreateGraphics() oGraphics.FillEllipse(oBrush, New Rectangle(200, 200, 150, 50)) oGraphics.Dispose() End Sub private void mnuPenSistema_Click(object sender, System.EventArgs e) { // crear objeto Pen del sistema Pen oPen; oPen = SystemPens.ControlDark; // obtener el contexto de dispositivo

P g i n a | 29

// grfico del formulario Graphics oGraphics = this.CreateGraphics(); // dibujar en el formulario oGraphics.DrawEllipse(oPen, new Rectangle(150, 120, 100, 100)); oGraphics.Dispose();

} //---------------------private void mnuBrushSistema_Click(object sender, System.EventArgs e) { // crear un objeto brush con un color de sistema SolidBrush oBrush = new SolidBrush(SystemColors.ControlDark); Graphics oGraphics = this.CreateGraphics(); oGraphics.FillEllipse(oBrush, new Rectangle(200, 200, 150, 50)); oGraphics.Dispose(); } Cdigo fuente 20

Dibujo de texto en el formularioAparte de los controles que nos permiten visualizar y editar texto, como Label, TextBox, etc., podemos realizar operaciones de dibujo de texto en la superficie del formulario, empleando el mtodo DrawString() de la clase Graphics. El texto visualizado mediante esta tcnica no es, evidentemente, editable, sino que se encamina fundamentalmente a ser mostrado con efectos adicionales, que no podramos conseguir mediante los controles tpicos. En el Cdigo fuente 21 creamos un objeto HatchBrush con un tramado especfico, un objeto Font de una determinada familia, y con ambos elementos, pintamos el texto mediante un objeto Graphics.Private Sub mnuTextoGrafico_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuTextoGrafico.Click ' crear un objeto Brush con efectos Dim oBrush As New HatchBrush(HatchStyle.Wave, Color.Aqua, Color.DarkGreen) ' crear el tipo de letra Dim oFont As New Font(New FontFamily("Georgia"), 50) ' obtener el dispositivo grfico del formulario ' y pintar el texto Dim oGraf As Graphics = Me.CreateGraphics() oGraf.DrawString("Texto en modo grfico", _ oFont, oBrush, New RectangleF(20, 20, 500, 200)) End Sub private void mnuTextoGrafico_Click(object sender, EventArgs e) { // crear un objeto Brush con efectos HatchBrush oBrush = new HatchBrush(HatchStyle.Wave, Color.Aqua, Color.DarkGreen); // crear el tipo de letra Font oFont = new Font(new FontFamily("Georgia"), 50); // obtener el dispositivo grfico del formulario // y pintar el texto Graphics oGraf = this.CreateGraphics(); oGraf.DrawString("Texto en modo grfico", oFont, oBrush, new RectangleF(20, 20, 500, 200)); oGraf.Dispose(); Cdigo fuente 21

}

P g i n a | 30

La Figura 8 muestra el texto dibujado en el formulario.

Figura 8. Dibujo de texto empleando las clases para manipulacin de grficos.

Personalizacin de la imagen de fondo del formularioPara establecer una imagen de fondo en el formulario disponemos de la propiedad BackgroundImage, aunque su facilidad de uso tiene desafortunadamente un lado negativo, ya que el tamao de la imagen asignada, no se adapta automticamente al del formulario. Por tal motivo, en este apartado vamos a proporcionar al lector un par de tcnicas, que le permitirn crear imgenes de fondo para formularios con ajuste dinmico, de forma que la imagen adapte sus dimensiones a las del formulario, cuando este cambie su tamao en tiempo de ejecucin.

Manipulacin de los eventos de pintado en la clase formEl primer ejemplo se basa en la codificacin del evento Paint() de la clase Form, dentro de cuyo mtodo manipulador creamos un objeto Bitmap, que contenga la ruta hacia un archivo con el grfico a mostrar de fondo. A continuacin, mediante el objeto Graphics obtenido del parmetro EventArgs del evento, pintamos el objeto Bitmap. Ver el Cdigo fuente 22.Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint ' crear un objeto bitmap Dim oBitmap As New Bitmap("LogoWinXP.gif") ' pintar el objeto con el contexto ' grfico del formulario; ' el area a pintar abarca desde la ' coordenada 0,0 y toma el ancho y alto ' del formulario de su propiedad Size Dim oGraphics As Graphics = e.Graphics oGraphics.DrawImage(oBitmap, 0, 0, Me.Size.Width, Me.Size.Height) oGraphics.Dispose() End Sub private void Form1_Paint(object sender, PaintEventArgs e) { // crear un objeto bitmap Bitmap oBitmap = new Bitmap("LogoWinXP.gif"); // // // // // pintar el objeto con el contexto grfico del formulario; el area a pintar abarca desde la coordenada 0,0 y toma el ancho y alto del formulario de su propiedad Size

P g i n a | 31

}

Graphics oGraphics = e.Graphics; oGraphics.DrawImage(oBitmap, 0, 0, this.Size.Width, this.Size.Height); oGraphics.Dispose(); Cdigo fuente 22

Queda todava un paso ms, ya que aunque la imagen se muestra como fondo del formulario, si redimensionamos este, slo se repinta la parte nueva redimensionada, produciendo un efecto no deseado. Ver la Figura 9.

Figura 9. Imagen de fondo con repintado irregular.

Para conseguir que se pinte de nuevo toda la imagen, debemos utilizar el evento Resize para invalidar la zona grfica del formulario mediante el mtodo Form.Invalidate(). Este evento se produce cada vez que cambia el tamao del formulario. Ver el Cdigo fuente 23.Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize ' cada vez que cambie el tamao del formulario ' invalidamos su rea de dibujo para que ' el evento Paint pinte toda la superficie Me.Invalidate() End Sub private void Form1_Resize(object sender, System.EventArgs e) { // cada vez que cambie el tamao del formulario // invalidamos su rea de dibujo para que // el evento Paint pinte toda la superficie this.Invalidate(); } Cdigo fuente 23

El control pictureboxDespus de la tcnica compleja (slo en parte), pasemos ahora al modo fcil para crear una imagen de fondo, empleando el control PictureBox. Este control nos permite la visualizacin de imgenes en el formulario de un modo sencillo, ya que toda la mecnica de generacin la lleva incorporada, con lo que el programador se despreocupa de la manipulacin del grfico a mostrar. Una vez insertado un PictureBox en el formulario, asignaremos a su propiedad Dock el valor Fill, de forma que el control ocupe por completo la superficie del formulario.

P g i n a | 32

A continuacin asignaremos el archivo de imagen a la propiedad Image, y por ltimo estableceremos la propiedad SizeMode al valor StretchImage. Estas operaciones podemos realizarlas tanto en modo de diseo como por cdigo, lo cual vemos en el Cdigo fuente 24.Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.picImagenFondo.Image = New Bitmap("LogoWinXP.gif") Me.picImagenFondo.SizeMode = PictureBoxSizeMode.StretchImage End Sub private void Form1_Load(object sender, EventArgs e) { this.picImagenFondo.Image = new Bitmap("LogoWinXP.gif"); this.picImagenFondo.SizeMode = PictureBoxSizeMode.StretchImage; } Cdigo fuente 24

Al ejecutar la aplicacin, la imagen quedar en todo momento ajustada al formulario; el mismo resultado que con el anterior ejemplo, pero ms sencillo en este caso. Ver la Figura 10.

Figura 10. Imagen de fondo del formulario empleando un PictureBox.

Manipulando el grado de opacidad del formularioLa propiedad Opacity de la clase Form, contiene un valor numrico de tipo Double que permite establecer el grado de opacidad del formulario. Cuando esta propiedad contenga el valor uno, el formulario se mostrar en la forma habitual, y cuando el valor sea cero, el formulario ser transparente. Podemos asignar valores intermedios de modo que hagamos parcialmente transparente el formulario, mostrando los elementos que quedan bajo el mismo. Debemos tener en cuenta que cuando asignemos este valor mediante la ventana de propiedades del formulario en modo de diseo, el nmero asignado ser el porcentaje de opacidad. La Figura 11 muestra la ventana de propiedades para este caso con un setenta y cinco por ciento de opacidad para el formulario.

Figura 11. Propiedad Opacity establecida desde la ventana de propiedades del IDE.

La Figura 12 muestra este formulario con el anterior porcentaje de opacidad.

P g i n a | 33

Figura 12. Formulario parcialmente transparente debido a la propiedad Opacity.

En el Cdigo fuente 25 establecemos, desde el evento DoubleClick del formulario, la opacidad de este ltimo a un grado del cuarenta y cinco por ciento.Private Sub Form1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DoubleClick Me.Opacity = 0.45 End Sub private void Form1_DoubleClick(object sender, System.EventArgs e) { this.Opacity = 0.45; } Cdigo fuente 25

Podemos proporcionar una mayor interaccin al usuario para esta propiedad, aadiendo al formulario un control TrackBar, que con el estilo de un control de volumen, nos va a permitir graduar el nivel de opacidad del formulario. Mediante las propiedades Maximum y Minimum estableceremos el rango de opacidad respectivamente a diez y cero. Por otra parte, asignaremos a la propiedad LargeChange el valor uno, para que el desplazamiento del indicador del control sea ms suave; mientras que en la propiedad Value asignaremos el valor diez, para partir de la mxima opacidad e ir disminuyendo. Como efectos visuales de este control, las propiedades Orientation y TickStyle nos permiten establecer la orientacin del indicador de posicin y su apariencia. Finalmente, el evento Scroll se producir cada vez que movamos el indicador de posicin en el control, ejecutando el cdigo de su procedimiento manipulador, que vemos en el Cdigo fuente 26.Private Sub tkbOpaco_Scroll(ByVal sender As Object, ByVal e As System.EventArgs) Handles tkbOpaco.Scroll ' cada vez que se mueve el desplazador ' del TrackBar se modifica la opacidad Select Case Me.tkbOpaco.Value Case 0 Me.Opacity = 0 Case 10 Me.Opacity = 1 Case Else Me.Opacity = Me.tkbOpaco.Value / 10

P g i n a | 34

End Select End Sub private void tkbOpaco_Scroll(object sender, System.EventArgs e) { // cada vez que se mueve el desplazador // del TrackBar se modifica el grado de opacidad switch (this.tkbOpaco.Value) { case 0: this.Opacity=0; break; case 10: this.Opacity=1; break; default: this.Opacity=(double)this.tkbOpaco.Value / (double)10; break;

}

}

Cdigo fuente 26

La Figura 13 muestra este ejemplo en ejecucin.

Figura 13. Utilizando un TrackBar para graduar la opacidad de un formulario.

Esta til caracterstica de los formularios nos permite, por ejemplo, proporcionar un efecto de fundido durante su proceso de cierre. Para conseguirlo, escribiremos el cdigo necesario en el manipulador del evento FormClosing del formulario. Este evento es producido cuando el formulario est a punto de cerrarse, y lo que haremos ser cancelar el cierre del formulario, creando un temporizador que ser el que a lo largo de varios intervalos de tiempo, realizar el fundido y cierre. En el cdigo del evento Tick crearemos el efecto de fundido, disminuyendo el grado de opacidad del formulario hasta hacerlo invisible, punto en el que cerraremos el formulario. Esto har que se vuelva a pasar por el evento FormClosing, pero en esta ocasin, como la opacidad del formulario estar a cero, no se volver a realizar el proceso de fundido. Ver el Cdigo fuente 27.Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.FormClosing Dim oTiempo As Timer ' el formulario debe tener el valor 1 ' en Opacity para conseguir el efecto If Me.Opacity 0 Then

P g i n a | 35

' cancelamos el cierre del formulario e.Cancel = True ' iniciamos un temporizador cada medio segundo oTiempo = New Timer() oTiempo.Interval = 500 ' conectamos el temporizador con un manipulador ' de su evento Tick AddHandler oTiempo.Tick, AddressOf TickTiempo oTiempo.Start() End If End Sub '---------------------------------------Private Sub TickTiempo(ByVal sender As Object, ByVal e As EventArgs) ' este manipulador del evento del temporizador, ' cada medio segundo ir disminuyendo el grado ' de opacidad del formulario hasta hacerlo invisible Static dbContador As Double = 1 dbContador -= 0.1 Me.Opacity = dbContador ' cuando el formulario es invisible If Me.Opacity = 0 Then ' parar el temporizador CType(sender, Timer).Stop() ' cerrar el formulario Me.Close() End If End Sub

private void Form1_FormClosing(object sender, System.ComponentModel.CancelEventArgs e) { Timer oTiempo; // el formulario debe tener el valor 1 // en Opacity para conseguir el efecto if (this.Opacity != 0) { // cancelamos el cierre del formulario e.Cancel = true; // iniciamos un temporizador cada medio segundo oTiempo = new Timer(); oTiempo.Interval = 500; // conectamos el temporizador con un manipulador // de su evento Tick oTiempo.Tick += new EventHandler(TickTiempo); oTiempo.Start();

} } //---------------------------------------private double dbContador = 1;

private void TickTiempo(Object sender, EventArgs e) { // este manipulador del evento del temporizador, // cada medio segundo ir disminuyendo el grado // de opacidad del formulario hasta hacerlo invisible dbContador -= 0.1; this.Opacity = dbContador; // cuando el formulario es invisible if (this.Opacity == 0) { // parar el temporizador ((Timer)sender).Stop();

P g i n a | 36

}

}

// cerrar el formulario this.Close();

Cdigo fuente 27

Creacin de formularios con formas irregularesLas capacidades grficas de GDI+ nos permiten dotar a los formularios de efectos hasta la fecha muy difciles de conseguir, si no se conoca en profundidad el API de Windows. Aspectos como la transparencia del formulario tratada en el apartado anterior, o el cambio en su forma estndar, que veremos seguidamente, permiten la creacin de ventanas con una apariencia no convencional.

Usando la clase regionPara cambiar el aspecto rectangular de un formulario, dotndole de una forma irregular, debemos, en primer lugar, declarar en nuestro cdigo el espacio de nombres System.Drawing.Drawing2D. A continuacin crearemos un objeto de la clase GraphicsPath, y mediante alguno de sus mtodos AddTipoObjeto(), le aadiremos una figura que ser la que se utilice para la forma del formulario. Finalmente crearemos un objeto de tipo Region, al que pasaremos el objeto GraphicsPath con la figura creada previamente. Esto crear una regin con dicha figura, que asignaremos a la propiedad Region del formulario, consiguiendo de esta manera, modificar el aspecto del formulario en cuanto a su forma. El Cdigo fuente 28 muestra unos ejemplos de cmo modificar el aspecto del formulario, que incorpora sendos botones para cambiar su forma a un crculo y un tringulo respectivamente.Imports System.Drawing.Drawing2D '.... Private Sub btnCirculo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCirculo.Click ' crear un GraphicsPath y aadirle un crculo Dim oGPath As GraphicsPath = New GraphicsPath() oGPath.AddEllipse(New Rectangle(0, 0, 200, 260)) ' crear una regin con el objeto GraphicsPath ' y asignarla a la regin del formulario Me.Region = New Region(oGPath) End Sub Private Sub btnPoligono_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPoligono.Click ' mostrar el formulario con la forma ' de un tringulo utilizando tambin ' un objeto GraphicsPath y un Region Dim oPuntos(2) As Point oPuntos(0) = New Point(-20, -20) oPuntos(1) = New Point(-20, 200) oPuntos(2) = New Point(220, 90) Dim oGPath As GraphicsPath = New GraphicsPath() oGPath.AddPolygon(oPuntos) Me.Region = New Region(oGPath) End Sub

P g i n a | 37

using System.Drawing.Drawing2D; //.... private void btnCirculo_Click(object sender, EventArgs e) { // crear un GraphicsPath y aadirle un crculo GraphicsPath oGPath = new GraphicsPath(); oGPath.AddEllipse(new Rectangle(0, 0, 200, 260)); // crear una regin con el objeto GraphicsPath // y asignarla a la regin del formulario this.Region = new Region(oGPath);

}

private void btnPoligono_Click(object sender, EventArgs e) { // mostrar el formulario con la forma // de un tringulo utilizando tambin // un objeto GraphicsPath y un Region Point[] oPuntos = new Point[3]; oPuntos[0] = new Point(-20, -20); oPuntos[1] = new Point(-20, 200); oPuntos[2] = new Point(220, 90); GraphicsPath oGPath = new GraphicsPath(); oGPath.AddPolygon(oPuntos); } this.Region = new Region(oGPath); Cdigo fuente 28

La Figura 14 muestra el formulario con forma de elipse.

Figura 14. Formulario con forma de elipse.

La Figura 15 muestra el formulario con forma de tringulo.

P g i n a | 38

Figura 15. Formulario con forma triangular.

Los efectos que acabamos de aplicar sobre la forma del formulario tienen el inconveniente de que ocultan los botones de la barra de ttulo del mismo. Para modificar la forma de una ventana pero manteniendo su barra de ttulos visible al completo, tenemos que seguir los siguientes pasos: crear un objeto Rectangle con el tamao del formulario, aplicar la modificacin de forma al objeto GraphicsPath; crear una nueva regin de dibujo; modificar el rectngulo adaptndolo al tamao de la barra de ttulos; unir el rectngulo con la regin; y finalmente asignar la regin a la propiedad Region del formulario. El Cdigo fuente 29 muestra un ejemplo con las operaciones que acabamos de describir.Private Sub btnBarraTitulo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBarraTitulo.Click ' crear un rectngulo con las dimensiones del formulario Dim oRectangulo As Rectangle oRectangulo = New Rectangle(0, 0, Me.Size.Width, Me.Size.Height) ' crear un GraphicsPath Dim oGraphPath As GraphicsPath = New GraphicsPath ' aadir al GraphicsPath una elipse ' con las dimensiones del rectngulo oGraphPath.AddEllipse(oRectangulo) ' crear un objeto Region usando el objeto GraphicsPath Dim oRegion As Region = New Region(oGraphPath) ' modificar tamao del rectngulo para ' que se ajuste a las dimensiones de la ' barra de ttulo del formulario oRectangulo.Width = 400 oRectangulo.Height = 25 ' une el objeto region con el rectngulo oRegion.Union(oRectangulo) ' asigna el objeto Region ' a la regin de dibujo del formulario Me.Region = oRegion End Sub private void btnBarraTitulo_Click(object sender, System.EventArgs e) { // crear un rectngulo con las dimensiones del formulario Rectangle oRectangulo; oRectangulo = new Rectangle(0, 0, this.Size.Width, this.Size.Height); // crear un GraphicsPath

P g i n a | 39

GraphicsPath oGraphPath = new GraphicsPath(); // aadir al GraphicsPath una elipse // con las dimensiones del rectngulo oGraphPath.AddEllipse(oRectangulo); // crear un objeto Region usando el objeto GraphicsPath Region oRegion = new Regio