计机羊咩咩 发表于 2014-8-25 22:55:19

滚动条范围限制

SCROLLINFO结构体存放着滑动条的一切信息

ScrollWindow会根据参数 “滑动” (bitbit) 当前客户区的数据,超出客户区的数据将不保留
滑动后客户区将出现无效区域,系统会自动获取并发送WM_PAINT消息
无效区域的大小及位置数据将会记录在PAINTSTRUCT中的rePaint结构里


无论上移还是下移,客户区的基点仍为(0,0),系统通过控制top和buttom两个参数实现对无效区域的定位
SetScrollInfo(hwnd,SB_VERT,&vScroll,TRUE);
GetScrollInfo(hwnd,SB_VERT,&vScroll);
if(iScrollPos != vScroll.nPos)
{
ScrollWindow(hwnd,0,cyChar * (iScrollPos - vScroll.nPos),NULL,NULL);
UpdateWindow(hwnd);
} 在改变滑动条位置之后,先存入SCROLLINFO(vScroll)数据再重新读取
此时在系统内部会计算当前滑动条的位置是否超出nMin和nMax,若超出范围则小小取大(nMin),大大取小(nMax)
否则保持滑动条当前位置

PaintBeg = max(0,vScroll.nPos + ps.rcPaint.top / cyChar);
PaintEnd = min(LineMath,vScroll.nPos + ps.rcPaint.bottom / cyChar);
for(;PaintBeg <= PaintEnd;PaintBeg++)
{
y = cyChar * (PaintBeg - vScroll.nPos);
StringCchLength(arr,3,&CchLength);
TextOut(hdc,0,y,arr,CchLength);
}
因为UpdateWindow后系统会立即发出一条不进队列的WM_PAINT消息
故改变滑动条位置后必须先保存当前SCROLLINFO数据
在重绘客户区时 ps.rcPaint.top / cyChar 计算出 ”滚动前“ 在客户区最后一行的数据位置
因此加上当前滑动块位置(vScroll.nPos)便可计算出将要读取的数据的位置(此位置是数据在缓冲区内的位置)
而 PaintBeg - vScroll.nPos可计算出数据在客户区重绘的位置(第n行)


当中还有各种细节不暇细说留给读者慢慢体会
若说的不好请指出 谢谢


计机羊咩咩 发表于 2014-8-25 23:01:55

:sad感觉自己讲这些好废   不过本人的确是因为这几个要点费了半个月的时间(中间存在一定量的闲聊:sad偷懒)现在想通了有点豁然开朗的感觉

OSKer 发表于 2014-10-13 18:25:14

谢谢楼主分享

tlwangxd 发表于 2014-11-12 09:19:02

学习

智商是硬伤 发表于 2015-8-18 08:33:35

{:7_146:}

彼岸花316 发表于 2015-8-19 14:32:06

多谢分享
页: [1]
查看完整版本: 滚动条范围限制