반응형

http://ospace.tistory.com/tag/%EC%8A%A4%ED%81%AC%EB%A1%A4%EB%B0%94

 


 

GetScrollPos => int GetScrollPos(HWND hWnd, int nBar);
설명 : 스크롤 바 컨트롤의 현재 값을 조사한다. 이 값은 스크롤 바 썸의 위치이다. 스크롤 바 메시지인 M_HSCROLL, WM_VSCROLL 메시지는 HIWORD(wParam)으로 현재 위치를 전달해 주기 때문에 16비트 범위의 값 이상을 표현할 수 없지만 이 함수를 사용하면 32비트 범위의 스크롤 값을 조사할 수 있다.
 
SetScrollPos => int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw);  
설명 : 스크롤 바위 현재 위치, 즉 스크롤 바의 값을 설정한다. 통상 이 함수는 WM_HSCROLL, WM_VSCROLL 등의 스크롤 바 메시지 처리 루틴에서 스크롤 바의 위치값을 변경하기 위해 호출한다. 범위를 지정하는 nPos는 32비트의 정수이나 메시지로 전달되는 스크롤 바 위치는 16비트값이기 때문에 위치값은 16비트로 제한된다. 그러나 메시지의 인수를 참조하지 않고 GetScrollInfo 등의 함수로 스크롤 바의 위치를 직접 조사하면 32비트의 스크롤 위치값을 지정할 수도 있다.


인수 설명 : 
hWnd : 스크롤 바 컨트롤의 핸들. 이 값의 의미는 두번째 인수 nBar에 따라 달라진다.

nBar : 위치를 설정할 스크롤 바를 지정한다. 다음 세가지 값중의 하나를 가진다.
          SB_CTL 별도의 스크롤 바 컨트롤이며 hWnd는 스크롤 바 컨트롤의 핸들을 나타낸다. 
          SB_HORZ 표준 수평 스크롤 바이며 hWnd는 스크롤 바를 가진 윈도우의 핸들이다. (int 0)
          SB_VERT 표준 수직 스크롤 바이며 hWnd는 스크롤 바를 가진 윈도우의 핸들이다. (int 1)

nPos : 스크롤 바위 새로운 위치를 지정한다. 이 위치는 반드시 스크롤 바위 범위내에 있어야 하므로 값을 변경할 때 범위 내부인지를 점검한 후 값을 변경해야 한다.

bRedraw : 위치를 변경한 후 스크롤 바를 다시 그릴 것인지를 지정한다. 실행중에 위치를 변경할 경우 이 값을 TRUE로 지정하여 썸을 다시 그리도록 해 주어야 한다. 그러나 최초 스크롤 바 초기화시에는 다시 그릴 필요가 없으며 또한 실행중에라도 스크롤 바위 범위와 위치를 동시에 변경할 때는 둘 중 한 함수에서만 다시 그리기를 지정하면 된다. 이 경우 통상 SetScrollRange에서만 bRedraw를 TRUE로 설정하며 SetScrollPos의 bRedraw는 FALSE로 지정한다.


 

 

 

[컨트롤이야기] 아무도 말해주지않은 스크롤바 기능

작성자: Ospace (ospace114 at naver.com)http://ospace.tistory.com

스크롤바는 상당히 많이 사용하고 있는 컨트롤 중에 하나이다. 내용을 한 화면에 표시하지 못할 경우 그 일부를 표시하고 나머지 내용은 스크롤 바로 상하, 혹은 좌우로 이동하면서 볼 수 있게 한다.
또는 일정 정수 구간 값을 이동하면서 원하는 지점의 정수 값을 가져올 수도 있다.

먼저 스크롤 바의 기본적인 이야기를 하고 후반에 좀더 깊이 다루겠다.

Note: 예제 코드는 거의 없기에 간단하게 스크롤바를 작성하는 강좌를 보고 읽는게 이해하기 쉽다. 스크롤바에 대한 실사용을 보려면 아래 기타강좌를 참고하시길 바란다.



스크롤바 들어가기


사용자 삽입 이미지

Fig 1. Scroll Bar (from Windows XP)


