I encountered a problem scrolling large areas in a CScrollView. When slowly moving the scrollbar from top to bottom the behaviour is the following: At first the scrolling is working fine. At some point scrolling further does not do anything, instead the top of the area is shown. At some point scrolling starts again from the top.
Here is a small example. I created a new MFC project using the document-view-model and used a CScrollView as the view class. I added the following code to create a large area and add some text to show, which part is currently shown:
void CScrollViewTest2View::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100*1000;
SetScrollSizes(MM_TEXT, sizeTotal);
for(int i = 0; i < 1000; i++)
{
CStatic* label = new CStatic();
label->Create(NULL, WS_CHILD | WS_VISIBLE, CRect(10,10 + i*100,100,30 + i*100), this);
CString text;
text.Format(L"%d",i);
label->SetWindowText(text);
}
}
If I add the following code I see that during the scrolling the 'nPos' value seems to wrap around. This would explain the behaviour. But I don't know how to work around that.
BOOL CScrollViewTest2View::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll )
{
CString msg;
msg.Format(L"nPos = %u\n",nPos);
TRACE(msg);
return CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);
}
and here is the output when it stops scrolling:
nPos = 27826
nPos = 29190
nPos = 30281
nPos = 31372
nPos = 31645
nPos = 32464
nPos = 4294938588
nPos = 4294939134
nPos = 4294939407
nPos = 4294939680
nPos = 4294940225
nPos = 4294940771
So is there a way to use a CScrollView to completely scroll down a large area?
The code of the sample project can be found here.
The static controls are not placed where you expect them to be. To see the problem, run the following code:
r.top
should be32767
. This is because of 16bit limits in Windows. All of the controls whose x/y position exceed this limit, are pushed back to this position.OnScroll
function suffers from a similar problem, however this can be fixed by usingGetScrollInfo
Add
ON_WM_VSCROLL
to message map and the followingOnVScroll
override to your classThis will not solve the problem with windows controls whose x/y position is greater than 32,000, but at least it will scroll the DC as expected.
For testing, remove the static controls. You can use the draw function below to test the painting: