Partilhar via


Otimizando o desenho de controle

Quando um controle é instruído a desenhar próprio em um contexto de dispositivo fornecido pelo contêiner, ele normalmente seleciona objetos GDI (por exemplo, fontes, pincéis e canetas) no contexto de dispositivo, executa sistema autônomo operações de desenho e restaura sistema autônomo objetos GDI anteriores.Se o contêiner tem vários controles que devem ser desenhadas no mesmo contexto de dispositivo, e cada controle seleciona objetos GDI requer, time pode ser salvos se os controles não restauram objetos anteriormente selecionados individualmente.Depois que todos os controles foi emitidos, o contêiner automaticamente pode restauração os objetos originais.

Para detectar se um contêiner suporta essa técnica, um controle pode chamar o COleControl::IsOptimizedDrawfunção de membro .Se essa função retornar TRUE, o controle pode ignorar a etapa normal de restaurar os objetos anteriormente selecionados.

Considere a possibilidade de um controle que tem o seguinte (não otimizadas) OnDraw função:

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);
}

A caneta e Pincel neste exemplo são variáveis locais, que significa que os destruidores serão chamados quando eles estão fora do escopo (quando o OnDraw função termina). Os destruidores tentará excluir objetos GDI correspondentes.Mas eles não devem ser excluídos se você pretende deixá-los selecionado no contexto de dispositivo ao retornar de OnDraw.

Para impedir que o CPen and CBrush objetos de sendo destruído quando OnDraw Concluir, armazená-los em variáveis de membro em vez de variáveis locais. Na declaração de classe do controle, adicione declarações de duas novas variáveis de membro:

class CMyAxOptCtrl : public COleControl
{


...


   CPen m_pen;
   CBrush m_brush;
};

Em seguida, a OnDraw função pode ser reescrita da seguinte maneira:

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);
}

Essa abordagem evita a criação da caneta e Pincel de cada vez OnDraw é chamado. O aperfeiçoamento de velocidade vem o custo da manutenção dos dados de instância adicional.

Se a propriedade ForeColor ou BackColor for alterado, caneta ou Pincel precisa ser criado novamente.Para fazer isso, substituir o OnForeColorChanged and OnBackColorChanged funções de membro:

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

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

Finalmente, para eliminar desnecessários SelectObject chamadas, modificar OnDraw sistema autônomo a seguir:

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);
   }
}

Consulte também

Conceitos

Os controles ActiveX MFC: Otimização

Controles do ActiveX MFC

Controles do ActiveX MFC

Os controles ActiveX MFC: Pintar um controle ActiveX

Referência

Classe COleControl

Assistente de controle ActiveX MFC