滚动条第四章节(添加一个自适应的滚动条)

自适应滚动条
为了得到一个自适应滚动条,你需要告诉Windows滚动条所覆盖区域的最大值和最小值,当前滚动条的位置以及滚动条滑块(Thumb,也称”页大小”)的大小。
一个比较麻烦的方法,是当显示区域最大值是可变的情况。这和GDI中的坐标计算有点不同:GDI中,一段范围,是不包含终结点的。这会导致在代码中出现类似”-1″这样的代码,用来对公式做出补偿修正。
为了实现这个目标,我们需要额外定义如下的变量:
滚动条第四章节(添加一个自适应的滚动条)
文章图片
我稍后会解释为什么这里的变量名叫做g_yOrigin。
核心代码
接下来,我们会定义一个帮助函数,它将会是滚动条操作的核心。
我们来看看这个函数:它将会接收一个代表滚动条目标位置的参数,然后函数对这个参数进行有效性校验,然后对窗口的内容进行必要的滚动,最后,设置滚动条的相关参数来匹配窗口滚动之后的状态。
滚动条第四章节(添加一个自适应的滚动条)
文章图片
有时候,我们仅仅是希望以一个相对的位置进行滚动,则可以使用下面的函数。
滚动条第四章节(添加一个自适应的滚动条)
文章图片
当窗口大小发生变化时,我们需要重新计算”一页”中可显示的条目个数。这个计算过程,会要求滚动条的Thumb位置进行自动调整,所以,我们这里在ON_SIZE消息处理例程中执行力一次Dummy Scroll,这将触发滚动条自身的自动调整。
滚动条第四章节(添加一个自适应的滚动条)
文章图片
WM_VSCROLL消息处理例程比较容易理解。当我们按行或者按页进行滚动时,实际上我们会在一个指定的方向上做一些对应的滚动。当用户拖动滚动条滑块时,我们将滚动到一个指定的位置。当用户拖动滚动条的顶部或底部时,我们也会做相对应的计算。
滚动条第四章节(添加一个自适应的滚动条)
文章图片
当然,我们还需要将消息处理例程和消息进行关联,如下图所示:
滚动条第四章节(添加一个自适应的滚动条)
文章图片
最后,我们需要让我们的绘制函数知道滚动条的存在。幸运的是,我们可以借助GDI的转换,实现这个目的,并且完全不需要改动PaintSimpleContent函数。
滚动条第四章节(添加一个自适应的滚动条)
文章图片
通过修改窗口的原点,我们的PaintSimpleContent函数还是和没有滚动条的时候一样正常工作。借助于GDI的坐标转换,我们可以愉快的在坐标点(0,0)上绘制条目,而绘制的像素将出现在新设定的原点的位置。
所以,你现在应该可以明白,为什么这里的变量叫做g_yOrigin了吧?
家庭作业
【滚动条第四章节(添加一个自适应的滚动条)】在上面的OnVscroll函数中有一个隐藏的Bug。看看可以找到它吗?然后试试能不能修复一下?
滚动条第四章节(添加一个自适应的滚动条)
文章图片

    推荐阅读