zoukankan      html  css  js  c++  java
  • MFC 控件编程之水平滚动条跟垂直滚动条

            MFC 控件编程之水平滚动条跟垂直滚动条

    一点水平滚动条的操作

      首先在操作滚动条的时候.我们要知道滚动条的一些属性. 比如我们要设置 最大值 最小值. 以及每次递增的值是多少.都要设置.

    所有就有一个结构.专门存储了滚动条信息. 而我们在对话框一启动就要进行控件初始化.下方看下结构.

    typedef struct tagSCROLLINFO {
      UINT cbSize;                         自身大小
      UINT fMask;                          滚动条的范围.左边->右边方式.
      int  nMin;                              滚动条最小值
      int  nMax;                             滚动条最大值
      UINT nPage;                          每次滚动的值
      int  nPos;                              位置
      int  nTrackPos;                        位置
    } SCROLLINFO, *LPSCROLLINFO;

    然后我们使用封装好的API 进行设置.

    BOOL SetScrollInfo( LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE );

    滚动条是一个类. MFC给我们封装好的.所以我们直接使用封装好的函数即可.

    初始化的时候需要做的.

      SCROLLINFO si = { 0 };
        si.cbSize = sizeof(SCROLLINFO);
        si.fMask = SIF_RANGE | SIF_PAGE;   //设置范围.
        si.nMin = 0;                         //最小值1
        si.nMax = 100;                     //最大值100
        si.nPage = 1;                     //每次递增1
    
        //设置滚动条信息.
        m_hor.SetScrollInfo(&si);

    此时我们初始化好了.但是我们要对它的消息进行处理.才可以使用这个滚动条.

    二丶指定点击水平滚动条消息  WM_HSCROLL

    我们第一个就是要对点击这个滚动条的消息进行处理.

    对话框-> 属性 -> 事件 -> 响应消息.

    我们在单击水平滚动条里面.判断是哪个消息进行不同的处理即可. 比如 点击左边箭头. 点击右边箭头. 等等. 值递增.

    代码如下.当我们响应了单击滚动条信息的时候

    void C滚动条Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
      参数1 代表的是消息.
    //处理滚动条的每一个消息.进行处理. switch (nSBCode) { case SB_THUMBTRACK: //判断消息是否是拉动滚动条 break; case SB_LINELEFT: //箭头向左的消息 break; case SB_LINERIGHT: //箭头向右的消息 break; case SB_PAGELEFT: // 值递减.也就是向左翻页 break; case SB_PAGERIGHT: //值递增.也就是向右翻页. break; break; default: break; } CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); }

    没有具体写代码.当我们写代码的时候.要先获取当前滚动条的状态信息.

    1.点击右箭头位置递增

    void C滚动条Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    
        SCROLLINFO si = { 0 };
        si.cbSize = sizeof(SCROLLINFO);
        si.fMask = SIF_ALL;  //获取所有滚动条消息
        pScrollBar->GetScrollInfo(&si); //通过这个函数.获取滚动条信息.
    
        //si里面就有所有的信息.
        int nNewPos = si.nPos;  //获取最新的位置.
    
        //处理滚动条的每一个消息.进行处理.
        switch (nSBCode)
        {
        case SB_THUMBTRACK:  //判断消息是否是拉动滚动条
            
            break;
        case SB_LINELEFT:   //箭头向左的消息
            break;
    
        case SB_LINERIGHT:  //箭头向右的消息
            nNewPos += 2; //我们的值加了.所以设置到滚动条里面
            break;
        case SB_PAGELEFT:   // 值递减.也就是向左翻页
            break;
        case SB_PAGERIGHT:  //值递增.也就是向右翻页.
            break;
            break;
    
        default:
            break;
        }
        
        pScrollBar->SetScrollPos(nNewPos);
        CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
    }

    思路:

      1.获取当前滚动条信息. 因为当前滚动条信息里面有滚动条里最新的位置.

      2.保存位置.

      3.设置到滚动条上面.

    参数三就是当前滚动条类.所以我们可以使用 封装好的方法.用来获取当前信息.以及设置当前位置到这个滚动条上面.

    2.一个正常使用的垂直滚动条的完整代码.

    void C滚动条Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    
        SCROLLINFO si = { 0 };
        si.cbSize = sizeof(SCROLLINFO);
        si.fMask = SIF_ALL;  //获取所有滚动条消息
        pScrollBar->GetScrollInfo(&si); //通过这个函数.获取滚动条信息.
    
        //si里面就有所有的信息.
        int nNewPos = si.nPos;  //获取最新的位置.
    
        //处理滚动条的每一个消息.进行处理.
        switch (nSBCode)
        {
        case SB_THUMBTRACK:  //判断消息是否是拉动滚动条
            nNewPos = nPos;            //如果拖动滑块.那么参数2就是最新位置.
            break;
        case SB_LINELEFT:   //箭头向左的消息
            nNewPos -= 2; //我们的值加了.所以设置到滚动条里面
            break;
    
        case SB_LINERIGHT:  //箭头向右的消息
            nNewPos += 2; //我们的值加了.所以设置到滚动条里面
            break;
        case SB_PAGELEFT:   // 值递减.也就是向左翻页    点击滚动条左边空格的时候
            nNewPos -= si.nPage;
            break;
        case SB_PAGERIGHT:  //值递增.也就是向右翻页.
            nNewPos += si.nPage;
            break;
            break;
    
        default:
            break;
        }
        
        //需要判断位置是否超出.
        if (nNewPos > si.nMax)
        {
            nNewPos = si.nMin;
        }
        if (nNewPos < si.nMin)
        {
            nNewPos = si.nMin;
        }
        pScrollBar->SetScrollPos(nNewPos);
        CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
    }

    三丶总结

      1.首先要设置滚动条的各项属性. 有一个结构体SCROLLINFO .并且使用封装的方法进行初始化 SetScrollInfo(&结构)

      2.要在对话框属性上面.响应滚动条单击的消息.  WM_HSCROLL

      3.此时响应过后的回调函数会有三个参数.

          参数1 : 滚动条信息. 因为我们还要处理其余信息.

          参数2: 当滚动条拖动的时候.保存拖动过后的最新位置.

          参数3: 滚动条信息. 保存了滚动条的当前状态信息.

      4.需要通过第三个参数. 获取滚动条当前状态信息. GetScrollInfo(&结构) 我们的结构的标志要设置为获取全部信息的标志.

      5.创建一个变量.保存当前状态中的垂直滚动条的位置.

      6.通过SWITCH 语句.判断不同的滚动条消息. 进行位置的设置.

      7.判断是否越界.如果越界.设置为滚动条最小值. 

      8.使用封装好的函数.设置到当前滚动条中. 也就是设置位置.SetScrollPos(新的位置)

     四丶垂直滚动条的使用

    垂直滚动条跟水平滚动条是一样的.只不过处理的消息不一样了.下方特贴一份源码.学习源码即可.跟上面一样.

    int ChyperlinkDlg::GetScrollPos(int nBar, UINT nSBCode)    
    {    
        SCROLLINFO si;    
        si.cbSize = sizeof(SCROLLINFO);    
        si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;    
        GetScrollInfo(nBar, &si);    
        
        const int minPos = si.nMin;    
        const int maxPos = si.nMax - (si.nPage - 1);    
        
        int result = -1;    
        
        switch(nSBCode)    
        {    
        case SB_LINEUP /*SB_LINELEFT*/:       //消息不一样了.
            result = max(si.nPos - 1, minPos);    
            break;    
        case SB_LINEDOWN /*SB_LINERIGHT*/:    
            result = min(si.nPos + 1, maxPos);    
            break;    
        case SB_PAGEUP /*SB_PAGELEFT*/:    
            result = max(si.nPos - (int)si.nPage, minPos);    
            break;    
        case SB_PAGEDOWN /*SB_PAGERIGHT*/:    
            result = min(si.nPos + (int)si.nPage, maxPos);    
            break;    
        case SB_THUMBPOSITION:    
            // do nothing     
            break;    
        case SB_THUMBTRACK:    
            result = si.nTrackPos;    
            break;    
        case SB_TOP /*SB_LEFT*/:    
            result = minPos;    
            break;    
        case SB_BOTTOM /*SB_RIGHT*/:    
            result = maxPos;    
            break;    
        case SB_ENDSCROLL:    
            // do nothing     
            break;    
        }    
        
        return result;    
    }    

     

  • 相关阅读:
    洛谷P3384 【模板】树链剖分
    hdu3518 Boring counting(后缀数组)
    CSL 的密码(后缀数组)
    洛谷P3809 【模板】后缀排序
    洛谷P2387 [NOI2014]魔法森林(LCT)
    洛谷P3366 【模板】最小生成树(LCT)
    Stanford机器学习课程(Andrew Ng)
    操作系统存储器管理选择题精练
    实验12:Problem I: 成绩排序
    实验12:Problem H: 整型数组运算符重载
  • 原文地址:https://www.cnblogs.com/iBinary/p/9656925.html
Copyright © 2011-2022 走看看