界面是人机交互的门户,对产品至关重要。在界面开发中只有想不到没有做不到的,有好的想法,当然要尝试着做出来。对滚动条的扩展,现在有很多类是的例子。
VS2015的代码编辑是非常强大的,其中有一个功能可以把滚动态变成MinMap,可以通过Options->Text Editor->C/C++->Scroll Bars中的Behavior
选项分类进行打开。
sublime也有这个功能,但没有VS的好用。变成MinMap后整个代码文档变成一个完整的缩微图,在你对代码比较熟悉的情况下,可以非常容易判断并定位到大致的函数位置。同时对特殊状态,如:错误信息,更新信息等进行标识。只要看一眼滚动条就能知道当前文档的情况,可以快速定位到相关文档位置。
优点多多: 当一个文件内容比较长时,在上面标注相关重要内容是非常方便的。用于只要一看滚动条上的相关标示,就能知道相关信息。不用再开辟窗口告诉用户,他想得到的有关信息。
有VS可作参考,做这个就比较容易。不知道微软有没有注册版权-_-!!。因此想到扩展Scroll Bar是个不错的主意,但windows系统并没有给这个机会,一般的窗口类都自带系统滚动条。系统自带的完全无法做出这种效果,只能自己做一个覆盖系统默认滚动条。
一、滚动条结构SCROLLINFO
typedef struct tagSCROLLINFO {
UINT cbSize; // 结构尺寸
UINT fMask; // 需要处理或返回的相关选项参数
int nMin; // 滚动条的最小值
int nMax; // 最大滚动范围
UINT nPage; // 一页有效行数
int nPos; // 当前滚动条
int nTrackPos; // 拖拽滚筒条时的位置
} SCROLLINFO, *LPCSCROLLINFO;
正常我们用到的的滚动条有下面一些元素,画了张图更容易理解点。
可以看到如果我们默认最小值=0时,实际需要的只有三个滚动条参数,最大可以滚动的范围nMax,一页可显示的行数nPage 和 当前行的显示位置nPos 这三个参数。
1、滚动数量计算
如滚动条能正常滚动到最后一行的位置。有100行记录,滚动最下面界面显示最后一行。为方便计算没条记录的行高固定。
- nPage = ClientHeight / rowHeight
- nMax = rowCount - 1 + nPage - 1
正常情况计算是总行数-1, 就是 nMax的值,应为要允许滚动到记录最后一条,因此需要多加一页的滚动数量。就产生了上面的nMax的公式。
// 只要超过1行就能滚动,因此需要多加一页的行数。
si.nMax = rowCount - 1 + yClient / rowHeight - 1;
si.nPage = yClient / rowHeight;
2、滑块尺寸计算
滑块的尺寸的尺寸按照上图的定义,滚动条的高度除以滚动范围再乘上每页数量可以得到。
滑块尺寸 = 滚动条高度 / 有效范围 * 每页数量
上述计算公式存在另外一个问题,如果记录量很大时就杯具,滑块会非常小,用户很难用鼠标抓到滑块。眼神犀利和伸手敏捷的才能完成这种艰巨任务。因此为滑容易定位的最小值。
s = max((float)((r.bottom - r.top) / (si.nMax - si.nMin) * si.nPage), 20.0f);
3、滑块位置计算
在图上看滑块有效的滑动位置是需要扣除滑块的大小的。
实际滑动位置 = (滚动条高度 - 滑块尺寸) / (有效范围 - 每页数量 + 1) * 当前行位置
有除法,就会存一些精度问题,所以算出位置后要检查一下位置是否超出客户区。
v = 0;
if (si.nPos > 0)
v = (int)((r.bottom - r.top - s) / (float)(si.nMax - si