最佳控件绘制

当控件将指示将引入了由容器提供的设备上下文时,通常会选择 GDI 对象 (如钢笔、画笔和字体) 到设备上下文,执行绘制操作,然后恢复以前的 GDI 对象。如果容器具有要引入的多个控件相同的设备上下文,,它需要的每个控件选择 GDI 对象时,可以保存,如果控件没有单独还原以前选定的对象。在所有控件绘制后,容器可以自动恢复原始对象。

若要检测容器是支持此技术,控件可以调用 COleControl::IsOptimizedDraw 成员函数。如果此函数返回 TRUE,控件可以跳过常规步骤还原以前选定的对象。

考虑具有以下的控件 (优化 ") 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);
}

钢笔和画笔在此示例中为局部变量,这意味着它们的析构函数将调用,则会超出范围时 (在 OnDraw 函数结束时)。析构函数将尝试删除相应的 GDI 对象。它们,如果您计划将其选中到设备上下文中返回从 OnDraw,但是,不应删除。

若要防止 CPenCBrush 对象销毁,当 OnDraw 完成时,请将它们存储在成员变量而不是局部变量。在控件的类声明,请将两个新成员变量的声明:

class CMyAxOptCtrl : public COleControl
{


...


   CPen m_pen;
   CBrush m_brush;
};

然后, 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);
}

,在 OnDraw 调用时,此方法避免钢笔和画笔的创建。速度提高随附维护额外的实例数据太。

如果前景色或背景色属性更改,钢笔或画笔需要重新创建。为此,请重写 OnForeColorChangedOnBackColorChanged 成员函数:

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

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

最后,消除不需要的 SelectObject 调用,修改 OnDraw 如下所示:

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

请参见

参考

COleControl 类

MFC ActiveX 控件向导

概念

MFC ActiveX 控件:优化

MFC ActiveX 控件

MFC ActiveX 控件

MFC ActiveX 控件:绘制 ActiveX 控件