UNIDAD 4 Interfaz Gráfica de Usuario(GUI). 4.1 Creación de interfaz gráfica para usuarios. 4.1.1 Librería de interfaz gráfica (API’s). 4.1.

2 Aplicaciones GUI. 4.2 Computación gráfica. 4.2.1 Área de dibujo. 4.2.2 Primitivas de dibujo (línea, arco, círculo, colores, rellenos, imágenes).

API de Windows
La interfaz de programación de aplicaciones (API - Application Programming Interface) es un conjunto de funciones residentes en bibliotecas (generalmente dinámicas) que permiten que una aplicación corra bajo el sistema operativo Windows. Las funciones API se dividen en varias categorías:
• • • • • • • • • • •

Depuración y manejo de errores E/S de dispositivos DLLs, procesos e hilos Comunicación entre procesos Manejo de la memoria Monitoreo del desempeño Manejo de energía Almacenamiento Información del sistema

GDI (interfaz gráfica) de Windows
Interfaz de usuario de Windows

Versiones
La primera versión era la Win16, de 16 bits. Las versiones modernas de Windows utilizan la API de 32 bits llamada Win32. Está compuesta por funciones en C almacenadas en librerías de enlace dinámico (DLL), especialmente en las del núcleo:
• • •

kernel32.dll user32.dll gdi32.dll 1

Aunque la implementación de Microsoft tiene derechos de autor, generalmente se acepta que otras empresas puedan emular Windows proporcionando APIs idénticas, sin que implique violación de derechos de autor. Win64 es la extensión de 64 bits de Win32. La siguiente versión es WinFX, que está basada en nuevas tecnologías que se están probando en la siguiente versión de Windows, por ahora llamada Longhorn. La interfaz gráfica de WinFX se llama Avalon y requiere tarjetas graficadoras modernas. El proyecto WINE es un intento de que esta API esté disponible para plataformas tipo UNIX.

Compiladores
Para desarrollar programas que funcionen en Windows se necesita un compilador que maneje las DLL y objetos COM específicos de Microsoft, así como también un cierto número de archivos de cabecera de C (header files, .h) que definen las interfaces de las DLL. Generalmente se usan las familias de compiladores Visual Studio y Borland, pero ahora existen herramientas de dominio público como MinGW y Cygwin.

2

La GDI es provista como una librería llamada Gdi.dll. en informática. (Véase Interfaz de usuario). como guardar un archivo. Otra ventaja es que las aplicaciones escritas para una interfaz gráfica de usuario son independientes de los dispositivos: a medida que la interfaz cambia para permitir el uso de nuevos dispositivos de entrada y salida. DEFINICION: Interfaz gráfica de usuario. figuras. ya que no está sujeto a los detalles de la visualización ni a la entrada a través del ratón o del teclado. las interfaces gráficas de usuario ofrecen un entorno que se encarga de la comunicación con el ordenador o computadora. 4. 4. porque la interfaz proporciona mecanismos estándar de control como ventanas y cuadros de diálogo. Este incluye la plataforma donde se dibujará. Para los autores de aplicaciones. 3 . Un dispositivo de contexto (contexto de dispositivo) es un conjunto de herramientas para dibujar líneas.2 Aplicaciones GUI. Las selecciones pueden activarse bien a través del teclado o con el ratón. los colores.1. y otros gráficos. INTERFAZ DE DISPOSITIVO GRAFICO (GDI). las herramientas necesarias para dibujar en la plataforma. las aplicaciones pueden utilizarlos sin necesidad de cambios. También permite a los programadores crear programas que realicen de la misma forma las tareas más frecuentes. como un monitor de pantalla grande o un dispositivo óptico de almacenamiento. tipo de visualización que permite al usuario elegir comandos. iniciar programas y ver listas de archivos y otras opciones utilizando las representaciones visuales (iconos) y las listas de elementos del menú. Microsoft creo la GDI.1.1 Librería de interfaz gráfica (API’s). la orientación y otras variaciones de los dibujos. variables. y otros accesorios que pueden completar su imaginación.1 Creación de interfaz gráfica para usuarios. Este es un conjunto de clases funciones. el dimensionamiento de la plataforma. y constantes que agrupan todo (o casi todo) lo necesario para dibujar sobre una aplicación. Para proveer el soporte para dibujo en Windows.4. Esto hace que el programador pueda concentrarse en la funcionalidad.

