辅导:C++实例SDK中控制滚动条
来源:优易学  2011-10-27 12:47:18   【优易学:中国教育考试门户网】   资料下载   IT书店
  SDK的复杂性了,所谓复杂性,即在一个程序中,大大小小的事情都得程序编写者亲力亲为,Windows帮的忙很少,我在想,要是使用文本框之类的组件也得一句一句的写滚动条控制代码,那不累死!
  一、滚动条细节问题
  滚动条这玩意儿众所周知了,一个滚动条由三个部分组成:向上(左)移动按钮、卷动方块和向下(右)移动按钮,刚看到书上说这个「卷动方块」时还差点儿没明白过来。
  滚动条上常用的有五种操作:
  1.点击向上(左)移动按钮,向上(左)移动一行
  2.点击向下(右)移动按钮,向下(右)移动一行
  3.点击卷动方块上方空白处,向上翻一页
  4.点击卷动方块下方空白处,向下翻一页
  5.拖动卷动方块
  滚动条分水平滚动条和垂直滚动条,在Windows中就对应WM_HSCROLL和WM_VSCROLL两种消息,其中WM_HSCROLL是供左右移动的消息,WM_VSCROLL是供上下移动的消息。也就是说,响应滚动条的五种操作都是在这两个消息下执行的,比如当用户对垂直滚动条进行操作时,就会给Windows发出一个WM_VSCROLL消息,至于对这个垂直滚动条具体执行的是什么操作,是向上移动一行还是向下移动一行,这就要引出一个「通知码」的概念。
  这个「通知码」是怎么来的呢?当发送WM_VSCROLL或WM_HSCROLL消息时,会附带有wParam和lParam参数。其中lParam的作用没太弄明白,至于wParam参数,其分为一个低位字和高位字,我对这两个概念的认识也比较模糊。其中低字组是一个数值,而这个数值就是「通知码」。
  「通知码」是以SB(scroll bar)开头的标识符定义(全是大写名称),这些标识符比较好理解,比如SB_UP向上移动一行,SB_DOWN是向下移动一行。青年人网站提示:那现在如果要写响应将滚动条向下移动一行的代码,该如何写呢?看看下面的代码:
  case WM_VSCROLL: //响应垂直滚动条操作的消息
  switch(LOWORD(wParam))
  {
  case SB_DOWN: //向下移动通知码标识符
  //程序执行代码
  break;
  }
  头痛呀,本来有着很清晰的思路,但现在无缘无故多了个LOWORD,书中的前面几章也没讲这东西,只说了这是一个宏,在用GetSystemMetrics获取窗体显示区域大小时,到是用过LOWORD宏,除此之外还有一个HIWORD宏。
  case WM_SIZE:
  x = LOWORD(lParam);
  y = HIWORD(lParam);
  上面这段代码就是用来获取窗体显示区域的宽度和高度,不过使用的参数是lParam。看来要想明明白白的继续滚动条其它的知识点,还得先弄清楚这两个宏,另外还有lParam和wParam这两个参数,也是很常见的参数,得弄清楚。
  先了解一下lParam和wParam两个参数,lParam是一个UINT数据类型(unsigned int),wParam是一个LONG数据类型。在这两个参数中分别包含一个16位低位字和一个16位高位字。通过sizeof计算出,一个UINT类型占用4个字节,一个LONG也是占用4个字节,因为1个字节等于8比特,那4个字节的数据类型就是32比特,由此可知UINT和LONG是32位数据类型。我的基础知识不牢,又不得不恶补了一下。知道了lParam和wParam是32位数据类型,再来说说16位低位字和16位高位字。
  其中LOWORD是获取一个16位低位字,HIWORD是获取一个16位高位字,我估摸着就是将一个32位的数据类型分解成两个16位数据类型。
  通过wParam的低位字和高位字就能获取滚动条的「通知码」和卷动方块位置。
  wParam低位值 wParam高位值
  SB_THUMBTRACK 卷动方块时的目前位置
  SB_THUMBPOSITION 使用者释放鼠标键后卷动方块的最终位置
  其它的卷动列操作 忽略
  这样一来就明白了上面switch语句的作用。
  二、控制滚动条操作方法
  SetScrollRange (hwnd, iBar, iMin, iMax, bRedraw) ; //设置滚动条卷动方块滚动范围
  SetScrollPos (hwnd, iBar, iPos, bRedraw) ; //设置卷动方块的位置
  BOOL GetScrollRange(HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos); //获取滚动条卷动广场滚动范围
  int GetScrollPos(HWND hWnd, int nBar); //获取卷动方块的位置
  下面给个简单的示例代码:
  int iVscrollPos; //滚动条卷动方块位置
  SetScrollRange (hwnd, SB_VERT, 0, 20, FALSE) ; //滚动条最大范围为20
  SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ; //初始化滚动条位置
  case WM_VSCROLL: //垂直滚动条操作消息
  switch (LOWORD (wParam)) //wParam 16位低位值,即「通知码」
  {
  case SB_LINEDOWN: //滚动条向下移动一行
  iVscrollPos += 1;
  break;
  case SB_LINEUP: //滚动条向上移动一行
  iVscrollPos -= 1;
  break;
  case SB_PAGEDOWN: //滚动条向下翻一页
  break;
  case SB_PAGEUP: //滚动条向上翻一页
  break;
  case SB_TOP: //将卷动方块移置顶部
  iVscrollPos = 0;
  break;
  case SB_BOTTOM: //将卷动方块移置底部
  break;
  case SB_THUMBPOSITION: //拖动卷动方块释放鼠标后
  break;
  case SB_THUMBTRACK: //托运卷动方块
  break;
  case SB_ENDSROLL: //完成滚动操作?
  break;
  }
  上面的代码只是修改了iVscrollPos的值,要想让滚动条发生视觉改变,还得使用SetScrollPos来重新定位卷动方块的位置。
  //用min和max宏来调控iVscrollPos,确保iVscrollPos的值在SetScrollRange设置的范围之内
  iVscrollPos = max (0, min (iVscrollPos, NUMLINES - 1)) ;
  if (iVscrollPos != GetScrollPos (hwnd, SB_VERT)) //如果卷动方块有变动
  {
  //SB_VERT表示设置垂直滚动条的卷动方块位置,用SB_HORZ标识符是设置水平滚动条的卷动方块位置
  SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
  //滚动条的卷动方块已经作了改变,现在得设置重绘显示区域大小了
  //在这里是使用InvalidateRect来设置整个显示区域为无效,即重绘整个显示区域
  InvalidateRect (hwnd, NULL, TRUE) ;
  }
  好了,这第一种控制滚动条的方法就这么着了,其实就用到了SetScrollPos和SetScrollRange两个函数,相对比较简单。书中说这是一种很古老的方法了,在WIN32 API中新提供了两个操作滚动条的函数:SetScrollInfo和GetScrollInfo函数。这两个函数可以完成上面几个函数的功能,而且还多了两个特性:
  第一个特性
  可以修改卷动方块大小,主要是修改卷动方块的高度。
  第二个特性
  可以接受32位参数。在前面的方法中,是在一个32位数据类型中提取一个16位低位字和一个16位高位字来获取滚动条的各种信息,比如卷动方块位置,通知码等,而使用WIN32 API中这两个新的函数可以直接接受32位的参数。

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训