当前位置: 首页 > news >正文

MFC开发,给对话框添加垂直滚动条并解决鼠标滚动响应的问题

无论在使用QT或者MFC进行界面开发时,都会出现在一个对话框里面存在好多的选项,导致对话框变得非常长或者非常大,就会显现的不美观,在这种情况下通常是添加一个页面的滚动条来解决这个问题,下面我们就来介绍给MFC的对话框添加滚动条和响应鼠标滚轮滚动的事件

在写下面的代码之前需要现在对话框的OnInitDialog()函数中将窗口大小和滚动条长度进行初始化

// 初始化窗口大小
CRect rect;
GetWindowRect(&rect);
TRACE(_T("width:%d height:%d\n"), rect.Width(), rect.Height());
rect.bottom = rect.top + 250;
SetWindowPos(NULL, rect.left, rect.top, 810, 450, SWP_NOZORDER | SWP_NOMOVE);
// 初始化滚动条大小
SCROLLINFO scrollinfo;
GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);
scrollinfo.nPage = 10;
scrollinfo.nMax = 72;
SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);

给对话框添加滚动条

首先给对话框添加垂直滚动条

点开对话框设计页面→点击属性→将垂直滚动条设置为True

添加垂直滚动条的消息处理函数

右键点击类向导→选择消息→点击添加WM_VSCROLL消息处理程序

在消息处理函数中添加下面的代码,即可实现对话框滚动条滚动

