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

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

一点水平滚动条的操作

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

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

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

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

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

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

初始化的时候需要做的.

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

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

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

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

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

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

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

1void C滚动条Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 2{  参数1 代表的是消息. 3 4 //处理滚动条的每一个消息.进行处理. 5 switch (nSBCode) 6 { 7 case SB_THUMBTRACK: //判断消息是否是拉动滚动条 8 break; 9 case SB_LINELEFT: //箭头向左的消息 10 break; 11 12 case SB_LINERIGHT: //箭头向右的消息 13 break; 14 case SB_PAGELEFT: // 值递减.也就是向左翻页 15 break; 16 case SB_PAGERIGHT: //值递增.也就是向右翻页. 17 break; 18 break; 19 20 default: 21 break; 22 } 23 CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); 24}

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

1.点击右箭头位置递增

1void C滚动条Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 2{ 3 4 SCROLLINFO si = { 0 }; 5 si.cbSize = sizeof(SCROLLINFO); 6 si.fMask = SIF_ALL; //获取所有滚动条消息 7 pScrollBar->GetScrollInfo(&si); //通过这个函数.获取滚动条信息. 8 9 //si里面就有所有的信息. 10 int nNewPos = si.nPos; //获取最新的位置. 11 12 //处理滚动条的每一个消息.进行处理. 13 switch (nSBCode) 14 { 15 case SB_THUMBTRACK: //判断消息是否是拉动滚动条 16 17 break; 18 case SB_LINELEFT: //箭头向左的消息 19 break; 20 21 case SB_LINERIGHT: //箭头向右的消息 22 nNewPos += 2; //我们的值加了.所以设置到滚动条里面 23 break; 24 case SB_PAGELEFT: // 值递减.也就是向左翻页 25 break; 26 case SB_PAGERIGHT: //值递增.也就是向右翻页. 27 break; 28 break; 29 30 default: 31 break; 32 } 33 34 pScrollBar->SetScrollPos(nNewPos); 35 CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); 36}

思路:

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

  2.保存位置.

  3.设置到滚动条上面.

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

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

1void C滚动条Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 2{ 3 4 SCROLLINFO si = { 0 }; 5 si.cbSize = sizeof(SCROLLINFO); 6 si.fMask = SIF_ALL; //获取所有滚动条消息 7 pScrollBar->GetScrollInfo(&si); //通过这个函数.获取滚动条信息. 8 9 //si里面就有所有的信息. 10 int nNewPos = si.nPos; //获取最新的位置. 11 12 //处理滚动条的每一个消息.进行处理. 13 switch (nSBCode) 14 { 15 case SB_THUMBTRACK: //判断消息是否是拉动滚动条 16 nNewPos = nPos; //如果拖动滑块.那么参数2就是最新位置. 17 break; 18 case SB_LINELEFT: //箭头向左的消息 19 nNewPos -= 2; //我们的值加了.所以设置到滚动条里面 20 break; 21 22 case SB_LINERIGHT: //箭头向右的消息 23 nNewPos += 2; //我们的值加了.所以设置到滚动条里面 24 break; 25 case SB_PAGELEFT: // 值递减.也就是向左翻页 点击滚动条左边空格的时候 26 nNewPos -= si.nPage; 27 break; 28 case SB_PAGERIGHT: //值递增.也就是向右翻页. 29 nNewPos += si.nPage; 30 break; 31 break; 32 33 default: 34 break; 35 } 36 37 //需要判断位置是否超出. 38 if (nNewPos > si.nMax) 39 { 40 nNewPos = si.nMin; 41 } 42 if (nNewPos < si.nMin) 43 { 44 nNewPos = si.nMin; 45 } 46 pScrollBar->SetScrollPos(nNewPos); 47 CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); 48}

三丶总结

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

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

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

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

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

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

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

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

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

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

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

 四丶垂直滚动条的使用

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

1int 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}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

JS之滚动条效果2

在前面一篇说的是滚动条效果,本篇继续在前面的基础上面针对滚动条进行操作。本次要实现的效果如下:拖动滚动条左右移动时,上面的图片内容也相对外层盒子做相对移动。!(https://oscimg.oschina.net/oscnet/c64767294c846f5a670e95fe57384474d3d.png)下面针对要实现的效果进行分析:首先是页面