Compartilhar via


Otimizando controle desenho

Quando um controle é instruído para desenhar a mesmo em um contexto de dispositivo fornecido pelo contêiner, ele normalmente seleciona objetos GDI (como canetas, pincéis e fontes) no contexto de dispositivo, realiza suas operações de desenho e restaura os objetos GDI anteriores.Se o contêiner tem vários controles que estão a ser desenhada no mesmo contexto de dispositivo, e cada controle seleciona objetos GDI requer, tempo pode ser salvas se os controles não restauram objetos anteriormente selecionados individualmente.Após todos os controles foram desenhados, o contêiner pode automaticamente restaurar objetos originais.

Para detectar se um contêiner oferece suporte a essa técnica, um controle pode chamar o COleControl::IsOptimizedDraw função de membro.Se essa função retorna TRUE, o controle pode ignorar a etapa normal de restauração de objetos selecionados anteriormente.

Considere um controle que tem o seguinte (otimizado) 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);
}

Caneta e Pincel neste exemplo são variáveis locais, significando que os destruidores serão chamados quando saem do escopo (quando o OnDraw função extremidades).Os destruidores tentará excluir objetos GDI correspondentes.Mas eles não devem ser excluídos se você pretende deixar selecionado no contexto de dispositivo no retorno de OnDraw.

Para impedir que o CPen e CBrush objetos sejam destruídos quando OnDraw terminar, 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;
};

Então, 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 de caneta e Pincel sempre OnDraw é chamado.A melhoria 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 e 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 da seguinte maneira:

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

Referência

Classe COleControl

MFC ActiveX Control Wizard

Conceitos

Controles de ActiveX MFC: otimização

Controles de ActiveX do MFC

Controles de ActiveX do MFC

Controles de ActiveX MFC: Pintura de um controle ActiveX