PDF de programación - Apunte de VC++ - Capítulo X

Imágen de pdf Apunte de VC++ - Capítulo X

Apunte de VC++ - Capítulo Xgráfica de visualizaciones

Actualizado el 21 de Marzo del 2018 (Publicado el 5 de Febrero del 2018)
282 visualizaciones desde el 5 de Febrero del 2018
334,7 KB
7 paginas
Creado hace 3a (21/11/2016)
Apunte de Visual C++

 

Por: Demian Panello        demianpanello@yahoo.com.ar
     
Capítulo X
Indice rápido del capítulo 10:

La clase CPaintDC.
El mensaje WM_PAINT.
Repintar sólo una región.
Estructura RECT.
Estructura PAINTSTRUCT.
Lápices, (la clase CPen).
Cómo crear un lápiz.
La clase CPoint.
Funciones CreatePen() y SelectObject().
Funciones MoveTo() y LineTo().
Cómo generar números aleatorios, (la función rand()).
Pinceles, (la clase CBrush).
Funciones CreateSolidBrush(), GetClientRect() y FillRect().

 

DIBUJAR Y REDIBUJAR (la clase CPaintDC, el mensaje WM_PAINT):
 
La clase CPaintDC es un contexto de dispositivo especial, derivada de CDC, que sirve de ayuda para manejar el mensaje WM_PAINT procedente de Windows. El
mensaje WM_PAINT se envía a las ventanas cuando dejan de estar cubiertas totalmente o en parte por otra ventana; indica que la aplicación debe redibujar la región
descubierta.
En lugar de volver a pintar toda la ventana cada vez que se descubre alguna parte, WM_PAINT nos pasa un rectángulo con las coordenadas del pedacito descubierto.
Entonces se puede emplear esta información para volver a dibujar solamente la parte afectada.
 
Para ver esto crearemos un proyecto MFC, basado en diálogos llamado “graf3”.
 
Realice las misma modificaciones al diálogo igual que en el ejemplo del capítulo anterior; esto es cambie el botón Cancelar por Dibujar con ID=IDC_DIBUJAR.
 
El código que vamos a escribir será muy similar al escrito en el ejemplo anterior, pero en principio no lo escribiremos directamente en el evento OnDibujar de botón
Dibujar, sino que crearemos una función que luego llamaremos al pulsar el botón y además en el evento OnPaint, para manejar el mensaje WM_PAINT.
 
Para crear la función en ClassView pulse con el botón derecho sobre la clase CGraf3Dlg y seleccione del menú contextual la opción Add Member Function, luego en
Function Type escriba void y en Function Declaration escriba Dibujar. Pulse OK y se editará la función, allí escriba:
 

void CGraf3Dlg::Dibujar()

{

            CPaintDC paintDC(this);  (1)       //DC para pintar sobre el diálogo.

            RECT *pRect;            (2)                   //Puntero a la clase RECT para almacenar

                                                                                    //los puntos de la región a redibujar.

            int x,y;

//Se asocia el puntero pRect a la variable m_ps, miembro

            //de CPaintDC, que tiene las coordenadas de la región.

            pRect=&paintDC.m_ps.rcPaint;             (3)  

            //Se recorre para pintar, unicamente la región descubierta.

            for (x=pRect­>left; x<pRect­>right; x++)

                        for (y=pRect­>top; y<pRect­>bottom; y++)

                                    paintDC.SetPixel(x,y,RGB(x*y,0,0));

}
 
 
Bien, en primero lugar se declara una variable objeto CPaintDC para pintar sobre el diálogo (1).
En (2) se  declara  una  variable  de  tipo  RECT,  (también  existe  una  clase  CRect),  para  almacenar  los  puntos  de  la  región  a  redibujar.  RECT  es  una  estructura
predefinida en VC cuyos campos son:
 

typedef struct tagRECT {   LONG left;   LONG top;   LONG right;   LONG bottom;} RECT;

 
left – indica la coordenada x del punto superior izquierdo.
top – indica la coordenada y del punto superior izquierdo.
right – indica la coordenada x del punto inferior izquierdo.
bottom – indica la coordenada y del punto inferior izquierdo.
 
Lo siguiente a hacer es cargar la estructura pRect con los puntos de la región, (rectángulo), a redibujar; esto se hace en la línea (3) ya que en el mismo objeto
CPaintDC creado existe una variable miembro pública llamada m_ps de tipo PAINTSTRUCT que contiene información que le sirve a la aplicación para pintar un
área cliente de un diálogo, (ventana), asociado con un objeto CPaintDC. Una estructura PAINTSTRUCT contiene los siguientes campos:
 
typedef struct tagPAINTSTRUCT {   HDC  hdc;   BOOL fErase;   RECT rcPaint;   BOOL fRestore;   BOOL fIncUpdate;   BYTE rgbReserved[16];} PAINTSTRUCT
 
hdc – identifica el dispositivo de contexto usado para pintar.
fErase – especifica si el fondo de la ventana necesita redibujarse. Si es distinto de 0, es porque la aplicación debería redibujar el fondo.
rcPaint – especifica las esquinas superior izquierda e inferior derecha del rectángulo que necesita ser redibujado. Este es el campo que usamos en la línea (3).
fRestore – campo reservado. Windows lo usa internamente.
fIncUpdate – campo reservado. Windows lo usa internamente.
rgbReserved[16] – bloque de memoria reservado que usa Windows internamente.
 