void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{SCROLLINFO scrollinfo;GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);int unit = 3;scrollinfo.nPage = 10;switch (nSBCode){case SB_LINEUP:          // 向上滚动一行scrollinfo.nPos -= 1;if (scrollinfo.nPos < scrollinfo.nMin){scrollinfo.nPos = scrollinfo.nMin;break;}SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);ScrollWindow(0, unit);break;case SB_LINEDOWN:           // 向下滚动一行scrollinfo.nPos += 1;if (scrollinfo.nPos + scrollinfo.nPage > scrollinfo.nMax)  //此处一定要注意加上滑块的长度,再作判断{scrollinfo.nPos = scrollinfo.nMax;break;}SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);ScrollWindow(0, -unit);break;case SB_PAGEUP:            // 向上滚动一页scrollinfo.nPos -= 5;if (scrollinfo.nPos < scrollinfo.nMin){scrollinfo.nPos = scrollinfo.nMin;break;}SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);ScrollWindow(0, unit * 5);break;case SB_PAGEDOWN:        // 向下滚动一页scrollinfo.nPos += 5;if (scrollinfo.nPos  > (scrollinfo.nMax - scrollinfo.nPage))  //此处一定要注意加上滑块的长度,再作判断{scrollinfo.nPage = 13;SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);break;}SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);ScrollWindow(0, -unit * 5);break;case SB_ENDSCROLL:      // 结束滚动break;case SB_THUMBPOSITION:  // 滚动到绝对位置。当前位置在nPos中提供break;case SB_THUMBTRACK:     // 将滚动框拖到指定位置。当前位置在nPos中提供ScrollWindow(0, (scrollinfo.nPos - nPos) * unit);scrollinfo.nPos = nPos;SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);break;}CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

效果展示

响应鼠标滚轮滚动事件

虽然上面的方式实现了对话框页面的滚动效果,但是使用起来依然是不太方便,通常一个页面带有滚动条,这个页面通过鼠标滑动也是可以进行页面滚动的,但是如果只是单单实现了上面的代码,还是达不到我们想要的效果的,这时就需要对鼠标的滚动事件进行进一步的处理

添加鼠标滚动事件处理程序

右键点击类向导→选择消息→点击添加WM_MOUSEWHEEL消息处理程序

在消息处理函数中添加下面的代码,即可实现对话框鼠标滚轮滚动

在鼠标滚动的处理函数中直接调用我们写好的滚动条处理事件即可

BOOL CSettingDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{	SCROLLINFO scrollinfo;GetScrollInfo(SB_VERT, &scrollinfo);if (zDelta == 120){OnVScroll(SB_PAGEUP, GetScrollPos(SB_VERT), GetScrollBarCtrl(SB_VERT));}else if (zDelta == -120){OnVScroll(SB_PAGEDOWN, GetScrollPos(SB_VERT), GetScrollBarCtrl(SB_VERT));}return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}

效果展示

在实现中出现的问题和解决方法

出现的问题:如果在界面的底部不停通过鼠标进行滚动就会出现页面不对或偏移的问题,这个问题的原因是由于滚动条的最下面还有一点空余,之前发现这个问题的解决方法是不移动页面就直接将滚动条向下移,这样就导致了这个问题的出现

问题分析:这个问题的主要原因就是滚动条的长度和页面的长度不匹配导致的问题,但是谁也不能将页面和滚动条的长度进行完全的匹配,最后参考其他应用软件找到了他们处理这个问题的方法,于是运用到了我的这个项目上,把问题解决了

解决方法:解决方法是,当滑动到底部时不改变滚动条的位置,而是修改滚动条的长度来解决这个问题

OnVScroll函数代码的SB_PAGEDOWN分支就是基于这种方式实现的

case SB_PAGEDOWN:scrollinfo.nPos += 5;if (scrollinfo.nPos  > (scrollinfo.nMax - (int)scrollinfo.nPage))  //此处一定要注意加上滑块的长度,再作判断{// 不移动页面,只是将滚动条的长度增加scrollinfo.nPage = 13;SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);break;}SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL);ScrollWindow(0, -unit * 5);break;

通过这个方法就可以解决这个小小的细节问题,这里可以不增加长度直接不移动也是可以的,但是看着就不是那么完美了

到这里,给对话框添加垂直滚动条并响应鼠标滚动事件是页面移动就介绍完了

感谢观看学习,大佬们多多指点,愿明天的自己会感谢当下的努力!!!!

http://www.lryc.cn/news/529612.html

相关文章:

  • 动态规划DP 最长上升子序列模型 导弹防御模型(题目分析+C++完整代码实现)
  • LevelDB 源码阅读:写入键值的工程实现和优化细节
  • 药店药品销售管理系统的设计与实现
  • 人格分裂(交互问答)-小白想懂Elasticsearch
  • 【论文投稿-第八届智能制造与自动化学术会议(IMA 2025)】HTML, CSS, JavaScript:三者的联系与区别
  • python | OpenCV小记(一):cv2.imread(f) 读取图像操作(待更新)
  • 网络工程师 (9)文件管理
  • Java中的线程池参数(详解)
  • 2 MapReduce
  • 如何用函数去计算x年x月x日是(C#)
  • 开发过程中如何减少属性注释?
  • NX/UG二次开发—CAM—快速查找程序参数名称
  • socket实现HTTP请求,参考HttpURLConnection源码解析
  • 访问CMOS RAM
  • 解决AnyConnect开机自启动问题
  • 芯片AI深度实战:进阶篇之vim内verilog实时自定义检视
  • 数据结构实战之线性表(一)
  • jdk8项目升级到jdk17——岁月云实战
  • 商品列表及商品详情展示
  • 使用where子句筛选记录
  • SQL Server查询计划操作符(7.3)——查询计划相关操作符(5)
  • C++中常用的十大排序方法之4——希尔排序
  • 扶摇计划--从失业的寒冬,慢慢的走出来
  • unity学习24:场景scene相关生成,加载,卸载,加载进度,异步加载场景等
  • [cg] 使用snapgragon 对UE5.3抓帧
  • 一元函数微积分的几何应用:二维平面光滑曲线的曲率公式
  • ISBN 号码——蓝桥杯
  • Spring Boot - 数据库集成06 - 集成ElasticSearch
  • 51单片机CLD1602显示万年历+闹钟+农历+整点报时
  • C++ 中的类(class)和对象(object)