위의 그림은 Windows XP에 있는 스크롤 바이다. 그전 스크롤바보다 이쁘게 변했다. ^^;
MS에서는 이렇게 스킨을 어떻게 했길래 선택적으로 바뀔 수 있지. 컨트롤 스킨 변경하려면 수많은 코드와 삽질을 해야만 되는데.. OTL

아래는 실제 스크롤 바에 구성요소들이다.

사용자 삽입 이미지

Fig 2. Scroll Bar 구성요소



스크롤바는 많이 사용해서 각 기능이야 대충 알고 있지만, 다시 대충 살표보자.

좌우에 삼각형 모양의 버튼이 보인다. 이는 좌후로  1 발자국(step)씩 움직인다. 이는 스크롤바 전체 값 범위에서 실제 1값을 의미의한다.
예를 들어 스크롤바 값 범위가 1~100 혹은 1~1000이든 상관없이 무조건 1을 의미한다.

가운데 홀로 떨어진 스크롤박스가 보인다. 이는 MSDN의 스크롤바 설명을 참조했다. 이를 이용해 값을 찾아간다. 좌우측에 빈 페이지가 보인다.

스크롤바의 정보를 가져오는 API로 GetScrollInfo 함수가 있다. 그리고 정보를 설정하는 API는 SetScrollInfo 함수가 있다.

스크롤바는 100% 수동적인 컨트롤이다. 이말은 모든 부분을 프로그래머가 제어해줘야한다.
예를 들어 가운데 스크롤박스를 움직이면 끝나는 것이 아니라. 그때 스크롤바 위치를 얻고, 해당 값을 다시 스크롤바에 갱신하고 화면을 다시 그리게 한다는 의미이다.주의하길 바란다!

스크롤바 값은 정수형이다. 실수는 사용할 수 없다. 사용하려면 값변환을 통해서 사용해야 한다. 최대 최소값을 지정하지 않으면 기본 범위는 0~100을 가진다. 일단 정확히 지정해주는게 좋다.

예를 들어 문서를 불러와서 표시하려 한다. 총 줄수가 150개라고 하면, 스크롤바 값 범위는 0~150으로 설정한다. 이건 고정된 값은 아니다. 스크롤바 범위는 300, 450도 가능하고 200도 가능하다.
단지 스크롤바 1스텝이 라인 1줄에 해당하는 형태로 일치시키기 위해서이다.

이렇게 최대 최소 값을 지정하는건 그다지 큰 문제가 없고 다른 사이트에서 많이 다루는 예제이다. 


스크롤바 깊게 들어가기


지금은 스크롤바 페이지에 대해서 보도록 하겠다. 페이지는 스크롤바 가운데 있는 스크롤상자 크기에 대한 이야기이다. 스크롤상자는 때에 따라서 커지고 작아지기도 한다. 손오공 여의봉처럼 마음대로 커지고 마음대로 작아지는 놈일까?
그렇지 않다. 사용 목적이 있기 때문에 크기가 그에 따라 변경이된다.

스크롤바 크기는 페이지 크기이다. 한페이지에 들어가는 값 개수이다. 어차피 정수이니 한페이지에 들어가는 정수값 크기라고 보면 된다.

페이지 크기라고 하면 감이 안잡힌다. 예를 들어 책을 살펴보는게 쉽게 이해할 수 있다.
책에는 방대한 양의 글자들이 들어가 있다. (물론 그림, 사진 등도 있다^^;) 모든 내용을 하나의 종이메 모두 담지 못했기에 페이지 단위로 나눠서 표시한다.

예를 들어, 총 1234줄의 내용이 있고 한페이지에 들어가는 줄수는 100줄이라고 가정하면 총 페이지 수는 얼마가될까?

답은 13 페이지
마지막 12페이지를 꽉채우고 34줄이 남지만 한 페이지는 반으로 나눌 수는 없기에 1페이지로 만들어서 넣는다. 추가로 표지, 목차, 속지, 인지 등을 포함하면 더 늘어날 수 있지만 ㅡ.ㅡㅋ

