MFC垂直滚动条的实现

来源:互联网 发布:vmware 网络桥接 编辑:程序博客网 时间:2024/05/16 14:14

关于SCROLLINFO

  滚动条(卷动列)信息,结构定义为:
  typedef struct tagSCROLLINFO
  {
  UINT cbSize ; // set to sizeof (SCROLLINFO)
  UINT fMask ; // values to set or get
  int nMin ; // minimum range value
  int nMax ; // maximum range value
  UINT nPage ; // page size
  int nPos ; // current position
  int nTrackPos ; // current tracking position
  }SCROLLINFO
  函数SetScrollInfo和GetScrollInfo的参数LPSCROLLINFO lpsi指向该结构。
  在程序中,可以定义如下的SCROLLINFO结构型态:
  SCROLLINFO si ;
  在调用SetScrollInfo或GetScrollInfo之前,必须将cbSize字段设定为结构的大小:
  si.cbSize = sizeof (si) ;
  或
  si.cbSize = sizeof (SCROLLINFO) ;
  逐渐熟悉Windows后,您就会发现另外几个结构像这个结构一样,第一个字段指出了结构大小。这个字段使将来的Windows版本可以扩充结构并添加新的功能,并且仍然与以前编译的版本兼容。
  把fMask字段设定为一个以上以SIF前缀开头的旗标,并且可以使用C的位操作OR运算子(|)组合这些旗标。
  SetScrollInfo函数使用SIF_RANGE旗标时,必须把nMin和nMax字段设定为所需的卷动列范围。GetScrollInfo函数使用SIF_RANGE旗标时,应把nMin和nMax字段设定为从函数传回的目前范围。
  SIF_POS旗标也一样。当通过SetScrollInfo使用它时,必须把结构的nPos字段设定为所需的位置。可以通过GetScrollInfo使用SIF_POS旗标来取得目前位置。
  使用SIF_PAGE旗标能够取得页面大小。用SetScrollInfo函数把nPage设定为所需的页面大小。GetScrollInfo使用SIF_PAGE旗标可以取得目前页面的大小。如果不想得到比例化的卷动列,就不要使用该旗标。
  当处理带有SB_THUMBTRACK或SB_THUMBPOSITION通知码的WM_VSCROLL或WM_HSCROLL消息时,通过GetScrollInfo只使用SIF_TRACKPOS旗标。从函数的传回中,SCROLLINFO结构的nTrackPos字段将指出目前的32位的卷动方块位置。
 
 
[cpp] view plaincopy
  1. //头文件中添加如下内容,m_page记得初始化  
  2. int m_page;  
  3.   
  4. int GetScrollPos(int nBar, UINT nSBCode);  
  5. void ScrollClient(int nBar, int nPos) ;  
  6. void VScrool(int nBar, UINT nSBCode) ;  
[cpp] view plaincopy
  1.    
[cpp] view plaincopy
  1. //在OnInitDialog里添加如下代码为对话框创建一个垂直滚动条  
  2.     CRect rc;    
  3.     GetClientRect(&rc);    
  4.     
  5.     const SIZE sz = { rc.right - rc.left, rc.bottom - rc.top };    
  6.   
  7.     SCROLLINFO si;    
  8.     si.cbSize = sizeof(SCROLLINFO);    
  9.     si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;    
  10.     si.nPos = si.nMin = 1;    
  11.     
  12.     si.nMax = sz.cy*m_page;    
  13.     si.nPage = sz.cy;    
  14.     SetScrollInfo(SB_VERT, &si, FALSE);  //此函数将产生一个垂直滚动条  
//为对话框添加下列函数
[cpp] view plaincopy
  1. void ChyperlinkDlg::ScrollClient(int nBar, int nPos)    
  2. {    
  3.     static int s_prevx = 1;    
  4.     static int s_prevy = 1;    
  5.     
  6.     int cx = 0;    
  7.     int cy = 0;    
  8.     
  9.     int& delta = cy;    
  10.     int& prev = s_prevy;  
  11.     
  12.     delta = prev - nPos;    
  13.     prev = nPos;    
  14.     
  15.     if(cx || cy)    
  16.     {    
  17.         ScrollWindow(cx, cy, NULL, NULL);    
  18.     }    
  19. }    
[cpp] view plaincopy
  1. int ChyperlinkDlg::GetScrollPos(int nBar, UINT nSBCode)    
  2. {    
  3.     SCROLLINFO si;    
  4.     si.cbSize = sizeof(SCROLLINFO);    
  5.     si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;    
  6.     GetScrollInfo(nBar, &si);    
  7.     
  8.     const int minPos = si.nMin;    
  9.     const int maxPos = si.nMax - (si.nPage - 1);    
  10.     
  11.     int result = -1;    
  12.     
  13.     switch(nSBCode)    
  14.     {    
  15.     case SB_LINEUP /*SB_LINELEFT*/:    
  16.         result = max(si.nPos - 1, minPos);    
  17.         break;    
  18.     case SB_LINEDOWN /*SB_LINERIGHT*/:    
  19.         result = min(si.nPos + 1, maxPos);    
  20.         break;    
  21.     case SB_PAGEUP /*SB_PAGELEFT*/:    
  22.         result = max(si.nPos - (int)si.nPage, minPos);    
  23.         break;    
  24.     case SB_PAGEDOWN /*SB_PAGERIGHT*/:    
  25.         result = min(si.nPos + (int)si.nPage, maxPos);    
  26.         break;    
  27.     case SB_THUMBPOSITION:    
  28.         // do nothing     
  29.         break;    
  30.     case SB_THUMBTRACK:    
  31.         result = si.nTrackPos;    
  32.         break;    
  33.     case SB_TOP /*SB_LEFT*/:    
  34.         result = minPos;    
  35.         break;    
  36.     case SB_BOTTOM /*SB_RIGHT*/:    
  37.         result = maxPos;    
  38.         break;    
  39.     case SB_ENDSCROLL:    
  40.         // do nothing     
  41.         break;    
  42.     }    
  43.     
  44.     return result;    
  45. }    

[cpp] view plaincopy
  1. void ChyperlinkDlg::VScrool(int nBar, UINT nSBCode)    
  2. {    
  3.     const int scrollPos = GetScrollPos(nBar,nSBCode);    
  4.     
  5.     if(scrollPos == -1)    
  6.         return;    
  7.     
  8.     SetScrollPos(nBar, scrollPos, TRUE);    
  9.     ScrollClient(nBar, scrollPos);    
  10. }    

//最后为对话框添加WM_VSCROLL消息响应函数

[cpp] view plaincopy
  1. void ChyperlinkDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)  
  2. {  
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值  
  4.   
  5.     VScrool(SB_VERT,nSBCode);  
  6.   
  7.     CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);  
  8. }  

好啦,大功告成~

原创粉丝点击