Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Quando um controle é instruído a se desenhar 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 do dispositivo e cada controle selecionar os objetos de GDI necessários, tempo poderá ser economizado se os controles não restaurarem individualmente os objetos selecionados anteriormente. Depois que todos os controles tiverem sido desenhados, o contêiner poderá restaurar automaticamente os objetos originais.
Para verificar se um contêiner oferece suporte a essa técnica, um controle pode chamar a função membro COleControl::IsOptimizedDraw. Se essa função retornar TRUE, o controle poderá ignorar a etapa normal de restauração dos 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 eles ficarem fora do escopo (quando a função OnDraw terminar). Os destrutores tentarão apagar os objetos GDI correspondentes. Mas eles não devem ser excluídos se você planeja mantê-los selecionados no contexto do dispositivo ao retornar de OnDraw.
Para impedir que os objetos CPen e CBrush sejam destruídos quando OnDraw for concluído, armazene-os em variáveis-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 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 do pincel sempre que OnDraw é chamado. A melhoria de velocidade tem como custo a manutenção de dados de instância adicionais.
Se a propriedade ForeColor ou BackColor for alterada, a caneta ou pincel precisará ser criado novamente. Para fazer isso, substitua as funções membro OnForeColorChanged e OnBackColorChanged:
void CMyAxOptCtrl::OnForeColorChanged()
{
m_pen.DeleteObject();
}
void CMyAxOptCtrl::OnBackColorChanged()
{
m_brush.DeleteObject();
}
Por fim, para eliminar chamadas desnecessárias SelectObject , modifique 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
Controles ActiveX do MFC: Otimização
COleControl Class
Controles MFC ActiveX
Assistente de controle ActiveX do MFC
Controles ActiveX do MFC: Pintando um controle ActiveX