컨트롤이 컨테이너 제공 디바이스 컨텍스트에 자신을 그리도록 지시되는 경우 일반적으로 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);
}
이 예제의 펜과 브러시는 지역 변수입니다. 즉, 함수가 종료되어 범위를 벗어날 때 소멸자가 호출됩니다. 소멸자는 해당 GDI 개체를 삭제하려고 시도합니다. 그러나 OnDraw
에서 돌아올 때 장치 컨텍스트에 선택된 상태로 유지하려는 경우, 이를 삭제해서는 안 됩니다.
완료 시 CPen 및 CBrush 개체가 제거 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
펜과 브러시를 만들지 않도록 방지합니다. 속도 향상은 추가 인스턴스 데이터를 유지 관리하는 비용으로 발생합니다.
ForeColor 또는 BackColor 속성이 변경되면 펜 또는 브러시를 다시 만들어야 합니다. 이렇게 하려면 OnForeColorChanged 및 OnBackColorChanged 멤버 함수를 재정의합니다.
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);
}
}
참고하십시오
MFC ActiveX 컨트롤: 최적화
COleControl 클래스
MFC ActiveX 컨트롤
MFC ActiveX 컨트롤 마법사
MFC ActiveX 컨트롤: ActiveX 컨트롤 그리기