Paso 4: Cambiar el código de dibujo

En el código de dibujo que se utiliza las funciones del pecado y cos para calcular los puntos del polígono, así que agregue incluyen math.h en la parte superior de PolyCtl.h:

# include lt;math.h >
# include "resource.h" / / principales símbolos

&Nota de despacho construye sólonbsp;  Cuando el Asistente para aplicaciones de ATL COM genera el proyecto predeterminado, define la macro _ATL_MIN_CRT. Esta macro se define para que no ponga la biblioteca de tiempo de ejecución de c en el código si no lo necesita. El control de polígono necesita el código de puesta en marcha de la biblioteca de tiempo de ejecución de c para inicializar las funciones de punto flotante. Por lo tanto, necesita eliminar la macro _ATL_MIN_CRT y si desea crear una versión de lanzamiento. Para quitar la macro, haga clic en configuración en el menú proyecto . En la para la configuración: desplegable lista, elija Varias configuraciones. Seleccione configuraciones de proyecto para modificar cuadro de diálogo que aparece, haga clic en las casillas de verificación para todas las versiones de lanzamiento cuatro y, a continuación, haga clic en Aceptar. En la ficha de C o C++ , elija la categoría General y, a continuación, quite el cuadro de edición de definiciones del preprocesador _ATL_MIN_CRT.

Una vez que se calculan los puntos del polígono, almacenar los puntos mediante la adición de una matriz de tipo punto al final de la definición de clase en PolyCtl.h:

   OLE_COLOR m_clrFillColor;
   m_nSides corto;
   PUNTO m_arrPoint [100]

Ahora cambiar la OnDraw función en PolyCtl.h para que coincida con el siguiente. Tenga en cuenta que eliminar las llamadas a las funciones de rectángulo y DrawText. También explícitamente debe obtener y seleccionar un lápiz negro y blanco pincel. Es necesario hacerlo en caso de que el control se ejecuta sin ventanas. Si no dispone de su propia ventana, no puede hacer suposiciones sobre el contexto de dispositivo que se va dibujando.

El terminar OnDraw parece esto:

HRESULT CPolyCtl::OnDraw(ATL_DRAWINFOamp; di)
{
   RECT & rc = *(RECT*)di.prcBounds;
   HDC hdc = di.hdcDraw;

COLORREF colFore;
   HBRUSH hOldBrush, hBrush;
   HPEN hOldPen, hPen;

/ / M_colFore se traducen en un tipo COLORREF
   OleTranslateColor (m_clrFillColor, NULL & colFore);

/ / Crear y seleccionar los colores para dibujar el círculo
   hPen = (HPEN)GetStockObject(BLACK_PEN);
   hOldPen = SelectObject (HPEN) (hdc, hPen);
   hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
   hOldBrush = SelectObject (HBRUSH) (hdc, hBrush);

Elipse (hdc, rc.left, rc.top, rc.right, rc.bottom);

/ / Crear y seleccione el pincel que se utilizará para rellenar el polígono
   hBrush = CreateSolidBrush(colFore);
   SelectObject (hdc, hBrush);

CalcPoints(rc);
   Polígono (hdc & m_arrPoint [0], m_nSides);

Y seleccione copia de la vieja pluma y pincel y elimina el pincel que hemos creado
   SelectObject (hdc, hOldPen);
   SelectObject (hdc, hOldBrush);
   DeleteObject(hBrush);

Devuelve S_OK;
}

Ahora &necesita agregar una función, llamada CalcPoints , que calculan las coordenadas de la línea intersections.nbsp; Estos cálculos se basará en la variable RECT que se pasa a la función.  Primero debe agregar la definición de CalcPoints a la sección pública de la clase de IPolyCtl en PolyCtl.h:

voidnbsp;   CalcPoints (RECT const & rc)

La sección pública de la clase de IPolyCtl debe ahora este aspecto:

/ / IPolyCtl
público:
   STDMETHOD(get_Sides) (/ * [out, retval] * / corto * Nuevo_valor);
   STDMETHOD(put_Sides) (/ * [en] * / corto Nuevo_valor);
   voidnbsp;   CalcPoints (RECT const & rc)

A continuación, agregue la aplicación de la CalcPoints función hasta el final del archivo PolyCtl.cpp:

void CPolyCtl::CalcPoints (const RECTamp; rc)
{
   const pi doble = 3.14159265358979;
   PUNTO ptCenter;
   doble dblRadiusx = (rc.right - rc.left) / 2;
   doble dblRadiusy = (rc.bottom - rc.top) / 2;
   doble dblAngle = 3 * pi / 2;          / / Inicio en la parte superior
   doble dblDiff = 2 * pi / m_nSides;   / / Cada ángulo lateral hará
   ptCenter.x = (rc.left + rc.right) / 2;
   ptCenter.y = (rc.top + rc.bottom) / 2;

/ / Calcular los puntos de cada lado
   para (int i = 0; i < m_nSides; i ++)
   {
      m_arrPoint [i] .x = (largo) (dblRadiusx * cos(dblAngle) + ptCenter.x + 0.5);
      m_arrPoint [i] .y = (largo) (dblRadiusy * sin(dblAngle) + ptCenter.y + 0.5);
      dblAngle += dblDiff;
   }
}

Ahora, inicializar m_clrFillColor . Elija verde como el color por defecto y añada esta línea a la CPolyCtl constructor en PolyCtl.h:

   m_clrFillColor = RGB (0, 0xFF, 0)

El constructor ahora este aspecto:

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

Ahora reconstruir el control y vuelva a intentarlo. Abra ActiveX Control Test Container e insertar el control. Debería ver un triángulo verde dentro de un círculo. Intente cambiar el número de lados por los siguientes pasos. Para modificar las propiedades de una interfaz dual de contenedor de prueba, utilice Invocar métodos:

  1. En Test Container, haga clic en Invocar métodos en el menú Control .
    Aparece el cuadro de diálogo de Invocar el método.

  2. Haga clic en la versión PropPut de la propiedad de partes del Nombre del método.

  3. Escriba 5 en el cuadro de edición del Valor del parámetro , haga clic en Establecer valor y haga clic en invocar.

Observe que el control no cambia. ¿Qué pasa? Aunque ha cambiado el número de lados internamente mediante el establecimiento de la m_nSides variable, no provocar el control para repintar. Si cambia a otra aplicación y vuelva a Test Container , encontrará el control se repinta y ahora tiene el número correcto de lados.

Para corregir este problema, debe añadir una llamada a la función FireViewChange , que se define en IViewObjectExImpl, después de establecer el número de lados. Si el control se ejecuta en su propia ventana, FireViewChange llamará directamente la InvalidateRect API. Si el control se ejecuta sin ventanas, se llamará al método InvalidateRect en la interfaz del sitio del contenedor. Esto hace que el control para repintar sí.

El nuevo put_Sides método es el siguiente:

STDMETHODIMP CPolyCtl::put_Sides(short newVal)
{
   Si (newVal gt; 2 & & Nuevo_valor < 101)
   {
      m_nSides = Nuevo_valor;
      FireViewChange();
      Devuelve S_OK;
   }
   otra cosa
      devolver Error (_T ("forma debe tener entre 3 y 100 partes"));
}

Después de que haya agregado FireViewChange, reconstruir e inténtelo de nuevo el control. Esta vez cuando cambia el número de lados y haga clic en invocar, debería ver el control cambiar inmediatamente.

A continuación, agregará un evento para el control.

Con el paso 3 |nbsp; Con el paso 5

Index