Compartir a través de


Cambiar el código de dibujo (Tutorial de ATL, Parte 4)

De forma predeterminada, el código de dibujo del control muestra un cuadrado y el texto PolyCtl. En este paso, cambiará el código para mostrar algo más interesante. Las siguientes tareas relacionadas:

  • Modificar el archivo de encabezado

  • Modificar la función de OnDraw

  • Agregar un método para calcular los puntos Polygon

  • Inicializar el color de relleno

Modificar el archivo de encabezado

El inicio agregando compatibilidad para las funciones matemáticas sin y cos, que se utilizarán calcula los puntos del polígono, y creando una matriz para almacenar posiciones.

Para modificar el archivo de encabezado

  1. Agregue la línea #include <math.h> a la parte superior de PolyCtl.h. La parte superior del archivo debe ser similar a:

    #include <math.h>
    #include "resource.h"        // main symbols
    
  2. Una vez que se calculan los puntos del polígono, se almacenan en una matriz de POINTescrito, así que agregue la matriz después de la definición de m_nSides en PolyCtl.h:

    POINT m_arrPoint[100];
    

Modificar el método de OnDraw

Ahora debe modificar el método de OnDraw en PolyCtl.h. El código que creará un nuevo lápiz y el pincel con el que para dibujar el polígono, y después llama a Ellipse y la API Win32 de Polygon funciona para realizar el dibujo real.

Para modificar la función de OnDraw

  • Reemplace el método existente de OnDraw en PolyCtl.h con el código siguiente:

    HRESULT CPolyCtl::OnDraw(ATL_DRAWINFO& di)
    {
       RECT& rc = *(RECT*)di.prcBounds;
       HDC hdc  = di.hdcDraw;
    
       COLORREF    colFore;
       HBRUSH      hOldBrush, hBrush;
       HPEN        hOldPen, hPen;
    
       // Translate m_colFore into a COLORREF type
       OleTranslateColor(m_clrFillColor, NULL, &colFore);
    
       // Create and select the colors to draw the circle
       hPen = (HPEN)GetStockObject(BLACK_PEN);
       hOldPen = (HPEN)SelectObject(hdc, hPen);
       hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
       hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
    
       Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom);
    
       // Create and select the brush that will be used to fill the polygon
       hBrush    = CreateSolidBrush(colFore);
       SelectObject(hdc, hBrush);
    
       CalcPoints(rc);
       Polygon(hdc, &m_arrPoint[0], m_nSides);
    
       // Select back the old pen and brush and delete the brush we created
       SelectObject(hdc, hOldPen);
       SelectObject(hdc, hOldBrush);
       DeleteObject(hBrush);
    
       return S_OK;
    }
    

Agregar un método para calcular los puntos Polygon

Agregue un método, denominado CalcPoints, que calculará las coordenadas de puntos que componen el borde del polígono. Estos cálculos se basan en la variable RECT que se pasa a la función.

Para agregar el método de CalcPoints

  1. Agregue la declaración de CalcPoints a la sección pública de IPolyCtl de la clase de CPolyCtl en PolyCtl.h:

    void CalcPoints(const RECT& rc);
    

    La última parte de la sección public de la clase de CPolyCtl será similar a:

       void FinalRelease()
       {
       }
    public:
       STDMETHOD(get_Sides)(short* pVal);
       STDMETHOD(put_Sides)(short newVal);
       void CalcPoints(const RECT& rc);
    
  2. Agregue esta implementación de la función de CalcPoints al final de PolyCtl.cpp:

    void CPolyCtl::CalcPoints(const RECT& rc)
    {
       const double pi = 3.14159265358979;
       POINT   ptCenter;
       double  dblRadiusx = (rc.right - rc.left) / 2;
       double  dblRadiusy = (rc.bottom - rc.top) / 2;
       double  dblAngle = 3 * pi / 2;          // Start at the top 
       double  dblDiff  = 2 * pi / m_nSides;   // Angle each side will make
       ptCenter.x = (rc.left + rc.right) / 2;
       ptCenter.y = (rc.top + rc.bottom) / 2;
    
       // Calculate the points for each side 
       for (int i = 0; i < m_nSides; i++)
       {
          m_arrPoint[i].x = (long)(dblRadiusx * cos(dblAngle) + ptCenter.x + 0.5);
          m_arrPoint[i].y = (long)(dblRadiusy * sin(dblAngle) + ptCenter.y + 0.5);
          dblAngle += dblDiff;
       }
    }
    