debemos crear un dispositivo de contexto. 4. colores. La posición horizontal esta basada en el eje X que se mueve desde el origen y hacia la derecha. el cual se mueve desde el origen y hacia abajo. para poder dibujar.2.2. arco. imágenes). Esto se realiza declarando una variable de tipo HDC (Handle Device Context – Manejador del Dispositivo de Contexto-). EL Canvas En una aplicación Win32.2 Computación gráfica. El dispositivo de contexto utiliza un sistema de coordenadas que tiene su origen (0.4. círculo. Este sistema de coordenadas nos dan la posición de un objeto tanto en medidas horizontales como verticales. 4. 4 .0) en la esquina superior izquierda: Todo lo que coloquemos o dibujemos en la pantalla esta basado en este origen.2 Primitivas de dibujo (línea.1 Área de dibujo (Canvas). rellenos. La posición vertical usa el eje Y.

Como la clase TCanvas no implementa todo lo que es posible dibujar en Win32. ésta clase provee un handle (manejador) que permite que TCanvas use una variable HDC 5 . En una aplicación VCL. la cual es derivada de TObject. cada control necesita dibujar sobre un objeto TCanvas.Por ejemplo si queremos dibujar una linea cuyas coordenadas son: Inicio : (0. TCanvas esta basada en la clase TPersistent.100) Esta será colocada en la siguiente posición: 100 100 ClientHeight ClientWidth Para simplificar el dibujo y hacer este compatible con la VCL. pero la clase TCanvas abarca casi todo lo que puede usarse para dibujar. Para facilitar el dibujado. Todo esto significa que no tenemos que declarar una variable TCanvas antes de dibujar. un canvas (lienzo) es el objeto sobre el cual dibujamos. Borland creó una clase llamada TCanvas.0) Fin(100. Esto incluye la plataforma y las herramientas.

borrelos y restaure los originales SelectObject(hdc. 0)). 0. RGB(255..250). hbrushOld. hbrush). y en su evento OnClick agregue el siguiente código: void __fastcall TForm1::Button1Click(TObject *Sender) { HPEN hpen. DeleteObject(hbrush).EJEMPLO 1: Dibujo de un rectángulo utilizando la API de Windows.Coloque un botón en una forma. 400. hpen). hpenOld. HBRUSH hbrush. hbrushOld). // Despues de utilizar sus objetos. // Pluma con color rojo para el borde hpen = CreatePen(PS_SOLID. 1. DeleteObject(hpen). hpenOld).100. 1. SelectObject(hdc. 0. } 6 . 255)). hbrushOld = SelectObject(hdc. // Brocha con color azul para el interior hbrush = CreateSolidBrush(RGB(0. // this de la forma HDC hdc = this->Canvas->Handle. // Seleccione la nueva pluma y la brocha para dibujar un rectangulo hpenOld = SelectObject(hdc. 100. Rectangle(hdc.

