从SetScrollSizes谈CScrollView和绘图技巧

    此函数的接口说明参见MSDN官方文档http://msdn.microsoft.com/en-us//library/3ew6s3ez(v=vs.110).aspx 函数

    其中sizeTotal参数设置的是滚动视图的滚动范围大小,采用逻辑单位。 spa

新建一个基于单文档的标准的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像素模式下,内存绘图、滚动范围大小的意义。


编译经过,调试运行,获得下面的结果: code


分析: 接口

  1. 窗口没有出现滚动条,是由于默认的滚动尺寸设置为100*100,视窗的范围已经足够显示绘制内容
  2. 窗口视图的滚动范围通常和文档的大小是一致的,这样在滚动的范围内能够展现全部的文档绘制内容,参考代码以下
    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());
    }
  3. 当视图窗口的尺寸小于滚动范围的时候,会出现滚动条,触发滚动条操做的时候,会调整的设备环境(DC)的窗口原点,以使文档显示达到友好的交互效果.参考图                                                                      
  4. 当你用鼠标不停的放大和缩小窗口尺寸的时候,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太小,禁止窗口擦除后会出现下面的效果 ip


能够经过处理视图的WM_SIZE消息记录窗体的尺寸大小,进行调整。有一点须要注意,若是内存BMP尺寸太大,拷贝会很耗时的,在改变窗口尺寸的时候会明显的感受到.文档尺寸设置为适用大小便可... 内存

相关文章
相关标签/搜索