好几天没写博客了。今天发现了一个需求,在对话框上有好多下拉框选项,一个屏幕显示不完,需要使用到滚动条。起初并不知晓有CScrollView这个类,便尝试了用滚动条,然后在滚动时更改屏幕上控件的坐标来实现。但是后来发现,不但经常会滚动得“不干不净”的,还有些在初始情况下是隐藏的下拉框如何再显示出来呢?一番纠结后,开始寻求更简洁的方案。
以前听说过内嵌子视图的说法,于是灵光一现,想到了创建一个带滚动条的子视图,也就自然而然地寻找到了CScrollView。
这个视图类的作用很简单,就是创建一个视图区域,也可以像向里面添加控件等,超出的部分就“看不见”了,通过滚动条来查看更多的区域。
无图无真相,来个小程序就知道是怎么回事了。
建立一个基于对话框的MFC程序ScrollViewTest。然后在项目上单击右键,添加新的MFC类CMyScrollView,在选择基类的时候,选择CScrollView。
然后在ScrollViewTest.h中添加一个成员变量
- CMyScrollView * m_pMyView;
接下来在CScrollViewTestDlg::OnInitDialog()中添加下面的代码吧。
- m_pMyView = (CMyScrollView*)(RUNTIME_CLASS(CMyScrollView)->CreateObject());
- CCreateContext context;
- context.m_pCurrentDoc = NULL;
- m_pMyView->Create(NULL,
- NULL,
- WS_BORDER,
- CRect(0, 0, 100, 100),
- this,
- WM_USER + 1,
- &context);
- ((CView*)m_pMyView)->OnInitialUpdate();
- m_pMyView->ShowWindow(SW_SHOW);
行啦,已经可以运行了,结果如下。
可以看到这东西就像一个控件一样嵌到对话框中了。
然后就可以为所欲为了。修改一下代码。
- m_pMyView->Create(NULL,
- NULL,
- WS_BORDER,
- CRect(0, 0, 200, 200),
- this,
- WM_USER + 1,
- &context);
再运行,你会发现,咦,滚动条们呢?
这里需要注意一下,在Create之后,调用了CScrollView的一个虚函数OnInitialUpdate(),会设置一些基本的参数,其中一个就是“滚动区域”。很明显运行此方法完后的“滚动区域”要比CRect(0, 0, 200, 200)小,所以子视图认为“我没有必要滚动了,你完全可以看得到所有的东西”。为了验证一下,我们Debug并查看一下。如图
m_totalDev便是“滚动区域”,m_pageDev是“滚动一页”需要滚动的大小,m_lineDev是“滚动一行”需要滚动的大小。
解决这种情况也很简单,增大“滚动区域”。使用SetScrollSize()方法。
- void SetScrollSizes(int nMapMode,
- SIZE sizeTotal,
- const SIZE& sizePage = sizeDefault,
- const SIZE& sizeLine = sizeDefault);
第一个参数就是“滚动区域”了,一会我们把它设为长宽各为500。
第二个参数是“滚动一页”时需要滚动的区域。
第三个参数是“滚动一行”时需要滚动的区域。
好,设置一下“滚动区域”。
- SIZE size;
- size.cx = 500;
- size.cy = 500;
- m_pMyView->SetScrollSizes(MM_TEXT, size);
注意,这几行代码必须要加在OnInitialUpdate()之后,否则不就前功尽弃了?
结果如下。
好,接下来在子视图上添加控件试试。添加一个成员变量:
- CMFCButton * m_button;
在构造函数中初始化之:
- m_button = new CMFCButton;
在CScrollViewTestDlg::OnInitDialog()中添加如下代码:
- button->Create(_T("Hello"),
- WS_VISIBLE,
- CRect(5, 5, 80, 250),
- m_pMyView,
- WM_USER + 1);
好,只能通过拖动滚动条的方式来看到这个按钮的全貌了。
基本的功能介绍完成了,还有些其他的方法,比如
- void CheckScrollBars(BOOL& bHasHorzBar, BOOL& bHasVertBar) const;
检查滚动条是否存在。
比如
- CPoint GetDeviceScrollPosition( ) const;
返回当前滚动条的位置,一个坐标值。
再比如
- void SetScaleToFitSize(SIZE sizeTotal);
可以根据视图的内容调整视图的大小。
诸如此类的方法,可以灵活地运用到程序中去。
转载于:https://blog.51cto.com/serious/876251