次の方法で共有


コントロールの描画の最適化

コンテナーが指定されたデバイス コンテキストに、自身を描画するようにコントロールに指示するとデバイス コンテキストには、 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から戻るときのデバイス コンテキストに選択されている場合は削除できません。

OnDraw が終了するとき CPenCBrush のオブジェクトが、保存します。ローカル変数ではなく、メンバー変数で破棄されないようにするには。コントロールのクラス宣言では、 2 個の新しいメンバー変数の宣言を追加します:

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 が呼び出されたとき、ペンとブラシの作成を回避できます。速度の機能強化に追加インスタンス データを保持する損なわれます。

前景色または BackColor プロパティの変更、ペンまたはブラシが再度作成する必要があります。これを行うには、 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 コントロールの描画