스크롤바를 달아만 놨었다.. 요지부동.. ㅎㅎ
스크롤바 컨트롤을 상속받아서 내부에서 처리하지 않는이상... 다이알로그 등에 올려놓고 쓰려면 WM_VSCROLL 및 WM_HSCROLL 메시지를 처리해서 하나 하나 직접 동작시켜 주어야 한다.
현재 길쭉한 나무 막대기 모양으로 만들었으니, WM_VSCROLL 메시지를 이용하여 스크롤바가 원하는 동작을 하도록 만들어 보자.
그림 처럼 클래스 위저드를 이용하여 메시지 핸들러를 추가한다.
그전에 알아두어야 할것이, winuser.h 에 디파인 되어있는 스크롤바의 동작에 관한 디파인이다. 우리가 사용할 WM_VSCROLL 메시지 핸들러의 정의부를 살펴보면 첫번째 인자에 전달되는 값이기도 하기 때문에 꼭 알고 있어야 한다.
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
아래에서 디파인이 같은 것들이 존재하는 이유는 결국 같은 동작이지만 수직 스크롤과 수평 스크롤을 구분해 보여주기 위하여 나누어 놓은것이다. #define SB_LINEUP 0 #define SB_LINELEFT 0 #define SB_LINEDOWN 1 #define SB_LINERIGHT 1 #define SB_PAGEUP 2 #define SB_PAGELEFT 2 #define SB_PAGEDOWN 3 #define SB_PAGERIGHT 3 #define SB_THUMBPOSITION 4 #define SB_THUMBTRACK 5 #define SB_TOP 6 #define SB_LEFT 6 #define SB_BOTTOM 7 #define SB_RIGHT 7 #define SB_ENDSCROLL 8
그러므로 수직 스크롤바에 대하여 설명하면 수평은 자동이해.. ^^; #define SB_LINEUP 0 - 위의 버튼 누름 #define SB_LINEDOWN 1 - 아래 버튼 누름 #define SB_PAGEUP 2 - 버튼과 이동막대기(thumb)사이의 상단 공간 누름 #define SB_PAGEDOWN 3 - 버튼과 이동막대기(thumb)사이의 하단 공간 누름 #define SB_THUMBPOSITION 4 - 이동 막대기의 최종위치 #define SB_THUMBTRACK 5 - 이동 막대기가 계속 이동하고 있음 #define SB_TOP 6 - 크기가 변하거나 업데이트 될 때.. min 설정 #define SB_BOTTOM 7 - 크기가 변하거나 업데이트 될 때.. max 설정 #define SB_ENDSCROLL 8 - 한단계의 스크롤 동작을 마침
아주 간단하게 동작에 대해 설명했는데.. 6,7,8번을 제외하고는 이해하는데 별 문제가 없다. SB_TOP, SB_BOTTOM은 레인지를 다시 설정하거나 크기를 변경하거나 할 때 발생하는 것이라는데 거의 사용하지 않는다.
스크롤시에 버튼을 꾹 누르고 있거나 이동 막대기를 잡고 왔다 갔다 하다가 마지막에 마우스 버튼을 딱 띠는 순간 SB_ENDSCROLL가 발생한다. 마우스를 누르고 이리 저리 움직이면 내부 타이머에 의하여 연속적으로 이벤트가 발생하는데, 이 이벤트가 떨어지면 전체적인 하나의 동작으 완료되었음을 알 수 있게된다.
보통 잘 쓰이지는 않는데.. 연속적인 동작에는 관심없고 마지막 최종 동작에만 관심이 있을 경우 위 이벤트를 이용하여 최종 포지션을 읽어와서 먼가 작업을 한다던가 할 때 주고 쓰인다.
아래는 실제로 이벤트 핸들러 내부에 동작을 구현해본 코드이다. 1. 버튼을 누를 경우는 위 아래로 +-1 이동하고 2. 이동막대기를 움직일 때는 움직인 만큼 3. 페이지 영역을 누를 때는 +-5로 이동하도록 구현하였다.
void CSampleDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { if(!pScrollBar || !pScrollBar->m_hWnd) return;
if(pScrollBar->GetDlgCtrlID() == IDC_SCROLLBAR5) { UINT nCurPos = pScrollBar->GetScrollPos(); switch(nSBCode) { case SB_BOTTOM: pScrollBar->SetScrollPos(SCROLL_MAX); break;
case SB_ENDSCROLL: break;
case SB_LINEDOWN: nCurPos += 1; if(nCurPos > SCROLL_MAX) nCurPos = SCROLL_MAX; pScrollBar->SetScrollPos(nCurPos); break;
case SB_LINEUP: nCurPos -= 1; if(nCurPos < SCROLL_MIN) nCurPos = SCROLL_MIN; pScrollBar->SetScrollPos(nCurPos); break;
case SB_PAGEDOWN nCurPos += 5; if(nCurPos > SCROLL_MAX) nCurPos = SCROLL_MAX; pScrollBar->SetScrollPos(nCurPos); break;
case SB_PAGEUP: nCurPos -= 5; if(nCurPos < SCROLL_MIN) nCurPos = SCROLL_MIN; pScrollBar->SetScrollPos(nCurPos); break;
case SB_THUMBPOSITION: pScrollBar->SetScrollPos(nPos); break;
case SB_THUMBTRACK: pScrollBar->SetScrollPos(nPos); break;
case SB_TOP: pScrollBar->SetScrollPos(SCROLL_MIN); break; } } CDialog::OnVScroll(nSBCode, nPos, pScrollBar); }
|
댓글 없음:
댓글 쓰기