y además utilizar la función de Windows para establecer el color. Recto. 425. la cual nos permite definir un rectángulo. } 7 .left = 100.bottom = 350.cad. HDC hDC = Canvas->Handle.top = 100.2. 140.0)). Recto. BF_RECT). DrawEdge(hDC. &Recto. &Recto. //char *cad="hola".Coloque otro Botón para dibujar un rectángulo e insertar un texto dentro de él. BDR_RAISEDOUTER | BDR_SUNKENINNER.Coloque otro Botón para utilizar la estructura TRECT. //Valores para probar DrawText(hDC. void __fastcall TForm1::Button2Click(TObject *Sender) { TRect Recto2(250.0.DT_CENTER). char *cad="TECNOLOGICO DE LA LAGUNA". HDC hDC = Canvas->Handle.. Recto. 200). void __fastcall TForm1::Button3Click(TObject *Sender) { RECT Recto.. DrawEdge(hDC. 425. BF_RECT).Coloque otro Botón para utilizar la estructura RECT. BDR_RAISEDOUTER | BDR_SUNKENINNER. //Aqui utilizamos directamente el Canvas Canvas->Rectangle(Recto). y agregue el siguiente código: Nota: La estructura RECT define las coordenadas de las ezquinas superior-izquierda e inferior-derecha de un rectángulo. 20..RGB(255. } 3. } 3.right = 400. SetTextColor(hDC. 115). //DT_RIGHT). void __fastcall TForm1::Button3Click(TObject *Sender) { TRect Recto(20.//DT_LEFT. Recto.strlen(cad).&Recto.

void __fastcall FormPaint(TObject *Sender). private: // User declarations POINT Puntos[1000]. 8 . la cual cuenta con un campo para la posición X y otro para Y. // Matriz para mantener la posición de 1000 puntos int Contador. Además se hace uso de la estructura POINT. arco. Cree una nueva aplicación. // Punto medio del área de dibujo public: // User declarations __fastcall TForm1(TComponent* Owner).2 Primitivas de dibujo (línea.4. círculo. colores.H.2. agregue en su parte private las siguientes declaraciones: class TForm1 : public TForm { __published: // IDE-managed Components TTimer *Reloj. imágenes). void __fastcall RelojTimer(TObject *Sender). }. En su archivo . donde esta la definición de la clase TForm1. rellenos. // Contador general para la matriz anterior int MediaX. MediaY. El siguiente programa desplaza píxeles hacia el centro de la pantalla. Ejemplo 2 : Píxeles en movimiento.

Puntos[Contador].x][Puntos[Contador].x = random(ClientWidth).x > MediaX)*-1. } //--------------------------------------------------------------------------void __fastcall TForm1::Timer1Timer(TObject *Sender) { for (int N = 0. } Contador = 0.y = random(ClientHeight).y > MediaY)*-1. N++) {// Desplazar 100 puntos en cada ciclo.x][Puntos[N]. Puntos[Contador].1000 // Desactivar el punto de su posición actual Canvas->Pixels[Puntos[Contador].y < MediaY)*1 + (Puntos[Contador].x += (Puntos[Contador].y] = clWhite. N++) { // Calcular los 1000 puntos Puntos[N].x = random(ClientWidth). // Y calcular el punto medio MediaY = ClientHeight / 2.y] = clBlack.y += (Puntos[Contador]. // Pasar al punto siguiente // O al primero si ya se han recorrido todos if (Contador == 1000) Contador = 0. } // Mostrarlo en la nueva posición Canvas->Pixels[Puntos[Contador]. // Calcular su nueva posición Puntos[Contador]. N < 1000.x][Puntos[Contador]. probar en vez de 100 . // Inicializar el contador MediaX = ClientWidth / 2. Canvas->Pixels[Puntos[N].Agregue un componente Timer en la forma y escriba el siguiente código en sus métodos correspondientes. Contador++. N < 100.x < MediaX)*1 + (Puntos[Contador].y = random(ClientHeight).y == MediaY) { // Reapareciendo en un punto aleatorio Puntos[Contador].y] = clRed. } } 9 . // de forma aleatoria Puntos[N]. void __fastcall TForm1::FormPaint(TObject *Sender) { for(int N = 0. // Si el punto está en el centro del área debe desaparecer if (Puntos[Contador].//Black.x == MediaX && Puntos[Contador].

Ejemplo 3: Efecto con lineas: El siguiente programa se genera utilizando el trazo de líneas y aprovechando el escalonamiento que se produce en el trazo de las mismas se obtiene la siguiente salida: Cree una nueva aplicación y agregue el siguiente código en los métodos correspondientes : 10 .

CentroY). 0).//psDash. Canvas->LineTo(0.//psDashDotDot. Contador). // Incrementar el contador } } //--------------------------------------------------------------------------void __fastcall TForm1::FormResize(TObject *Sender) { //Si la forma se redimensiona actualizar todo //a sus nuevas dimensiones Invalidate(). // Recorrer toda la anchura del área de dibujo while (Contador < ClientWidth) { // Trazando líneas desde el centro // hasta los bordes superior e inferior Canvas->MoveTo(CentroX. Canvas->LineTo(Contador. Canvas->LineTo(Contador.. Contador += 4. Contador). ClientHeight). Contador += 4. CentroY. Canvas->MoveTo(CentroX.//psDashDot. // Calcular el centro del área de dibujo CentroX = ClientWidth / 2. CentroY). Canvas->MoveTo(CentroX.void __fastcall TForm1::FormPaint(TObject *Sender) { int CentroX.//psDot. } 11 . // Incrementar el contador } Contador = 0. // Contador de nuevo a cero // Para recorrer la altura del área de dibujo while (Contador < ClientHeight) { // Trazando líneas desde el centro // hasta los bordes izquierdo y derecho Canvas->MoveTo(CentroX. // Líneas con trazo discontinuo Canvas->Pen->Style = psSolid. CentroY). CentroY = ClientHeight / 2. CentroY). Contador = 0. Canvas->LineTo(ClientWidth.

