滚动条的使用中的两个需要注意的地方
在自绘窗口界面的时候,经常需要自己控制滚动条,下面就是以添加垂直滚动条为例,怎么自己增加滚动条的代码:
1.首先,在创建窗口Create的时候,设置window Style的风格:WS_VSCROLL
2.然后,一般在OnSize中,会调整滚动条的各项参数,比如range,page,pos等等。
其中,SCROLLINFO的nMin设置为0,nMax设置为要显示的全部内容的高度,当不需 要显示滚动条的时候,设置nMax为0即可。nPage设置为显示区域的高度。
代码如下:
处理WM_VSCROLL 消息,OnVScroll函数,代码如下:
3。最后,在OnPaint中绘制
INT64 iTop=-m_nVScrollPos;也就是在滚动了这么多的基础上开始绘制内容。
看起来没有问题是吧。确实么有多少问题。
这是一个树的控件,在我插入少与1000条 item的时候,么有任何问题。
问题1.
但是当我插入上万条item的时候,惊奇的发现,通过拉动滑块往下拉的过程中,在下拉1000条左右,就会发现中间会闪白板,然后又重新回到开始的内容开始显示了。
问题2.
当插入上万条item的时候,我发现点击向下箭头的时候,滑块在向下走,显示的内容也是在往下走,但是看起来的视觉却也是往下滚,这种情况下应该是看起来往上滚的。同样,在item个数小于1000条的时候 ,没有这个问题。
问题1的 原因:
OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
下面是关于 SB_THUMBPOSITION和 SB_THUMBTRACK的说明:
然后就明白了,原来这个时候的位置已经超过了16位的表示范围,自然就重新开始了。
解决方法是,在处理这两个消息的时候,采用GetScrollInfo来获取。
相关的代码:
问题2的原因:SB_LINEDOWN的处理,看看代码:
case SB_LINEDOWN:
if (m_nVScrollPos >= nMaxPos)
return;
nDelta = min(nMaxPos/100,nMaxPos-m_nVScrollPos);
break;
其中 int nMaxPos = (iTotalHeight - rc.Height());
这样其实每次按箭头向下滚动的值就会根据iTotalHeight也就是整个内容高度的变化而变化,这样当在恰当的时候,也就是每次刚好滚动到相对原来的位置靠下的地方时候,就会给人产生在向上滚的视觉效果。 如果每次刚好滚动cy的高度,那么视觉效果应该就是不动的了,相反,如果刚好滚动到相对原来的位置靠上的位置,那么就给人产生在向下滚动的视觉效果。 所以,很简单,如果要在按下箭头的时候,给人向上滚动的效果,就要滚动到相对靠下的位置。
比如,每次增加cy/10的值,那么肯定就是向上滚动的效果。所以把代码改动如下:
这样,两个问题都解决了。以前在设置高度不是很高的滚动条的时候,根本就么有
发现这两个问题,以后要注意下。