마찬가지로 컴퓨터 화면도 방대한 내용을 한화면에 모두 표시할 수 없기에 페이지 단위로 나눠서 표시한다. 책과 다른 점은 컴퓨터는 연속적으로 페이지를 볼 수 있다.

앞의 책의 예를 일반 텍스트 문서라고 가정해서 스크롤바 설정을 해보자.

최대 최소 값 범위: 0~1234
페이지크기(스크롤박스 크기): 100


너무 쉬어 보인다. 내가 설명을 잘해서인가? ㅋㅋㅋ

그러나 주의할 점이 있다. 바로 스크롤박스가 움직일 수 있는 최대값이 스크롤바 최대값과는 틀리다.
이는 스크롤박스 크기에 따라 가변적이기에 주의해야한다.

사용자 삽입 이미지

Fig 3. Scroll Bar 값들

위 그림은 스크롤바에서 사용되는 값을 표시하였다.
스크롤박스 왼쪽 경계가 현재 값이다. (Current Position)
스크롤바 양쪽 버튼을 제외한 영역이 스크롤바 전체 값 범위이다.(MAX Range Value)
그리고, 양쪽 버튼과 스크롤박스 크기를 제외한 나머지 영역이 스크롤박스가 움직일 수 있는 범위이다.(MAX Scroll Pos)

여기서 중요한 값이 MAX Scroll Pos이다. 현재 위치(Current Position)이 MAX Scroll Pos값을 넘을 수 없다. 단, 최소값은 항상 0으로 가정한다.

0 <= Current Position <= MAX Scroll Pos

그럼 MAX Scroll Pos을 구하는게 중요하다.

MAX Scroll Pos = MAXRangeValue - (Page Size - 1)

Page Size에서 -1은 당연히 Page Size 왼쪽 경계까지 값 범위이기 때문이다. 이를 앞에 책의 예를 이용해서 다시 스크롤바 설정을 해보자.

최대 최소 값 범위: 0~1234
페이지크기(스크롤박스 크기): 100
스크롤박스 이동 범위: 0 ~ 1135




스크롤바 전문가 과정

좀더 스크롤바를 깊게 들어가자. 지금 부터 조금 머리 아파질 수 있으니, 지금 머리가 조금 아프신 분들은 창문가서 밖같 하늘 한번 구경하자.

지금 다를 내용은 크게 두가지 이다. 하나는 프로그램 크기(resize)와 데이터 변경되는 경우와 다른하나는 스크롤을 좀더 세밀하기 하기 위해 스크롤바 최대 최소 범위를 변경하는 경우이다.


프로그램 크기와 데이터 변경

먼저 프로그램 크기와 데이터가 변경되는 경우를 살펴보자.
프로그램 크기가 변경되는 의미는 내용이 나타나는 화면 크기가 바뀌었다는 의미이고 스크롤 바에서는 한 화면에 표시되는 크기를 가리키는 스크롤박스 크기가 달라졌다는 의미이다.

앞의 책의 예를 보면 한페이지에 표시할 수 있는 줄수가 100줄에서 130줄 혹은 50줄로 커지거나 작아졌다는 의미이다.
일단 내용 변경이 없다면 스크롤바 최대 최소 값 범위은 변경되지 않고 페이지 크기가 변경되었고, 즉, 스크롤박스가 이동할 수 있는 범위가 변경되었다는 의미이다.

책의 예제에서 한페이지(한화면)에서 표시할 수 있는 줄수가 100줄에서 130줄로 변경되었다면 스크롤바 설정을 살펴보자.

스크롤바 최대 최소 값 범위: 0 ~ 1234
페이지크기(스크롤박스 크기): 100 -> 130 (변경)
스크롤박스 이동 범위: 1234 - (130 - 1) = 1103 (변경)
페이지수: 10 페이지 (이는 스크롤바 설정 값은 아니다.)


그리고 데이터가 변경되었다면 어떻게 될까?
일단 스크롤바 최대 최소 값 범위가 변경된다. 페이지 크기는 고정이지만, 스크롤 박스 이동 범위도 바뀌게 된다. 즉, 전체 크기가 변경되었으므로 이동가능한 범위도 변경되었다는 의미이다. 그럼 마찬가지로 앞의 책의 예로 계산해보자.
가정은 데이터 량이 1234줄에서 1500줄로 늘어낳고 한 페이지 크기는 130줄로 계산해보자.

