Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Quando um controle é instruído a desenhar-se em um contexto de dispositivo fornecido por contêiner, ele normalmente seleciona objetos GDI (como canetas, pincéis e fontes) no contexto do dispositivo, executa suas operações de desenho e restaura os objetos GDI anteriores. Se o contêiner tiver vários controles que devem ser desenhados no mesmo contexto de dispositivo e cada controle selecionar os objetos GDI necessários, o tempo poderá ser economizado se os controles não restaurarem individualmente objetos selecionados anteriormente. Depois que todos os controles tiverem sido desenhados, o contêiner pode restaurar automaticamente os objetos originais.
Para detetar se um container suporta esta técnica, um controlo pode invocar a função membro COleControl::IsOptimizedDraw. Se essa função retornar TRUE, o controle pode ignorar a etapa normal de restaurar os objetos selecionados anteriormente.
Considere um controle que tenha a seguinte função (não otimizada): 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);
}
A caneta e o pincel neste exemplo são variáveis locais, o que significa que seus destruidores serão chamados quando saírem do escopo (quando a OnDraw função terminar). Os destruidores tentarão excluir os objetos GDI correspondentes. Mas eles não devem ser excluídos se você planeja deixá-los selecionados no contexto do dispositivo ao retornar do OnDraw.
Para evitar que os objetos CPen e CBrush sejam destruídos quando OnDraw terminar, armazene-os em variáveis de membro em vez de variáveis locais. Na declaração de classe do controle, adicione declarações para 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 forma:
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);
}
Esta abordagem evita a criação da caneta e do pincel sempre que OnDraw é chamado. A melhoria da velocidade tem o custo de manter dados de instância adicionais.
Se houver uma alteração na propriedade ForeColor ou BackColor, será necessário criar novamente a caneta ou o pincel. Para fazer isso, substitua os métodos de membro OnForeColorChanged e OnBackColorChanged
void CMyAxOptCtrl::OnForeColorChanged()
{
m_pen.DeleteObject();
}
void CMyAxOptCtrl::OnBackColorChanged()
{
m_brush.DeleteObject();
}
Finalmente, para eliminar chamadas desnecessárias SelectObject , modifique OnDraw da seguinte forma:
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);
}
}
Ver também
Controles ActiveX MFC: Otimização
Classe COleControl
Controles ActiveX MFC
Assistente de controle ActiveX MFC
Controles ActiveX MFC: Pintando um controle ActiveX