NovaMonoFix
Errores PHP
X
Usuario
Password
0 FPS

Tutorial WINAPI C++ 1.4 (Entorno gráfico de windows GDI)

08 de Abril del 2010 por Josep Antoni Bover, 0 visitas, 0 comentarios, 0 votos
Categorías : Windows, Programación, C y C++.
La web está en segundo plano, animación en pausa.
Cargando animación...
Tutorial WINAPI C++ 1.4 (Entorno gráfico de windows GDI)

Con este tutorial empezaremos a tocar la parte grafica de las ventanas, cosa que nos servira mas adelante para moldear y pintar todos los controles de creacion propia a nuestro antojo.

En esencia vamos a ver como responder al mensaje WM_PAINT de windows, que es el encargado de avisarnos cuando una ventana necesita repintarse. Luego utilizaremos este mensaje para escribir una cadena de caracteres en la ventana, y pintar el fondo de toda la ventana utilizando un color aleatorio.

Aun recuerdo cuando hice un cursillo de programación básico, y mi profesor decía : hay 2 tipos de programadores en esencia, los que mueven datos, y los que mueven gráficos. Ahora le doy la razón, a pesar de que una aplicación no solo son gráficos o datos y siempre se requiere de las dos partes, y yo tengo una afición especial para añadir acabados gráficos que marquen la diferencia.

Supongo que más de uno recordara Windows 95/98/ME, con sus gráficos 100% rectangulares, pues os sorprendería ver la de aplicaciones con un acabado excelente bajo esos sistemas operativos, y no precisamente gracias a los controles estándar de windows. Yo personalmente tengo una serie de controles creados por mi que simulan gran parte de los controles estándar de windows con varias mejoras graficas y que además son perfectamente configurables en su apariencia. Actualmente con windows 7 y windows vista la cosa ha mejorado mucho en cuanto al aspecto grafico, pero no por ello tenemos que usar los controles por defecto del windows.

Bueno dejando de banda mi historial académico y versiones antiguas de windows, empezaremos a familiarizarnos con el GDI de windows. Windows esta hecho de tal forma que cuando necesita repintar algo, solo repinta lo que necesite cambios, es decir si minimizamos una ventana windows repintara la porción de la pantalla donde estaba esa ventana.

Pongamos por ejemplo una ventana con 4 controles dentro, y windows necesita repintar la mitad de la ventana, la cual solo contiene 2 controles. Que pasara? Windows mandara un mensaje WM_PAINT a la ventana indicando que esta debe repintarse, además windows mirara que controles están dentro de la región de repintado, y repetirá el mensaje WM_PAINT en los controles que queden dentro.

Para poder pintar cualquier cosa en windows necesitamos obtener el HDC de la ventana que queremos pintar. El HDC es una herramienta de windows para pintar gráficos, y está formado por varios objetos. Para empezar un HDC tiene un objeto HBITMAP, que es donde se almacenan los gráficos en esencia, también tiene un objeto HFONT que enlaza con la fuente seleccionada que se usa para pintar texto, un objeto HPEN que simboliza una pluma de un color para pintar líneas, un HBRUSH que simboliza una brocha para pintar regiones de un color, y otros objetos.

Desde un mensaje WM_PAINT para acceder al DC debemos usar las API's BeginPaint y EndPaint, ya que estas funciones están preparadas para pintar SOLO la porción que windows necesita. Dentro de la estructura PAINTSTRUCT podemos encontrar la región que se requiere pintar, o podemos ignorar esos datos y pintar todo el HDC, y dejar que windows pinte la porción que necesite (cosa que será más lenta pero más cómoda).

Archivo : PlantillaEventos.h
1
2
3
4
5
6
7
8
// Respuesta al evento pintar (con controles estandar no va bien...)
case WM_PAINT :
HDC DC;
PAINTSTRUCT ps;
DC = BeginPaint(_hWnd, &ps);
Ret = this->Evento_Pintar(DC, ps);
EndPaint(_hWnd, &ps);
return Ret;

Si por el contrario queremos acceder a un HDC para repintarlo nosotros mismos sin enviar el mensaje WM_PAINT, debemos utilizar las API's GetDC y ReleaseDC. Hay casos en los que podemos necesitar repintar nuestra ventana / control, por ejemplo si queremos hacer un efecto de resaltado cuando pasamos por encima con el mouse, debemos repintar la ventana una vez cuando el mouse esta dentro, y una vez cuando el mouse sale.

Archivo : Tutorial_GDI.cpp
1
2
3
4
5
6
// Función que obtiene el HDC de nuestra ventana y se lo pasa a la funcion Pintar, para repintar la ventana.
void RePintar(void) {
HDC hDC = GetDC(_hWnd);
Pintar(hDC);
ReleaseDC(_hWnd, hDC);
};

Bueno ahora ya hemos tomado contacto con el HDC sin pintar nada. Lo siguiente será crear la función Pintar para hacer un fondo de color aleatorio con un texto centrado de color blanco.

Archivo : Tutorial_GDI.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Función que pinta el fondo de un color aleatorio con un texto de color blanco
void Pintar(HDC hDC) {
COLORREF R = rand()%255;
COLORREF G = rand()%255;
COLORREF B = rand()%255;
HBRUSH Brocha = CreateSolidBrush(RGB(R, G, B));
RECT RC;
GetClientRect(_hWnd, &RC);
FillRect(hDC, &RC, Brocha);
SetTextColor(hDC, RGB(255, 255, 255));
SetBkColor(hDC, RGB(R, G, B));
DrawText(hDC, TEXT("Ejemplo 1.4 - Entorno gráfico de windows (GDI)"), -1, &RC, DT_CENTER);
DeleteObject(Brocha);
};

La función Pintar utiliza la API CreateSolidBrush para crear una brocha de color aleatorio, luego obtiene el ancho y alto de la ventana utilizando la API GetClientRect, pinta el fondo de la ventana de color negro con la API FillRect, asigna el color del texto a blanco con la API SetTextColor, asigna el color del fondo para el texto a negro con la API SetBkColor, pinta el texto "Hola Mundo" centrado en la ventana con la API DrawText, y borra la brocha de la memoria con la API DeleteObject.

Hay que destacar que la gran mayoría de objetos del GDI tienen una API para ser creados y otra para ser eliminados. Si utilizamos objetos que debamos crear nosotros, debemos recordar que dichos objetos deben ser destruidos cuando ya no sean necesarios, si nos olvidamos de borrar correctamente estos objetos llegara un punto en el que windows no podrá crear mas objetos y causara errores graficos.

Otra cosa a tener en cuenta es que podemos echar mano de algunos objetos GDI creados por el sistema operativo para sus operaciones rutinarias, de esta forma ahorraremos algo de memoria y tiempo de procesador, pero debemos recordar que dichos objetos no deben ser eliminados, ya que Windows los esta utilizando tambien. Para ello podemos utilizar las API GetSysColorBrush y GetStockObject entre otras.

Ahora que ya sabemos crear ventanas y utilizar básicamente el GDI de Windows es el momento ideal para empezar a crear nuestro primer control y asi poder aprender mas sobre el GDI haciendo algo util. Este control consistirá en un botón con los bordes redondeados el cual estará pintado con un degradado de fondo : 1.5 Creación de nuestro objeto Botón.

Descargar tutorial WinAPI completo Calculadora compilada