티스토리 뷰
프로그램의 작업 영역이 뷰의 크기보다 클 경우 스크롤(Scroll) 기능을 제공함으로써 원하는 위치로 이동할 수 있도록해야 한다. 스크롤 기능을 구현하기 위해서는 윈도우에 스크롤 바가 있어야 하고, 사용자가 스크롤 바를 조작함에 따라 뷰에 표시되는 내용을 적절히 변경해야 하는데 CScrollView 클래스를 사용하면 이러한 스크롤 기능을 좀 더 쉽게 구현할 수 있다.
1. 스트롤 뷰 클래스
void CScrollView::SetScrollSizes(int nMapMode, SIZE sizeTotal, const SIZE& sizePage = sizeDeafult, const SIZE& sizeLine = sizeDafault);
nMapMode : 매핑 모드를 나타내며, MM_ISOTROPIC, MM_ANISOTROPIC 매핑 모드를 제외하고 모두 사용할 수 있다.
sizeTotal : 작업 영역의 전체 크기를 나타내며 논리 단위를 사용한다.
sizePage : 페이지 크기를 나타내며 논리 단위를 사용한다. 페이지 단위로 이동할때 이 크기 만큼 스크롤 한다.
sizeLine : 한 줄의 크기를 나타내며 논리 단위를 사용한다. 줄 단위로 이동할 때 이 크기만큼 스크롤 한다.
아래 예제 코드에는 한번만 호출되는 OnInitialUpdate() 에서 페이지 크기와 줄 크기는 기본값으로 사용하고 있으나 실제로는 윈도우의 크기 또는 작업 영역의 크기 변경에 따라 SetScrollSize()를 매번 호출하는것이 바람직한다.
뷰 클래스의 OnDraw() 에서 사용하는 DC는 스크롤 바의 위치에 따른 원점 보정이 이미 되어 있으므로 논리좌표를 기준으로 출력하면 문제가 없다.
그러나 OnDraw() 이외의 함수에서 화면에 출력한다면 OnPrepareDC()로 매핑 모드 변경과 더불어 스크롤 바의 위치에 따른 원점 보정을 해준다.
1
2
3
4
5
6
7 |
void CMFCApplication18View::MyDraw()
{
CClientDC dc(this);
OnPrepareDC(&dc);
dc.TextOutW(20, 20, CString(L"스크롤 뷰를 연습합니다."));
dc.Ellipse(1930, 1930, 1980, 1980);
} |
cs |
4행을 주석 처리하면 위 그림 처럼 스크롤할때 화면에 잔상이 남는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
class CMFCApplication18View : public CScrollView
{
...
};
void CMFCApplication18View::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: 이 뷰의 전체 크기를 계산합니다.
sizeTotal.cx = sizeTotal.cy = 2000;
SetScrollSizes(MM_TEXT, sizeTotal);
}
void CMFCApplication18View::OnDraw(CDC* pDC)
{
CMFCApplication18Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
pDC->TextOutW(20, 20, CString(L"스크롤 뷰를 연습합니다."));
pDC->Ellipse(1930, 1930, 1980, 1980);
}
|
cs |
2. 스크롤 최적화
작업 영역의 크기가 큰 경우(4000*4000 등)에는 스크롤 속도에 문제가 발생할 수 있다. 스크롤할 때마다 화면에 보이지 않는 부분까지 출력을 하므로 속도가 느려질 가능성이 있다. 이 경우 좀 더 효율적인 방법은 CDC::GetClipBox()를 호출하여 다시 그려할 영역에 대한 정보를 얻은 후 이 부분에만 출력하도록 해서 스크롤 속도를 향상 시킬 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12 |
void CMFCApplication18View::OnDraw(CDC* pDC)
{
CMFCApplication18Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
CRect rect;
pDC->GetClipBox(&rect);
...
} |
cs |
그 밖에 유용한 함수로 CScrollView::SetScaleToFitSize() 가 있는데 이 함수를 사용하면 작업 영역의 내용을 현재 윈도우의 크기에 맞게 축소 또는 확대하여 표시할 수 있다.