안녕하세요. 저번 글까지는 스크롤을 만드는 것까지 했는데, 이번 글에서는 약간의 설명과 코드를 바로 첨부해 드리겠습니다.
코드를 하기 앞서 dc와 dcTemp, 그리고 스크롤로 표현 하는 방법을 설명해드리겠습니다.
최종적으로 사용자가 보는 dc화면이 있습니다.

이 dc에서 CRect rect를 이용하여 크기를 구합니다.
그리고 가로 크기는 10000, 세로는 dc 와 같은 dcTemp를 생성해줍니다.

그리고 dcTemp에 0, 100, 200, … , 9900 같이, 100 위치마다 해당 값을 표시해줍니다.

어제 코드에 보면 스크롤을 설정할 때 10000이라는 크기를 줬습니다. dcTemp크기와 같은 값으로 설정해야 계산하기 편합니다.
1 2 3 4 5 | SCROLLINFO scrInfo; // ... scrInfo.nMax = 10000; // 스크롤 최대값 // ... m_ctlHScroll.SetScrollInfo( &scrInfo ); // 스크롤바 정보 설정 |
스크롤도 0~10000의 값을 가지고 있고 화면 크기도 0~10000이니까 스크롤의 위치에 따라 dcTemp에서 dc로 BitBlt 하시면 됩니다.


이제 OnPaint에 코딩해보도록 하겠습니다. 아래와 같이 입력해주세요.
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | void CDisplay::OnPaint() { CPaintDC dc( this ); // device context for painting // TODO: 여기에 메시지 처리기 코드를 추가합니다. // 그리기 메시지에 대해서는 CWnd::OnPaint()을(를) 호출하지 마십시오. // 크기 구하기 CRect rect; GetClientRect( &rect ); // 화면 그리기 CDC dcTemp; dcTemp.CreateCompatibleDC( &dc ); HBITMAP hbmp = ::CreateCompatibleBitmap( dc, 10000, rect.Height() - 20 ); // 가로 10000 크기로 생성 HBITMAP hbmpOld = ( HBITMAP )dcTemp.SelectObject( hbmp ); // 100마다 텍스트 출력 dcTemp.PatBlt( 0, 0, 10000, rect.Height(), WHITENESS ); for ( int iX = 0 ; iX < 10000 ; iX += 100 ) { CString sX; sX.Format( _T( "%d" ), iX ); dcTemp.TextOut( iX, (rect.Height() / 2), sX ); } SCROLLINFO scrInfo; int iSrcX = 0; if ( NULL == m_ctlHScroll.GetSafeHwnd() ) { CRect rectHScroll; rectHScroll.SetRect( rect.left, rect.top, rect.right, rect.bottom ); m_ctlHScroll.Create( WS_CHILD | WS_VISIBLE | SBS_HORZ | SBS_BOTTOMALIGN // 속성 , rectHScroll // 위치 , this // 부모 윈도우 , 0 // 스크롤 막대의 컨트롤 ID입니다 ); m_ctlHScroll.ShowScrollBar( TRUE ); scrInfo.cbSize = sizeof ( scrInfo ); scrInfo.fMask = SIF_ALL; scrInfo.nMin = 0; // 스크롤 최소값 scrInfo.nMax = 10000; // 스크롤 최대값 scrInfo.nPage = rect.Width(); // 페이지 번호 scrInfo.nTrackPos = 0; // 드래깅 상태의 트랙바 위치 scrInfo.nPos = 0; // 트랙바 위치 m_ctlHScroll.SetScrollRange( scrInfo.nMin, scrInfo.nMax ); // 범위 설정 m_ctlHScroll.SetScrollPos( scrInfo.nPos ); // 위치 설정 m_ctlHScroll.SetScrollInfo( &scrInfo ); // 스크롤바 정보 설정 } else { if ( FALSE != m_ctlHScroll.GetScrollInfo( &scrInfo ) ) { iSrcX = scrInfo.nPos; // 현재 스크롤 위치 받아옴 } } dc.BitBlt( 0, 0, rect.Width(), rect.Height(), &dcTemp, iSrcX, 0, SRCCOPY ); // 더블 버퍼링 dcTemp.SelectObject( hbmpOld ); ::DeleteObject( hbmp ); dcTemp.DeleteDC(); } |
OnEraseBkgnd에 아래와 같이 코딩해주세요. return TRUE;는 덮어씌우기를 하는겁니다.
1 2 3 4 5 6 | BOOL CDisplay::OnEraseBkgnd( CDC* pDC ) { // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다. return TRUE; } |
HScroll 함수 OnHScroll에 아래와 같이 코딩합니다.
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 28 29 30 | void CDisplay::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다. SCROLLINFO scrInfo; memset ( &scrInfo, 0, sizeof (scrInfo) ); if ( FALSE != m_ctlHScroll.GetScrollInfo( &scrInfo ) ) { switch ( nSBCode ) { case SB_LINERIGHT: scrInfo.nPos+=100; break ; case SB_LINELEFT: scrInfo.nPos-=100; break ; case SB_THUMBTRACK: case SB_PAGEDOWN: scrInfo.nPos = nPos; break ; } m_ctlHScroll.SetScrollInfo( &scrInfo ); this ->Invalidate(); } CWnd::OnHScroll( nSBCode, nPos, pScrollBar ); } |
마우스 휠 이벤트가 발생했을 때 처리하는 함수 OnMouseWheel에 아래와 같이 코딩합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | BOOL CDisplay::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt ) { // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다. if ( zDelta > 0 ) { SendMessage( WM_HSCROLL, SB_LINELEFT, NULL ); } else { SendMessage( WM_HSCROLL, SB_LINERIGHT, NULL ); } return CWnd::OnMouseWheel( nFlags, zDelta, pt ); } |
간혹 마우스에 아래와 같이 횡스크롤이 있는데, 이 스크롤에 대한 처리 함수 OnMouseHWheel에 아래와 같이 코딩합니다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void CDisplay::OnMouseHWheel( UINT nFlags, short zDelta, CPoint pt ) { // 이 기능을 사용하려면 Windows Vista 이상이 있어야 합니다. // _WIN32_WINNT 기호는 0x0600보다 크거나 같아야 합니다. // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다. if ( zDelta > 0 ) { SendMessage( WM_HSCROLL, SB_LINERIGHT, NULL ); } else { SendMessage( WM_HSCROLL, SB_LINELEFT, NULL ); } CWnd::OnMouseHWheel( nFlags, zDelta, pt ); } |
실행 시켜 확인해 봅니다.

이상으로 CScrollbar를 이용하여 사용자 정의 클래스를 만들어봤습니다.