12 . la cual nos permite modificar la salida de los textos que escribimos en la forma.Ejemplo 4: Escribir texto con ángulo de rotación Windows cuenta con una estructura LOGFONT. Además realice modificaciones para observar el resultado. Consulte en la ayuda en línea (Presione F1 sobre LOGFONT) para conocer más acerca del funcionamiento de la misma. En evento OnClick del Botón “Mostrar Texto” escriba el siguiente código.

//45*10.lfOrientation = 45*10. //Creamos un font logico con las caracteristicas especificadas en la //Estructura LOGFONT //Consultar en la ayuda LOGFONT para conocer su definición Canvas->Font->Handle = CreateFontIndirect(&lgfont). GM_ADVANCED). //Propiedades que nos permiten modificar la orientación de la salida del Texto lgfont.void __fastcall TForm1::Button1Click(TObject *Sender) { //Canvas->Font->Color = clBlue. //Angulo *10 lgfont. De La Laguna". String text = "Tec. //Nombre del // Font //Declaramos una variable LOGFONT LOGFONT lgfont. //Tamaño del Font Canvas->Font->Name = "SimSun". //Angulo *10 lgfont.//"Tahoma".310.//45*10. text). Canvas->Font->Size = 30. SetGraphicsMode(Canvas->Handle.//0. } //Dibujamos el Texto 13 .lfOutPrecision = OUT_TT_ONLY_PRECIS. sizeof(LOGFONT).lfEscapement = 45*10.//-900.//"Times Roman". Canvas->TextOut(0. GetObject(Canvas->Font->Handle.//-900.//0. &lgfont).

Además los estilos de brocha y pluma disponibles. Arco. Trazo de lineas. Elipse. Modificando el color y estilo de la pluma. 14 . Pie.Ejemplo 5: Objetos Gráficos. En este ejemplo se muestran los objetos gráficos más comunes como: Rectángulo. Modificando el color y estilo de la brocha.

-Diagonal Izq.En la forma coloque los siguiente: Componente Panel Label1 ComboBox1 Propiedad Caption Color Caption Text Ítems Asignar Cadena vacia clTeal Objeto Gráfico Borrar texto -Linea -Rectangulo -Rectangulo Redondeado -Elipse -Circulo -Pie -Arco Brocha Estilo Borrar texto -Solido -Transparente . Pluma Estilo Borrar Texto -Solido -Dash -Dot -DashDot -DashDotDot -Clear -InsideFrame Color Color Dibujarlo Dibujarlo ----------15 Label2 Label3 ComboBox2 Caption Caption Text Ítems Label4 Label5 ComboBox3 Caption Caption Text Ítems Label6 Label7 SpeedButon1 SpeedButton2 Color Dialog1 Caption Caption Glyph Glyph ------ .Horizontal -Vertical -Diagonal Der. -Cuadricula -Cuadricula Diag.

case 3: Canvas->Ellipse(250.200).450.//Arco break.100.100).450.200.10. case 6: Canvas->Arc(250.450. case 2: Canvas->RoundRect(250. 16 . case 3: Canvas->Brush->Style = bsVertical. case 2: Canvas->Brush->Style = bsHorizontal.100).100.450.50. case 6: Canvas->Brush->Style = bsCross.//Rectangulo Redondeado break. case 5: Canvas->Brush->Style = bsBDiagonal. break. break.450.//Rectangulo break. case 1: Canvas->Brush->Style = bsClear.Codificación de los componentes: void __fastcall TForm1::ComboBox1Change(TObject *Sender) { Repaint(). break.100). break. break.250).420.350.250.200.//Elipse break.//Pie break.//Circulo break.100.100.10). case 4: Canvas->Brush->Style = bsFDiagonal.450.450. case 4: Canvas->Ellipse(250.200).//Linea break.180. Canvas->LineTo(300. case 1: Canvas->Rectangle(250. case 5: Canvas->Pie(250. } } //--------------------------------------------------------------------------void __fastcall TForm1::ComboBox2Change(TObject *Sender) { switch(ComboBox2->ItemIndex) { case 0: Canvas->Brush->Style = bsSolid.200). switch(ComboBox1->ItemIndex) { case 0: Canvas->MoveTo(100.350.50. break.50.

