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
Os controles ActiveX MFC: Pintar um controle ActiveX