Scrollbar thumbtrack doesn't scroll all the way
Part of me feels rather dumb for asking this, but everything seems to
work smoothly except for one scrolling action.
I have a dialog with two embedded child dialogs within it. The top
dialog has a scrolling interface. The parent dialog is roughly 640 *
540 pixels, with the top child dialog being 640*388. The ACTUAL size
of the top child is 640*2008 (strange application, but YES, that is
intentional. It has twenty "elements" which include a couple of
statics and a picture control. So you'll see a lot of "20"'s floating
around, that's why.).
Using information here:
http://support.microsoft.com/kb/262954
I found I had to tweak it a bit to get it correct, as my Windows
seemed to want to cap my window to 1030 tall, roughly the vertical
pixel count of my screen, I guess.
Parent dialog:
BOOL C4IN1RegDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_TopDlg.Create(C4IN1RegTopDialog::IDD, this);
m_BottomDlg.Create(C4IN1RegBottomDialog::IDD, this);
m_TopDlg.ShowWindow(SW_SHOW);
CRect rc;
GetWindowRect(rc);
MoveWindow(rc.left, rc.top, 648, 530,true);
m_TopDlg.MoveWindow(0,0,640, 388, true);
m_BottomDlg.ShowWindow(SW_SHOW);
m_BottomDlg.MoveWindow(0,390,640, 120, true);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
Top dialog (bottom is fine, so I'll avoid code-spammage)
BOOL C4IN1RegTopDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_iScrollPos = 0;
m_rect.top = 0;
m_rect.left = 0;
m_rect.right = 617;
m_rect.bottom = iOffsetFromTop + ((iItem) * (iOffsetBetween +
iSizeOfImageY));
SetWindowPos(NULL, m_rect.left, m_rect.top, m_rect.right,
m_rect.bottom, SWP_NOZORDER);
UpdateWindow();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void C4IN1RegTopDialog::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
m_iCurHeight = cy;
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL; // SIF_ALL = SIF_PAGE | SIF_RANGE | SIF_POS;
si.nMin = 0;
si.nMax = m_rect.Height() - m_iCurHeight;
si.nPage = si.nMax/20;
si.nPos = 0;
SetScrollInfo(SB_VERT, &si, TRUE);
}
void C4IN1RegTopDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*
pScrollBar)
{
// TODO: Add your message handler code here and/or call default
int nDelta;
int nMaxPos = m_rect.Height() - m_iCurHeight;
switch (nSBCode)
{
case SB_LINEDOWN:
if (m_iScrollPos >= nMaxPos)
return;
nDelta = min(nMaxPos/20,nMaxPos-m_iScrollPos);
//nDelta = min(max(nMaxPos/20,5),nMaxPos-m_iScrollPos);
break;
case SB_LINEUP:
if (m_iScrollPos <= 0)
return;
nDelta = -min(nMaxPos/20,m_iScrollPos);
//nDelta = -min(max(nMaxPos/20,5),m_iScrollPos);
break;
case SB_PAGEDOWN:
if (m_iScrollPos >= nMaxPos)
return;
nDelta = min(nMaxPos/20,nMaxPos-m_iScrollPos);
//nDelta = min(max(nMaxPos/20,5),nMaxPos-m_iScrollPos);
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
{
nDelta = (int)nPos - m_iScrollPos;
//int iPos = GetScrollPos(SB_VERT);
//nDelta = (int)iPos - m_iScrollPos;
}
break;
case SB_PAGEUP:
if (m_iScrollPos <= 0)
return;
nDelta = -min(nMaxPos/20,m_iScrollPos);
//nDelta = -min(max(nMaxPos/20,5),m_iScrollPos);
break;
default:
return;
}
m_iScrollPos += nDelta;
SetScrollPos(SB_VERT,m_iScrollPos, TRUE);
ScrollWindow(0,-nDelta);
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
Obviously this is eliminating a LOT of initialization, loading, etc.
Now, this works perfectly when the user presses on the ends of the
scrollbar. The dialog scrolls smoothly and it's all wonderful. But
when the user clicks and drags the thumbtrack, the SB_THUMBTRACK event
seems to not scroll all the way. It goes almost all the way, but it
seems like the last "tick" isn't there. I get all but the last
element. Then if the user taps the button, it scrolls a little more,
showing everything. If the user clicks the thumbtrack, it snaps back
to that "tick" before the end. I've stepped throught he code, and
when the user taps the thumbtrack, I get a position of 1592, as
opposed to 1620 that is the max (remember, my windowsize is 388, so
2008-388=1620, which I do get with the buttons).
Why isn't this last "tick" there? And how can I get it? The
thumbtrack size is dependent upon my nPage count, but I've tried to
monkey with that and that doesn't change the behaviour. It always
seems to be one tick short.
Thanks for the help,
~Scoots