显示滚动条,只需要在CreateWindow的第三个参数中包括窗口样式(WS)标识符WS_VSCROLL(垂直卷动)和/或WS_HSCROLL(水平卷动)即可
这些卷动列通常放在窗口的右部和底部,伸展为显示区域的整个长度或宽度。显示区域不包含卷动列所占据的空间。
但是有这些是远远不够滴.
1.首先,滚动条是有范围的.在内定情况下,滚动条的范围是从0(顶部或左部)至100(底部或右部)。但是如果要改变,应该这么做.
SetScrollRange (hwnd, iBar, iMin, iMax, bRedraw) ; /* 参数iBar为SB_VERT或者SB_HORZ, iMin和iMax分别是范围的最小值和最大值。 如果想要Windows根据新范围重画滚动条,则设置bRedraw为TRUE */
有个常识:卷动方块的位置总是离散的整数值。如果你的范围过于小的话,比如0-5,那么整个滚动条只能定位五个位置。
2.我们可以手动设置新的滚动方块的位置:
SetScrollPos (hwnd, iBar, iPos, bRedraw) ; /* 参数iPos是新位置,它必须在iMin至iMax的范围内 */
3.获取滚动块的位置和范围可以使用GetScrollRange和GetScrollPos;
4.当程序内使用滚动条时,程序与Windows共同负责维护滚动条以及更新卷动方块的位置。
下面是Windows对滚动条的处理:
-
- 处理所有滚动条鼠标事件
- 当使用者在滚动条内单击鼠标时,提供一种「反相显示」的闪烁
- 当使用者在滚动条内拖动卷动方块时,移动卷动方块
- 为包含滚动条窗口的窗口消息处理程序发送滚动条消息
- 处理所有滚动条鼠标事件
以下是程序应该完成的工作:
- 1.初始化滚动条的范围和位置。SetScrollRange和SetScrollPos
- 2.处理窗口消息处理程序的滚动条消息。WM_VSCROLL,WM_HSCROLL
- 3.更新滚动条内卷动方块的位置。在switch中的SB_**消息中处理更新
- 4.更改显示区域的内容以响应对滚动条的更改。发送InvalidateRect (hwnd, NULL, TRUE) ;函数强制重绘显示区.
在用鼠标单击滚动条或者拖动卷动方块时,Windows给窗口消息处理程序发送WM_VSCROLL(供上下移动)和WM_HSCROLL(供左右移动)消息。
和所有的消息一样,WM_VSCROLL和WM_HSCROLL也带有wParam和lParam(忽略)消息参数。
wParam消息参数被分为一个低字组和一个高字组。wParam的低字组是一个数值,它指出了鼠标对滚动条进行的操作。这个数值被看作一个「通知码」。通知码的值由以SB开头的标识符定义
#define SB_LINEUP 0 //点击上边的箭头产生 #define SB_LINELEFT 0 //点击左边的箭头产生 #define SB_LINEDOWN 1//点击下边的箭头产生 #define SB_LINERIGHT 1//点击右边的箭头产生 #define SB_PAGEUP 2 //在垂直滚动条上面空白处且在滚动方块上面点击产生 #define SB_PAGELEFT 2//在垂直滚动条上面空白处且在滚动方块上面点击产生 #define SB_PAGEDOWN 3//在垂直滚动条上面空白处且在滚动方块下面点击产生 #define SB_PAGERIGHT 3//在垂直滚动条上面空白处且在滚动方块下面点击产生 #define SB_THUMBPOSITION 4//释放滚动方块产生 #define SB_THUMBTRACK 5//点击滚动方块拖着走产生 #define SB_TOP 6 #define SB_LEFT 6 #define SB_BOTTOM 7 #define SB_RIGHT 7 #define SB_ENDSCROLL 8//释放点击产生
添加有关SB_*通知码的代码如下:
case WM_VSCROLL: switch (LOWORD (wParam)) { case SB_LINEUP: iVscrollPos -= 1 ; break ; case SB_LINEDOWN: iVscrollPos += 1 ; break ; case SB_PAGEUP: iVscrollPos -= cyClient / cyChar ; break ; case SB_PAGEDOWN: iVscrollPos += cyClient / cyChar ; break ; case SB_THUMBPOSITION: iVscrollPos = HIWORD (wParam) ; break ; default : break ; } iVscrollPos = max (0, min (iVscrollPos, NUMLINES - 1)) ; if (iVscrollPos != GetScrollPos (hWnd, SB_VERT)) { SetScrollPos (hWnd, SB_VERT, iVscrollPos, TRUE) ; InvalidateRect (hWnd, NULL, TRUE) ; } return 0 ;
InvalidateRect这个函数是将WM_PAINT消息排进消息队列里面,不能做到及时刷新,如果需要及时刷新,可以在后面加上UpdateWindow这个函数.
以上是滚动条比较过时的做法,但是可以良好运行,新式做法看下一篇文章
附加一份实现滚动条的代码(C++)
突然发现不能传附件,Orz......传到git吧
https://github.com/shangbo/windows_api/tree/master/scroll
2013-09-10.21:39:11