window编程之滚动条(老式滚动条)

显示滚动条,只需要在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

 

posted @ 2013-09-10 22:12  SoulReaper  阅读(735)  评论(0编辑  收藏  举报