MFC:对话窗和滚动条的基情

本文介绍了在MFC中创建带滚动条对话框的步骤,包括设置滚动条属性、处理WM_VSCROLL和WM_HSCROLL消息、更新滑块位置及窗口内容。讲解了滚动条范围、滑块位置与窗口客户区的关系,强调了滚动条消息处理和窗口客户区重绘的重要性,并提到了滚动条初始化和与之相关的函数如SetScrollInfo、GetScrollInfo和ScrollWindow等。
摘要由CSDN通过智能技术生成

创建带滚动条窗口的步骤:

以竖直方向的标准滚动条为例(横向方向的滚动条控件也类似):

1.创建一个基于对话框的MFC工程,或新建一个对话框资源,在对话框的属性-->外观 选项中把Vertical Scrollbar选项设为True。


2.在对话框的初始化函数中用SetScrollInfo函数设置滚动条的范围、页面大小、初始位置。

3.捕捉WM_VSCROLL消息,在消息处理函数OnVScroll中根据消息通知码设置滚动条的位置。

4.根据3中滚动条的位置变化调用ScroolWindow函数滚动窗口客户区。

5.ScrollWindow滚动窗口客户区后,Windows自动将滚动新出现的地方无效化,从而产生一条WM_PAINT消息。所以我们还需要在WM_PAINT的消息处理函数中自己绘制新出现的区域。

       ps:若在其他消息处理函数中滚动了窗口客户区,也要记得同步设置滚动条。


详细

要用滚动条,我们需要做什么?

      在程序中使用滚动条,需要程序和Windows共同负责维护滚动条以及滑块在滚动条中的位置。Windows负责的任务如下:

  • 1.处理滚动条中的所以鼠标消息。
  •  2.当用户单击滚动条时,提供一种方向显示的闪烁。
  •  3.当用户拖到滑块时,在滚动条内移动滑块。
  •  4.向拥有滚动条的窗口的窗口过程发现滚动条消息。

程序要负责的任务如下:

  •   1.初始化滚动条的范围和位置。
  •    2.处理传送给窗口过程的滚动条消息。
  •    3.更新滑块的位置。
  •    4.滚据滚动条的变换更新客户区的内容。

 

注意上面windows负责的第3条和程序要负责的第3条。小弟以前理所当然的认为windows应该会负责移动滑块并更新滑块的位置。后来发现如果自己不在消息处理函数中重新设置滑块的位置,当你移动滑块松开鼠标后,滑块会自己回到原来的地方。原来要程序自己负责更新滑块的位置。我现在还想不清楚为什么windows不负责这个,这个不是很简单吗?


滚动条的范围、滑块的位置和窗口客户区的映射:

        滚动条的范围是一对整数,分别代表滚动条的最大值和最小值。位置值滑块在范围中所处的值。当滑块在滚动条的最顶端的时候,滑块的位置是范围的最小值。相应的,滑块在滚动条的底部时,位置是范围的最大值。如果滑块在滚动条的中间,那位置的取值就是介于最大值和最小值的一个中间值了。默认状态下标准滚动条的范围是0~100,默认位置是0,可以通过SetScrollInfo函数来设置。而滚动条控件的默认范围是0~0。

       看来滚动条的范围与滑块的位置和窗口客户区半毛钱关系都没有,全靠我们让它们产生关系。要想让让窗口客户区的内容随着滑块的滑动发生变化,我们必须在滚动条的消息处理函数中或WM_PAINT的消息处理函数中自己重绘窗口客户区的内容。



滚动条消息:

MFC中,如果我们想要在调整口大小时自动出现滚动条来实现内容的滚动,我们可以采取以下步骤: 1. 在需要添加滚动条对话框口类的类体中,添加一个CScrollView的派生类成员变量,用于处理滚动条的相关功能。例如,可以添加一个名为m_scrollView的成员变量。 2. 在对话框口类的OnInitDialog(对于对话框类)或OnCreate(对于口类)函数中,创建并初始化CScrollView对象。例如,在OnInitDialog函数中可以添加如下代码: m_scrollView.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST); 3. 在对话框口类中重写OnSize函数,用于处理口大小改变事件。例如,在对话框类中可以添加如下代码: void CMyDialog::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (m_scrollView.GetSafeHwnd() != nullptr) { CRect rect; GetClientRect(rect); m_scrollView.MoveWindow(rect); } } 在口类中可以添加如下代码: void CMyWnd::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); if (m_scrollView.GetSafeHwnd() != nullptr) { CRect rect; GetClientRect(rect); m_scrollView.SetWindowPos(nullptr, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER); } } 这样,在调整口大小时,滚动条会根据内容的大小和口的大小自动进行调整,并在需要时出现或隐藏。你可以根据需要在CScrollView对象中添加需要滚动的内容,例如使用CScrollView的派生类CDrawView实现自定义的绘图功能等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值