Compartir a través de


Optimizar el gráfico de Control

Cuando un control se indica para dibujarse a sí mismo en un contexto contenedor-proporcionado de dispositivo, selecciona normalmente los objetos GDI (como lápices, pinceles, y proporciona) en el contexto de dispositivo, realiza las operaciones de dibujo, y restaura los objetos anteriores de GDI.Si el contenedor tiene varios controles que deben ser dibujados dentro del mismo contexto de dispositivo, y cada control selecciona los objetos GDI que requiere, tiempo puede guardarse si los controles no restablece individualmente objetos seleccionada anteriormente.Después de que todos los controles se hayan dibujado, el contenedor automáticamente pueden restaurar los objetos originales.

Para detectar si un contenedor admite esta técnica, un control puede llamar a la función miembro de COleControl::IsOptimizedDraw .Si esta función devuelve TRUE, el control puede omitir el paso normal de restaurar los objetos seleccionada anteriormente.

Considere un control con la función (no optimizado) siguiente de OnDraw :

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   CBrush brush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&pen);
   CBrush* pBrushSave = pdc->SelectObject(&brush);
   pdc->Rectangle(rcBounds);
   pdc->SelectObject(pPenSave);
   pdc->SelectObject(pBrushSave);
}

El lápiz y el pincel de este ejemplo son variables locales, lo que significa que los destructores se llamará cuando salen del ámbito (cuando finaliza la función de OnDraw ).Los destructores intentará eliminar los objetos correspondientes de GDI.Pero no deben eliminarse si piensa dejarlos seleccionado en el contexto de dispositivo sobre volver de OnDraw.

Para evitar que los objetos de CPen y de CBrush son destruidos cuando OnDraw finaliza, almacénelos en variables miembro en lugar de variables locales.En la declaración de clase del control, agregue las declaraciones de dos nuevas variables miembro:

class CMyAxOptCtrl : public COleControl
{


...


   CPen m_pen;
   CBrush m_brush;
};

A continuación, la función de OnDraw puede ser reescrita como sigue:

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   CBrush brush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&pen);
   CBrush* pBrushSave = pdc->SelectObject(&brush);
   pdc->Rectangle(rcBounds);
   pdc->SelectObject(pPenSave);
   pdc->SelectObject(pBrushSave);
}

Este método evita la creación del lápiz y de pincel cada vez que se llama a OnDraw .La mejora de la velocidad procede a costa de mantener datos adicionales de la instancia.

Si los cambios de ForeColor o la propiedad BackColor, el lápiz o el pincel necesita crearse de nuevo.Para ello, reemplace OnForeColorChanged y el miembro de OnBackColorChanged funciona:

void CMyAxOptCtrl::OnForeColorChanged()
{
   m_pen.DeleteObject();
}

void CMyAxOptCtrl::OnBackColorChanged()
{
   m_brush.DeleteObject();
}

Finalmente, eliminar las llamadas innecesarias de SelectObject , modifique OnDraw como sigue:

void CMyAxOptCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (m_pen.m_hObject == NULL)
      m_pen.CreatePen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   if (m_brush.m_hObject == NULL)
      m_brush.CreateSolidBrush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&m_pen);
   CBrush* pBrushSave = pdc->SelectObject(&m_brush);
   pdc->Rectangle(rcBounds);
   if (! IsOptimizedDraw())
   {
      pdc->SelectObject(pPenSave);
      pdc->SelectObject(pBrushSave);
   }
}

Vea también

Referencia

COleControl (Clase)

Asistente para controles ActiveX MFC

Conceptos

Controles ActiveX de MFC: optimización

Controles ActiveX de MFC

Controles ActiveX de MFC

Controles ActiveX de MFC: Representación de un control ActiveX