[MFC] CScrollView와 줌인 줌아웃 처리.
MFC&ActiveX 2008. 7. 30. 00:26 |[MFC] Ruler 소스.. 메모리 DC 사용한 자연스러운 효과구현..
중점 :
- 줌인 줌아웃 처리를 위한 float 변수를 하나 추가 했습니다.
- ScrollView의 페이지 크기를 저장하는 CSize 변수를 하나 추가 했습니다.
- 방향키 UP, DOWN 을 사용해서 줌인, 줌아웃 처리를 보여 줍니다.
이제 설명을 시작하겠습니다.
Ruler 보완
Ruler의 기존 소스를 보게 되면 마우스로 스크롤 할때 Ruler가 따라 가지 않습니다.
기존 코드를 볼가요?
// 기본 Ruler
CRect rulerRect;
rulerRect.left = scrollPosition.x;
rulerRect.right = rulerRect.left + curArea.Width();
rulerRect.top = scrollPosition.y;
rulerRect.bottom = rulerRect.top + 20;
m_RulerHorz.Draw( pDC, rulerRect.left, rulerRect.top, rulerRect.Width(), rulerRect.Height(), scrollPosition.x );
분명히 scrollPosition.y를 해줬는데도 안됩니다.
이걸 해결 하기 위해서는 휠을 움직여서 화면을 업데이트 한 것이기 때문에
아래의 OnMouseWheel함수를 오버라이드(?) 해서 Invalidate()를 해줘야 됩니다.
BOOL CRulerSampleView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
Invalidate();
return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
}
그리고 Scroll의 Bar를 움직여도 화면이 업데이트 되어야 하기 때문에 아래의 함수들도 같이 처리
void CRulerSampleView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
Invalidate( true );
CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CRulerSampleView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
Invalidate( true );
CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}
이렇게 하고 나면 휠 또는 스크롤바를 움직여도 Ruler가 자연스럽게 화면에 보이는걸 알 수 있습니다.
자자..
이제 줌인 줌아웃 처리를 해볼까요..
줌인 줌아웃 처리를 위해서 아래의 코드를 RulerSampleView.h 에 추가 합니다.
CSize m_PageSize;
float m_Zoom;
그리고 RulerSampleView.cpp 에는 아래와 같이 해봅시다.
> 우선 줌 성분 초기화를 생성자 함수에 추가
m_Zoom = 1.f;
> ScrollVew이기 때문에 페이지의 크기를 추가
void CRulerSampleView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
m_PageSize = CSize( 1000, 1000 );
SetScrollSizes(MM_TEXT, m_PageSize);
}
> 드로잉 코드에 m_Zoom을 적절하게 수정해 줍니다.
테스트를 위한 위치값을 10개를 생성했습니다. 이건 코드 보시면 알수 있어요..
드로잉 할때 아래와 같이 처리 합니다.
vector< CPoint >::iterator iter;
for( iter = m_TestData.begin(); iter != m_TestData.end(); iter++ )
{
CRect rect;
rect.left = (*iter).x;
rect.top = (*iter).y;
rect.right = rect.left + 50;
rect.bottom = rect.top + 50;
rect.left *= m_Zoom;
rect.top *= m_Zoom;
rect.right *= m_Zoom;
rect.bottom *= m_Zoom;
pDC->FillRect( &rect, &redbrush );
}
위의 붉은 부분을 m_Zoom으로 곱해줍니다.
> 이렇게 하고 나서 이제 이벤트를 추가해줘야 겠죠.
방향키를 통해서 줌인 줌아웃 성분을 증가 감소 합니다.
void CRulerSampleView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if( nChar == VK_UP )
{
m_Zoom -= 0.1f;
CClientDC dc(this);
m_RulerHorz.CreateDC( &dc, 10000, 20, m_Zoom );
m_PageSize = CSize( 1000*m_Zoom, 1000*m_Zoom );
SetScrollSizes(MM_TEXT, m_PageSize);
Invalidate();
}
if( nChar == VK_DOWN )
{
m_Zoom += 0.1f;
CClientDC dc(this);
m_RulerHorz.CreateDC( &dc, 10000, 20, m_Zoom );
m_PageSize = CSize( 1000*m_Zoom, 1000*m_Zoom );
SetScrollSizes(MM_TEXT, m_PageSize);
Invalidate();
}
CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
}
위의 코드에서 보듯이 Ruler도 줌 성분이 달라지면, Ruler의 줌 성분을 보정해서 메모리 DC를 생성합니다.
그리고 ScrollView의 페이지도 m_Zoom에 따라서 사이즈를 제조정 해줍니다.
이렇게 하면 아래와 같은 프로그램을 만들 수 있습니다.
관련샘플 :
.
.