Lo que resta es recorrer el rectángulo pRect por medio de unos bucles y pintarlo nuevamente con la función SetPixel().
Esto es todo lo que respecta a la función Dibujar, ahora hay que llamarla desde el evento OnDibujar() y desde OnPaint(). Entonces pulse dos veces sobre el botón
Dibujar, aparece un aviso indicando que está por crear un manejador de mensajes llamado OnDibujar(), acepte el aviso y escriba:
 

void CGraf3Dlg::OnDibujar()

{

            // TODO: Add your control notification handler code here

            Dibujar();   //Aquí está la llamada a nuestra función.

}
Para escribir la llamada en OnPaint(), pulse dos veces en dicha función en el ClassView.

void CGraf3Dlg::OnPaint()

{

if (IsIconic())

            {

               CPaintDC dc(this); // device context for painting

                //Resumiendo un poco el código

    ....   

               // Draw the icon

              dc.DrawIcon(x, y, m_hIcon);

            }

            else

            {

                        Dibujar();        //Esta es la llamada.

                        CDialog::OnPaint();

            }

}
 
Ejecute la aplicación y obtendrá más o menos la siguiente salida:

 

 
Pruebe superponer ciertas zonas de la ventana con otra, (ejemplo la calculadora), y verá que cuanto más pequeña sea la zona que cubre y descubre más rápido será
repintada.
 
 

Resumiendo:

La clase CPaintDC es una clase derivada de CDC como contexto de dispositivo para pintar y permite capturar los mensajes BEGIN_PAINT y END_PAINT
(de WM_PAINT).
Los datos correspondientes a los vértices de la región a redibujar se pasan a una variable de tipo RECT igualandolá al campo rcPaint de la variable miembro
m_ps de tipo PAINTSTRUCT perteneciente a la clase CPaintDC. (pRect=&paintDC.m_ps.rcPaint;)
El evento OnPaint(), (mensaje WM_PAINT), es el lugar encargado de manipular todo el código referente a redibujar, repintar una ventana.

Descargar archivos fuentes del ejemplo: graf3.zip 

 

LÁPICES Y PINCELES (las clases CPen y CBrush):
 
El GDI de Windows proporciona además de cientos de funciones gráficas para dibujar líneas, círculos, elipses etc., herramientas con las cuales dibujarlas y pintarlas.
Estas herramientas son los lápices y los pinceles, las clases CPen y CBrush.
¿Cuándo usar lápices y/o pinceles?.
Bueno, si uno quiere, por ejemplo,  dibujar una línea roja de un cierto espesor debe usar un lápiz y especificarle que será de color rojo y que el trazo será de
determinado espesor.
Si se quiere pintar el interior de un circulo de color verde, se debe crear un pincel, (Brush), y especificarle tal color.
 
En la práctica, el método operativo consiste en definir una variables CPen para el nuevo lápiz y un puntero CPen para almacenar el lápiz actual, (esto siempre es
conveniente hacerlo, y debe ser un puntero la variable puesto que la función que permite guardar el lápiz retorna un puntero). Luego se crea el lápiz, (CreatePen()),
especificándole las características deseadas, (estilo, ancho, color); finalmente se guarda el lápiz actual y selecciona el nuevo, (estos dos pasos lo hace la función
SelectObject() de un saque).
 
El ejemplo con el que vamos a ver todo esto tendrá como objetivo que el usuario pueda dibujar líneas con sólo pulsar el botón izquierdo en un punto de la ventana y
luego en otro para que se realice el trazo entre ellos. Además cada línea que se dibuje tendrá un color aleatorio.
 

 
Se podrán dibujar cuantas líneas uno quiera y si se desea limpiar la ventana, (que desaparezcan todas las líneas) bastará con sólo pulsar el botón derecho.
Para ver el tema de los pinceles haremos que al hacer doble click con el botón izquierdo del mouse se pinte la ventana con un color aleatorio.
 
Cree, entonces, con el AppWizard un proyecto MFC basado en diálogos con el nombre “lineas”.
 
Análisis del programa:
 
En principio necesitamos agregar funciones para gestionar los mensajes WM_LBUTTONDOWN, WM_LBUTTONDBLCLK y WM_RBUTTONDOWN que
permitirán dibujar, pintar la ventana y limpiar. Así que agregue estas funciones siguiendo los pasos acostumbrados con el ClassWizard, (CTRL+W y agregar las
funciones).
Para poder realizar el trazo entre los puntos indicados por el usuario se necesitará una variable global que almacene el primer punto. Esta variable será de tipo
CPoint, la cual tiene dos campos miembros: x e y, donde almacenaremos las coordenadas. También necesitaremos otra variable global para poder detectar si es la
primera vez que se pulsa el mouse sobre la ventana y en consecuencia se guarda el punto y no se dibuja la línea.
Los primeros pasos entonces son:
 

­         Pulse CTRL+W para acceder a ClassWizard y agregue las funciones WM_LBUTTONDOWN, WM_LBUTTONDBLCLK  y

WM_RBUTTONDOWN a la clase CLineasDlg.

­         Pulse con el botón derecho del mouse sobre la clase CLineasDlg en ClassView y seleccione la opción Add member variable. Cree una llamada

ptoAnterior de tipo CPoint y otra llamada Primero de tipo BOOL.

­         Pulse dos veces sobre el constructor de la clase CLineasDlg, (el primer ítem al expandir la rama de la clase). Allí escriba: Primero = TRUE; (valor

inicial para la variable Primero).

 
Luego de estos primeros pasos estamos en condición de escribir el código correspondiente al mensaje WM_LBUTTONDOWN, el mismo que se encargará de
dibujar la línea.

Expanda la clase CLineasDlg en el ClassView y puls
  • Links de descarga
http://lwp-l.com/pdf8621

Comentarios de: Apunte de VC++ - Capítulo X (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad