此函数的接口说明参见MSDN官方文档http://msdn.microsoft.com/en-us//library/3ew6s3ez(v=vs.110).aspx
其中sizeTotal参数设置的是滚动视图的滚动范围大小,采用逻辑单位。
新建一个基于单文档的标准的MFC应用程序,其中视图采用滚动视图,仅仅在绘图操作中添加如下代码(采用GDI+库)
CSize totalDocSize = GetTotalSize();
CDC memDC;
CBitmap memBmp;
CBitmap *pReplacedBmp = NULL;
memDC.CreateCompatibleDC(pDC);
memBmp.CreateCompatibleBitmap(pDC,2*totalDocSize.cx,2*totalDocSize.cy);
pReplacedBmp = memDC.SelectObject(&memBmp);
Gdiplus::Graphics myGraphics(memDC.m_hDC);
myGraphics.SetSmoothingMode(SmoothingModeHighQuality);
Gdiplus::FontFamily myFontFamily(L"Microsoft Sans Serif");
Gdiplus::Font myFont(&myFontFamily, 24, FontStyleRegular, UnitPixel);
PointF pointF(30.0f, 10.0f);
Gdiplus::SolidBrush solidBrush(Color(255, 0, 0, 255));
myGraphics.DrawString(L"Bayesian Network", -1, &myFont, pointF, &solidBrush);
myGraphics.FillRectangle(&solidBrush,totalDocSize.cx,totalDocSize.cy,totalDocSize.cx,totalDocSize.cy);
pDC->BitBlt(0,0,totalDocSize.cx*2,totalDocSize.cy*2,&memDC,0,0,SRCCOPY);
该绘制操作展示了在DC映射模式为MM_TEXT像素模式下,内存绘图、滚动范围大小的意义。
编译通过,调试运行,得到下面的结果:
分析:
- 窗口没有出现滚动条,是因为默认的滚动尺寸设置为100*100,视窗的范围已经足够显示绘制内容
- 窗口视图的滚动范围一般和文档的大小是一致的,这样在滚动的范围内可以展示所有的文档绘制内容,参考代码如下
void CMyScrollView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); // The GetMyDocSize() member function is implemented in // your document class. The return type is CSize. CMyScrollDoc* pMyDoc = (CMyScrollDoc*)GetDocument(); SetScrollSizes(MM_TEXT, pMyDoc->GetMyDocSize()); }
- 当视图窗口的尺寸小于滚动范围的时候,会出现滚动条,触发滚动条操作的时候,会调整的设备环境(DC)的窗口原点,以使文档显示达到友好的交互效果.参考图
- 当你用鼠标不停的放大和缩小窗口尺寸的时候,WM_PAINT消息会被频繁的发送到主窗口,进行视图的重绘操作,先是填充窗口背景,然后进行图形的绘制操作,时间反差愈大,闪烁效果愈加明显...参考代码
BOOL CbayesarchitectView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default //return CScrollView::OnEraseBkgnd(pDC); return TRUE; }
解决方案:禁止窗口背景的擦除,直接在与视图DC兼容的内存DC中绘制文档的内容,然后一次性的贴在视图DC上进行显示。由于禁止了窗口背景的擦除,设置内存DC的画布要足够大,使得在屏幕窗口显示范围内不出现没有擦除的区域即可.若内存DC的画布BMP过小,禁止窗口擦除后会出现下面的效果
可以通过处理视图的WM_SIZE消息记录窗体的尺寸大小,进行调整。有一点需要注意,如果内存BMP尺寸太大,拷贝会很耗时的,在改变窗口尺寸的时候会明显的感觉到.文档尺寸设置为适用大小即可...