MFC中Cwnd窗口添加滚动条

MFC中Cwnd窗口添加滚动条

http://blog.youkuaiyun.com/chaozi2008/article/details/8116449

最近一个项目需要用到从CWnd派生的窗口添加滚动条,自己上网查过好多资料,但都没有很明确的说明这个应该怎么做,经过自己的摸索和努力,终于给完成了。在这里分享一下我的方法:

第一:设置窗口属性。首先,Cwnd是自带有滚动条属性的,在create时加上WS_HSCROLL| WS_VSCROLL风格,则创建出的窗口就会带有滚动条了。

[cpp]  view plain  copy
  1. if (!m_AttributeWnd.Create (NULL,NULL,WS_TABSTOP | WS_CHILD | WS_HSCROLL| WS_VSCROLL ,rect, this,12331))  
  2.     {  
  3.         TRACE0("Failed to create wndAttri wnd\n");  
  4.         return;      // fail to create  
  5.     }  

这时候你会发现,滑块大小是固定的,就是那么大,而且拖动后松开鼠标就回到开始的位置了。怎么会这样呢?嘿嘿,原来Windows自己是不会自动改变滑块位置的,需要程序自己去设置滑块的位置,这就是第二步。

第二:设置滑块位置。这里需要在对应的响应函数中添加处理代码,以水平滚动条为例:

[cpp]  view plain  copy
  1. void CAtrributeWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)  
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.   
  5.     static int oldpos = 0;  
  6.     int minpos = 0;  
  7.     int maxpos = 0;  
  8.     GetScrollRange(SB_HORZ, &minpos, &maxpos);   
  9.     maxpos = GetScrollLimit(SB_HORZ);  
  10.   
  11.     // Get the current position of scroll box.  
  12.     int curpos = GetScrollPos(SB_HORZ);  
  13.   
  14.     // Determine the new position of scroll box.  
  15.     switch (nSBCode)  
  16.     {  
  17.     case SB_LEFT:      // Scroll to far left.  
  18.         curpos = minpos;  
  19.         break;  
  20.   
  21.     case SB_RIGHT:      // Scroll to far right.  
  22.         curpos = maxpos;  
  23.         break;  
  24.   
  25.     case SB_ENDSCROLL:   // End scroll.  
  26.         break;  
  27.   
  28.     case SB_LINELEFT:      // Scroll left.  
  29.         if (curpos > minpos)  
  30.             curpos--;  
  31.         break;  
  32.   
  33.     case SB_LINERIGHT:   // Scroll right.  
  34.         if (curpos < maxpos)  
  35.             curpos++;  
  36.         break;  
  37.   
  38.     case SB_PAGELEFT:    // Scroll one page left.  
  39.         {  
  40.             // Get the page size.   
  41.             SCROLLINFO   info;  
  42.             GetScrollInfo(SB_HORZ, &info, SIF_ALL);  
  43.   
  44.             if (curpos > minpos)  
  45.                 curpos = max(minpos, curpos - (int) info.nPage);  
  46.         }  
  47.         break;  
  48.   
  49.     case SB_PAGERIGHT:      // Scroll one page right.  
  50.         {  
  51.             // Get the page size.   
  52.             SCROLLINFO   info;  
  53.             GetScrollInfo(SB_HORZ, &info, SIF_ALL);  
  54.   
  55.             if (curpos < maxpos)  
  56.                 curpos = min(maxpos, curpos + (int) info.nPage);  
  57.         }  
  58.         break;  
  59.   
  60.     case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position  
  61.         curpos = nPos;      // of the scroll box at the end of the drag operation.  
  62.         break;  
  63.   
  64.     case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the  
  65.         curpos = nPos;     // position that the scroll box has been dragged to.  
  66.         break;  
  67.     }  
  68.   
  69.     // Set the new position of the thumb (scroll box).  
  70.     SetScrollPos(SB_HORZ, curpos);  
  71.     ScrollWindow(oldpos-curpos,0);  
  72.   
  73.     oldpos = curpos;  
  74.     UpdateWindow();  
  75.   
  76.     CWnd::OnHScroll(nSBCode, nPos, pScrollBar);  
  77. }  
现在马上试试,是不是可以拖动滚动条了。但是新的问题出来了,滑块大小没有变化,不会像Windows中滚动条里边,滑块会随着窗口变化,窗口小滑块也变小,窗口变大,滑块也会随着变大,直到滑块消失。此时,应该如何解决这个问题呢?那就是下一步,设置滑块风格和滚动条范围。

第三:设置滚动条范围。SetScrollRange()可以完成这个操作,但是如果想要滑块跟着变化大小,这里推荐使用SetScrollInfo()函数,此函数中有个最为重要的参数为SCROLLINFO结构体,定义如下:

[cpp]  view plain  copy
  1. typedef struct tagSCROLLINFO  
  2. {  
  3.     UINT    cbSize; //设为sizeof(SCROLLINFO)  
  4.     UINT    fMask;  
  5.     int     nMin;  
  6.     int     nMax;  
  7.     UINT    nPage;  
  8.     int     nPos;  
  9.     int     nTrackPos;  
  10. }   SCROLLINFO, FAR *LPSCROLLINFO;  

成员说明:
cbSize: SCROLLINFO结构长度字节数,该值在设置和查询参数时都必须填写。
fMask: 指定结构中的哪些成员是有效,该值共有如下5种选择,可以选择多种用“OR”组合起来,该值在设置和查询参数时都必须填写。
SIF_ALL      :整个结构都有效
SIF_DISABLENOSCROLL:该值仅在设定参数时使用,视控件参数设定的需要来对本结构的成员进行取舍。
SIF_PAGE      :nPage成员有效
SIF_POS      :nPos成员有效
SIF_RANGE     :nMin和nMax成员有效
nMin:滚动范围最小值
nMax:滚动范围最大值
nPage:页尺寸,用来确定比例滚动框的大小
nPos:滚动框的位置
nTrackPos:拖动时滚动框的位置,该参数只能查询,不能设置。

然后在onsize()函数中设这滚动条的大小范围:

[cpp]  view plain  copy
  1. void CAtrributeWnd::OnSize(UINT nType, int cx, int cy)  
  2. {  
  3.     CWnd::OnSize(nType, cx, cy);  
  4.   
  5.     //设置滚动条范围  
  6.     SCROLLINFO si;  
  7.     si.cbSize = sizeof(si);  
  8.     si.fMask = SIF_RANGE | SIF_PAGE;  
  9.     si.nMin = 0;  
  10.     si.nMax = 998;  
  11.     si.nPage = cx;  
  12.     SetScrollInfo(SB_HORZ,&si,TRUE);  
  13.     si.nMax = 496;  
  14.     si.nPage = cy;  
  15.     SetScrollInfo(SB_VERT,&si,TRUE);  
  16.   
  17.     int icurxpos = GetScrollPos(SB_HORZ);  
  18.     int icurypos = GetScrollPos(SB_VERT);  
  19.       
  20.     if (icurxpos < m_ixoldpos || icurypos < m_iyoldpos)  
  21.     {  
  22.         ScrollWindow(m_ixoldpos-icurxpos,0);  
  23.         ScrollWindow(0,m_iyoldpos-icurypos);  
  24.   
  25.     }     
  26.     m_ixoldpos = icurxpos;  
  27.     m_iyoldpos = icurypos;  
  28.   
  29.     Invalidate(TRUE);  
  30. }  

现在看看是不是达到预期的要求了呢!!


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值