break. } //--------------------------------------------------------------------------- 17 . break. break. case 3: Canvas->Pen->Style = psDashDot. break. case 1: Canvas->Pen->Style = psDash. case 6: Canvas->Pen->Style = psInsideFrame. break. break.break. case 7: Canvas->Brush->Style = bsDiagCross. case 5: Canvas->Pen->Style = psClear. break. } //--------------------------------------------------------------------------void __fastcall TForm1::SpeedButton2Click(TObject *Sender) { if(ColorDialog1->Execute()) Canvas->Pen->Color = ColorDialog1->Color. case 2: Canvas->Pen->Style = psDot. case 4: Canvas->Pen->Style = psDashDotDot. break. } } //--------------------------------------------------------------------------void __fastcall TForm1::SpeedButton1Click(TObject *Sender) { if(ColorDialog1->Execute()) Canvas->Brush->Color = ColorDialog1->Color. } } void __fastcall TForm1::ComboBox3Change(TObject *Sender) { switch(ComboBox3->ItemIndex) { case 0: Canvas->Pen->Style = psSolid.

- Diseñe sus dibujos (10) en el programa Paint. colóquelos en la carpeta donde guarde su proyecto o indique el path. TShiftState Shift.bmp. private: Graphics::TBitmap *ImageObject[10].Escriba el código que se muestra a continuación en su correspondiente evento. este componente será el que controlará el comportamiento de nuestro proyecto. 18 .Ejemplo 6 : Diseño de un ScreenSaver Este ejemplo muestra de una forma simple la creación de un protector de pantalla. // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner). en el cual se dibujan de forma aleatoria figuras que están contenidas en archivos . . guárdelos como mapa de bits (. void __fastcall FormMouseMove(TObject *Sender.Coloque un Timer sobre la forma. char &Key).Modifique la propiedad WindowState de la forma : wsMaximized BorderStyle : bsNone . }. Para llevar a cabo lo anterior usaremos un arreglo de objetos de tipo TBitmap. . void __fastcall Timer1Timer(TObject *Sender). int X. void __fastcall FormKeyPress(TObject *Sender. void __fastcall FormCreate(TObject *Sender). el cual lo declararemos en la clase TForm1 en su parte private (ver código). int Y).bmp). class TForm1 : public TForm { __published: // IDE-managed Components TTimer *Timer1.

ImageObject[4]->Transparent = True. //--------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { ImageObject[0] = new Graphics::TBitmap.bmp"). ImageObject[9] = new Graphics::TBitmap. ImageObject[8]->Transparent = True. ImageObject[5]->Transparent = True. ImageObject[2]->LoadFromFile("Image3.bmp"). ImageObject[2]->Transparent = True. ImageObject[random(10)]). ImageObject[3] = new Graphics::TBitmap.bmp"). ImageObject[6]->Transparent = True.bmp"). y-60.bmp"). ImageObject[4] = new Graphics::TBitmap.bmp"). ImageObject[1] = new Graphics::TBitmap. Canvas->Draw(x-60. int y = random(Height).TForm1 *Form1. ImageObject[0]->Transparent = True. ImageObject[1]->Transparent = True. ImageObject[8]->LoadFromFile("Image9. ImageObject[6]->LoadFromFile("Image7. ImageObject[4]->LoadFromFile("Image5. ImageObject[9]->LoadFromFile("Image10.bmp"). } //--------------------------------------------------------------------------void __fastcall TForm1::Timer1Timer(TObject *Sender) { int x = random(Width). } 19 . ImageObject[3]->Transparent = True. ImageObject[2] = new Graphics::TBitmap. ImageObject[5] = new Graphics::TBitmap.bmp"). ImageObject[1]->LoadFromFile("Image2. ImageObject[8] = new Graphics::TBitmap. ImageObject[0]->LoadFromFile("Image1. ImageObject[7]->LoadFromFile("Image8. ImageObject[7]->Transparent = True. ImageObject[7] = new Graphics::TBitmap. ImageObject[5]->LoadFromFile("Image6.bmp").bmp"). ImageObject[6] = new Graphics::TBitmap. ImageObject[3]->LoadFromFile("Image4. ImageObject[9]->Transparent = True.

} //--------------------------------------------------------------------------void __fastcall TForm1::FormMouseMove(TObject *Sender. int Y) { static int MoveCounter = 0. MoveCounter++.void __fastcall TForm1::FormCreate(TObject *Sender) { ShowCursor(FALSE). } 20 . TShiftState Shift. int X. } //--------------------------------------------------------------------------void __fastcall TForm1::FormKeyPress(TObject *Sender. if( MoveCounter >= 15 ) Close(). char &Key) { Close().

Sign up to vote on this title
UsefulNot useful