컨트롤 그리기 최적화

21세기 모노리스ACLActiveXActiveX/잔상처리ActiveX/창 없는 활성화 제공 ActiveX/컨트롤 그리기 최적화

ActiveX/컨트롤 그리기 최적화

컨테이너가 제공하는 디바이스 컨텍스트에 컨트롤을 그리도록 명령을 실행하면 해당 컨트롤은 대개 컨테이너의 디바이스 컨텍스트에 있는 GDI 개체(펜, 브러시, 글꼴 등)를 선택하여 그리기 작업을 수행한 다음 이전의 GDI 개체를 복원합니다. 같은 디바이스 컨텍스트에 그려지는 컨트롤이 컨테이너에 여러 개 있고 모든 컨트롤이 각각 필요로 하는 GDI 개체를 선택하는 경우, 이 컨트롤들이 이전에 선택한 개체를 개별적으로 복원하지 않도록 하면 시간을 절약할 수 있습니다. 즉, 모든 컨트롤이 그려진 다음에 해당 컨테이너가 원래 개체를 자동으로 복원할 수 있습니다.
컨테이너가 이 기술을 지원하는지 여부를 확인하기 위해 컨트롤에서는 COleControl::IsOptimizedDraw 멤버 함수를 호출할 수 있습니다. 이 함수가 TRUE를 반환하면 해당 컨트롤은 이전에 선택한 개체를 복원하는 일반적인 단계를 건너뜁니다.
다음 예제에서 최적화되지 않은 OnDraw 함수를 포함하는 컨트롤을 참조하십시오.
void CMyCtrl::OnDraw(CDC* pdc, CRect& rcBounds, 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가 값을 반환할 때 선택한 GDI 개체를 해당 디바이스 컨텍스트에 선택된 상태로 남겨두면 해당 개체가 삭제되지 않습니다.
OnDraw가 종료될 때 CPen 및 CBrush 개체가 삭제되지 않도록 하려면 이 개체를 지역 변수 대신 멤버 변수에 저장합니다. 해당 컨트롤의 클래스 선언에 다음과 같이 두 개의 멤버 변수 선언을 새로 추가합니다.
class CMyCtrl : public COleControl
{
    .
    .
    .
    CPen m_pen;
    CBrush m_brush;
}
그런 다음 OnDraw 함수를 다음과 같이 다시 작성합니다.
void CMyCtrl::OnDraw(CDC* pdc, CRect& rcBounds, 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);
    pdc->SelectObject(pPenSave);
    pdc->SelectObject(pBrushSave);
}
이 방법을 사용하면 OnDraw가 호출될 때마다 펜 및 브러시를 만들지 않게 됩니다. 하지만 속도가 빨라지는 대신 추가 인스턴스 데이터는 유지할 수 없게 됩니다.
ForeColor 또는 BackColor 속성이 변경되는 경우에는 펜 및 브러시를 다시 만들어야 합니다. 이렇게 하려면 OnForeColorChanged 및 OnBackColorChanged 멤버 함수를 다음과 같이 재정의하면 됩니다.
void CMyCtrl::OnForeColorChanged()
{
    m_pen.DeleteObject();
}

void CMyCtrl::OnBackColorChanged()
{
    m_brush.DeleteObject();
}
마지막으로, 불필요한 SelectObject 호출을 제거하기 위해 OnDraw를 다음과 같이 수정합니다.
void CMyCtrl::OnDraw(CDC* pdc, CRect& rcBounds, 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);
    }
}
참고항목 : ActiveX/컨트롤설정

ID
Password
Join





- 전 이런 놈입니다.

격언> 세상이 자신에게 준 것보다 더 많이 세상에 되돌려 주는것, 그것이 바로 성공이다. (헨리포드)

Recent Changes

D  Echoes Of War(The... @ 2012-05-18 [03:44 pm] by windlesszone
D  Diablo3 @ 2012-05-15 [04:49 pm] by windlesszone
D  Diablo3/story/wizard @ 2012-05-15 [04:48 pm] by windlesszone 4 changes
D  Diablo3/story/wit... @ 2012-05-15 [04:16 pm] by windlesszone
D  Diablo3/story/monk @ 2012-05-15 [04:14 pm] by windlesszone





Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2006-04-06 11:47:40
Processing time 0.0964 sec