스크롤바를 사용하다 보면 32767 unsigned short의 양의값을 넘어가는 경우가
간혹 발생할 수 있다.
그래픽 디자인 프로그램과 같은 것들을 설계할 때야 줌 팩터등을 이용하여 따로 처리하니
별 문제가 없겠지만 간단한 먼가를 만들 때 100000의 값을 써야한다면 먼가 설계를 해야하나?
그렇다면 우선 MSDN을 살펴보자.
CScrollBar::SetScrollRange
Set nMinPos and nMaxPos to 0 to hide standard scroll bars.
Do not call this function to hide a scroll bar while processing a scroll-bar notification message.
If a call to SetScrollRange immediately follows a call to the SetScrollPos member function, set bRedraw in SetScrollPos to 0 to prevent the scroll bar from being redrawn twice.
The difference between the values specified by nMinPos and nMaxPos
must not be greaterthan 32,767
. The default range for a scroll-bar control is empty
라고 한다. 인자가 int라면 그렇다면 먼가를 처리하면 최대 양수 20억까지 쓸수 있다는 야근데..
However, because the SetScrollInfo, SetScrollPos, SetScrollRange, GetScrollInfo,
GetScrollPos, and GetScrollRange
functions support 32-bit scroll bar position data,
there is a way to circumvent the 16-bit barrier of the WM_HSCROLL and WM_VSCROLL
messages. See GetScrollInfo for a description of the technique.
16비트 베리어에 쌓여 있단다.. 그렇다면 위의 두 메시지에서 오는 UINT nPos 가 정수
범위임에도 불구하고 쇼트크기를 가진다면 저걸 않쓰면 가능하지 않을까...
(16비트 베리어라는 의미는 내부적으로 먼가를 처리할 때 아무생각 없이 16비트를 썼다는
내용을 아주 점잔하게 표시한 것으로 추측된다.. 즉, 16비트 머신의 잔제가 남았다는 거겠죠.)
--------------------------------------------------------------------------------------
일단 여기까지 살펴보면 32비트를 쓸 수 있는데도 불구하고, 메시지 WM_VSCROLL과
WM_HSCROLL의 UINT nPOS는 16비트 최대값을 가진다고 결론을 내릴 수있다.
즉, 저걸 않쓰면 된다는 이야기겠고..
그럼 저걸 않쓰고 프로그램을 구성하면 되겠죠..
이전 장에 있던 샘플은 0 부터 100까지 크기를 가지는 샘플이었습니다.
이걸 그럼 위의 지식을 기반으로 0부터 1000000 크기를 가지는 샘플로 바꿔보죠.
#define SCROLL_MIN 0
#define SCROLL_MAX
마이스크롤.SetScrollRange(SCROLL_MIN, SCROLL_MAX);
마이스크롤.SetScrollPos(50);
마이스크롤.EnableScrollBar(ESB_ENABLE_BOTH);
요렇게 설정을 해놓고 WM_VSCROLL 핸들러를 다음과 같이 수정해봅니다.
어짜피 이전 샘플에서도 nPos를 쓰는데는 스크롤바를 트래킹할 때만 썻으므로
이 샘플에서도 바뀌는 부분은 거기 밖에는 없습니다.
void CSampleDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
UINT nCurPos;
if(pScrollBar->GetDlgCtrlID() == IDC_SCROLLBAR5)
{
nCurPos = pScrollBar->GetScrollPos();
switch(nSBCode)
{
case SB_THUMBPOSITION:
{
SCROLLINFO si = {0};
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_TRACKPOS;
::GetScrollInfo(pScrollBar->m_hWnd, SB_CTL, &si);
pScrollBar->SetScrollPos(si.nTrackPos);
}
break;
case SB_THUMBTRACK:
{
SCROLLINFO si = {0};
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_TRACKPOS;
::GetScrollInfo(pScrollBar->m_hWnd, SB_CTL, &si);
pScrollBar->SetScrollPos(si.nTrackPos);
}
break;
// 아래도 생략.. 원본과 같음
}
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
헉.. 그냥 않쓰면 되네.. ㅜㅜ;;;
그럼 수고하세요..