JHB의 프로그래밍 삽질기

[MFC] ScrollBar 사용하기 본문

PROGRAMMING/Win/MFC

[MFC] ScrollBar 사용하기

roter 2011.02.18 10:03
1. 대화상자에 세로 스크롤바를 붙이자.

   2. 스크롤 바에 컨트롤 변수를 추가한다.

      CScrollBar      m_ctrVScroll;


   3. 스크롤 바 초기화

      // 스크롤 바 의 사용영역 설정.
      m_ctrVScroll.SetScrollRange(0, 100);


      // 스크롤 바의 위치 설정

      m_ctrVScroll.SetScrollPos(50);


      // 스크롤바의 모든 정보를 한번에 설정하기
      SCROLLINFO  scrinfo;
      scrinfo.cbSize = sizeof(scrinfo);
      scrinfo.fMask = SIF_ALL;
      scrinfo.nMin = 0;          // 최소값
      scrinfo.nMax = 100;      // 최대값
      scrinfo.nPage = 10;      // 페이지단위 증가값
      scrinfo.nTrackPos = 0;  // 트랙바가 움직일때의 위치값
      scrinfo.nPos = 50;        // 위치
      m_ctrVScroll.SetScrollInfo(&scrinfo);


   4. 스크롤이 움직일때

      - 대화상자의 메시지 WM_VSCROLL를 사용한다. 가로 스크롤바라면 WM_HSCROLL를 사용한다.


         void CDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
        {
            // TODO: Add your message handler code here and/or call default
            if(pScrollBar)
            {

               // 스크롤 바 검사

               if(pScrollBar == (CScrollBar*)&m_ctrVScroll)

               {
                  SCROLLINFO  scrinfo;
                  // 스크롤바 정보를 가져온다.
                  if(pScrollBar->GetScrollInfo(&scrinfo))
                  {
                     switch(nSBCode)
                     {
                     case SB_PAGEUP:   // 스크롤 바의 위쪽 바를 클릭
                        scrinfo.nPos -= scrinfo.nPage;
                        break;
                     case SB_PAGEDOWN:  // 스크롤 바의 아래쪽 바를 클릭
                        scrinfo.nPos += scrinfo.nPage;
                        break;
                     case SB_LINEUP:   // 스크롤 바의 위쪽 화살표를 클릭
                        scrinfo.nPos -= scrinfo.nPage/10;
                        break;
                     case SB_LINEDOWN:  // 스크롤 바의 아래쪽 화살표를 클릭
                        scrinfo.nPos += scrinfo.nPage/10;
                        break;
                     case SB_THUMBPOSITION: // 스크롤바의 트랙이 움직이고 나서
                     case SB_THUMBTRACK:  // 스크롤바의 트랙이 움직이는 동안
                        scrinfo.nPos = scrinfo.nTrackPos;   // 16bit값 이상을 사용

                        break;
                     }


                     // 스크롤바의 위치를 변경한다.
                     pScrollBar->SetScrollPos(scrinfo.nPos);

                  }

               }
            }

            else

            {

               // 이 부분은 Scroll기능이 있는 뷰를 사용시 사용된다.
               int ScrollPos = GetScrollPos(SB_VERT); // 세로 스크롤바 포지션 구하기
                                                                             // 가로는: SB_HORZ

               switch(nSBCode)
               {
               case SB_PAGEUP:        // 스크롤 바의 위쪽 바를 클릭
               case SB_PAGEDOWN:  // 스크롤 바의 아래쪽 바를 클릭
               case SB_LINEUP:         // 스크롤 바의 위쪽 화살표를 클릭
               case SB_LINEDOWN:    // 스크롤 바의 아래쪽 화살표를 클릭
                  CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
                  break;
               case SB_THUMBPOSITION:  // 스크롤바의 트랙이 움직이고 나서
               case SB_THUMBTRACK:      // 스크롤바의 트랙이 움직이는 동안

                  scrinfo.nPos = scrinfo.nTrackPos;
                  // 스크롤바의 위치를 변경한다.
                  SetScrollPos(SB_VERT, scrinfo.nPos);
                  Invalidate(FALSE);
                  break;
               }

            }


            //CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
         }


펌: http://pyong86.tistory.com/entry/MFC-스크롤-바

내용 추가1)
스크롤바는 저걸 구현해 주지 않으면 정말 아무 동작도 하질 않는다..
처음에 레인지만 지정해주면 버튼 누를 때 알아서 bar가 움직일 줄 알았는데.. 저 위의 코드를 구현해 주지 않으면 움직이질 않는다.. 엄청 빡친다 -_-;;

내용 추가2)
스크롤바로 스크롤되는 그림 이미지를 보여 줄 경우.. 스크롤바 사이즈가 참 난해하다.
가로로 스크롤 되는 스크롤바를 만들고 nMax를 그림의 width로 주었는데.. 즉 그림의 1pixel을 스크롤바의 1range로 맞췄었는데.. 안된다.. 이유인 즉슨 그림의 끝과 스크롤바의 nPos를 맞출려면 그렇게 해주면 안되기 때문 이었다.
그래서 나온 결론은 스크롤바의 nMax를 다음과 같이 주는 것이 었다.
int nScrollBarSize = m_nSize - DISPLAY_WIDTH + m_nSize/10; //스크롤바의 크기 때문에 이렇게 조금 빼줘야 한다.
nScrollBarSize = nScrollBarSize>0?nScrollBarSize:0;
si.nMax = nScrollBarsize;

여기서 m_nSize는 그림 파일의 가로 길이이고, DISPLAY_WIDTH는 스크롤바의 가로 길이이다.(즉, 그림이 표시되는 화면의 길이)
위처럼 해주니까 딱 맞더라. 아 물론 si.nPage = m_nSize/10; 일 경우의 얘기이다.

0 Comments
댓글쓰기 폼