스크롤바 최대 최소 값 범위: 0 ~ 1500 (변경)
페이지크기(스크롤박스 크기): 130
스크롤박스 이동 범위: 1500 - (130 - 1) = 1371 (변경)
페이지수: 12 페이지 (이는 스크롤바 설정 값은 아니다.)


화면 크기 혹은 데이터 크기 변경은 각각 페이지 크기 변경 혹은 스크롤바 최대 값 변화가 따로 생기지만 스크롤박스 이동 범위는 둘 다 새로 계산해야 된다.


스크롤바 정밀도 조절하기

데이터 크기와 스크롤바 크기가 일치하지 않은 경우를 살펴보자.
앞에서는 텍스트 한줄이 스크롤바 한스텝과 일치한다. 스크롤바에서 3값이 움직이면 텍스트에서 3줄이 움직인다.

간혹 1 스텝 이동이 1/2 줄 이동이나 1 스텝 이동이 2줄 이동으로 할 경우도 있다.

사용자 삽입 이미지

Fig 4. 1스텝 이동시 반줄 이동


이 그림은 1 스텝 이동은 반 줄 이동하는 예를 보여둔다. 즉 2 스텝 이동해야 한 줄이 이동된다는 의미이다. 즉 한 스텝 이동하면 글자 반정도 크기만 움직이고 화면 경계에 있다면 반은 보이고 반은 가려서 보이지 않게된다. 한 스텝이 글자 반 정도 움직이는 느린 스크롤이 된다.

사용자 삽입 이미지

Fig 5. 1스텝 이동시 2줄 이동



이 그림은 1 스템 이동이 2줄 이동하는 예이다. 즉, 반 스텝 이동이 한줄 이동이지만 반 스텝 이동은 없다. 스크롤 바는 정수 값만 사용하기 때문이다.
한스텝 이동은 2줄이 한꺼번에 움직이므로 빠른 화면 스크롤을 볼 수 있다.

그러면 위와 같은 경우 스크롤바 값 설정은 어떻게 될 것인다.
간단하게 계산하기 위해서 텍스트 줄수는 100줄이고 한화면 표시되는 페이지 크기는 10라고 하자.


1스텝에 1/2줄 이동

먼저 한 스텝에 반 줄 이동하는 예를 보자.
즉, 한줄이 2스텝을 차지하므로 총 100줄이므로,

100줄 x 2 스텝 / 줄 = 200 스텝

결국 스크롤바 값 범위가 0 ~ 200를 가진다. 좀더 생각을 하면 앞에서 스크롤바는 정수값만 사용한다고 했지만, 위의 값의 범위는 0~100줄은 0.5줄 단위까지 잘라서 얻을 수 있다는 의미이다.
페이지 크기가 10는 스템 수가 아닌 화면에 나타나는 줄 수 이다. 그러면 페이지 크기는

10줄 x 2 스텝 / 줄 = 20 스텝

페이지 크기는 20스텝이 된다.
그러면 스크롤박스 최대 이동 가능한 값이 계산된다.

스크롤박스 최대 이동 값 = 200 - (20 - 1) = 181

스크롤박스 최대 이동 값은 181이 된다.


1스텝에 2줄 이동

다음으로 1스텝이 2줄 이동하는 예를 살펴보자. 앞의 계산 법의 확인일 뿐이다.
앞의 계산 법에 의해서 단위 줄에 변하는 스텝 값은 1/2이 된다.

스크롤바 최대값: 100줄 x 1/2 스텝/줄 = 50 스텝
페이지 크기: 10줄 x 1/2 스텝/줄 = 5 스텝
스크롤박스 최대 이동 값: 50 - (5 - 1) = 46


계산 방법은 동일하다. 이부분은 텍스트를 예로 들어서 설명했지만, 그래픽 처리에서 상당히 유용하리라 생각한다.

 

기타강좌:
스크롤바 강좌: http://www.winapi.co.kr/win32lec/lec7/lec7-5-1.htm

반응형

+ Recent posts