Inicializar el color de relleno

Inicializa m_clrFillColor con el color predeterminado.

Para inicializar el color de relleno

  • Utilice el verde como color predeterminado agregando esta línea al constructor de CPolyCtl en PolyCtl.h:

    m_clrFillColor = RGB(0, 0xFF, 0);
    

El constructor ahora tiene este aspecto:

CPolyCtl()
{
   m_nSides = 3;
   m_clrFillColor = RGB(0, 0xFF, 0);
}

Compilar y probar el Control

Recompile el control. Asegúrese de que el archivo PolyCtl.htm cerrado si todavía está abierto, y después haga clic en Compilar polígono en el menú de Compilación . Puede ver el control de nuevo de la página de PolyCtl.htm, pero este uso de nuevo el ActiveX control test container.

Para utilizar el ActiveX control test container

  1. Compilar e inicie el contenedor del control ActiveX. Para obtener más información, vea Ejemplo TSTCON: ActiveX control test container.

  2. En contenedor de prueba, en el menú de Editar , haga clic Nueva Control INSERT.

  3. Busque el control, que se llama PolyCtl Class, y haga clic Aceptar. Verá un triángulo verde dentro de un círculo.

Pruebe a cambiar el número de lados siguiendo el procedimiento siguiente. Modificar propiedades de una interfaz dual dentro del contenedor de prueba, utilice Invoke Methods.

Para modificar la propiedad de un control dentro del contenedor de prueba

  1. En contenedor de prueba, haga clic en Invocar métodos en el menú de Control .

    Aparecerá el cuadro de diálogo Invocar método .

  2. Seleccione la versión de PropPut de la propiedad de Sides de cuadro de lista desplegable de Nombre del método .

  3. Escriba 5 en el cuadro de Valor del parámetro , haga clic en Establecer valor, y haga clic en Invocar.

Observe que el control no cambia. Aunque ha modificado el número de lados internamente estableciendo la variable de m_nSides , no ejecutó el control para que vuelva a. Si cambia a otra aplicación y vuelve al contenedor de prueba, verá que el control ha repintado y tiene el número correcto de lados.

Para corregir este problema, agregue una llamada a la función de FireViewChange , definida en IViewObjectExImpl, después de establecer el número de lados. Si el control se ejecuta en su propia ventana, FireViewChange llamará al método de InvalidateRect directamente. Si el control se ejecuta sin ventana, el método de InvalidateRect se en la interfaz del sitio del contenedor. Esto obliga al control para representar.

Para agregar una llamada a FireViewChange

  • Actualice PolyCtl.cpp si la llamada a FireViewChange al método de put_Sides . Cuando haya finalizado, el método de put_Sides debe ser similar a:

    STDMETHODIMP CPolyCtl::put_Sides(short newVal)
    {
       if (2 < newVal && newVal < 101)
       {
          m_nSides = newVal;
          FireViewChange();
          return S_OK;
       }
       else
       {
          return Error(_T("Shape must have between 3 and 100 sides"));
       }
    }
    

Después de agregar FireViewChange, recompile y pruebe el control de nuevo en el contenedor de prueba del control ActiveX. Esta vez cuando cambia el número de lados y haga clic en Invoke, debería ver el cambio de control inmediatamente.

En el paso siguiente, agregará un evento.

De nuevo al paso 3 | En el paso 5

Vea también

Tareas

Probar propiedades y eventos con un contenedor de prueba

Referencia

Tutorial de Active Template Library (ATL)