最佳化控制項繪圖

當控制項已經收到指示其本身繪製到容器提供的裝置內容時,它通常會選取 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 控制項