当文档的尺寸大于视图的范围时候可以采取CScrollView这种带滚动条的视图类解决文档的显示,还可以通过整体和局部的缩放交互技术实现。
在默认的情况下,窗口更新图面的时候,程序内部会用背景色来填充窗体的绘图区域,然后在进行文档的绘制展示工作。当WM_PAINT消息很频繁的发送给窗体的时候,填充背景和文档的绘制工作造成的反差会很大,出现闪烁的不友好的交互迹象。
解决方案:禁止窗体绘图区域的背景擦除,加快文档的绘制工作。具体到文档的绘制,可以先在内存中绘制,然后贴图到展示现场即可,通过CDC::BitBlt实现贴图,通过局部裁剪技术,提高绘图效率。
下面给出具体的参考代码,默认的DC映射模式采用的是MM_TEXT,
void CbayesarchitectView::OnDraw(CDC* pDC)
{
CbayesarchitectDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//
CDC memoryDC;
CDC* pCanvas = pDC;
CBitmap memoryBMP;
CBitmap* pOldBitmap = NULL;
CRect clipRect;
pDC->GetClipBox(clipRect);
CRect bmpRect = clipRect;
CClientDC dcClient(this);
OnPrepareDC(&dcClient, NULL);
dcClient.LPtoDP(bmpRect);
bmpRect.NormalizeRect();
if (!pDC->IsPrinting())
{
if (memoryDC.CreateCompatibleDC(pDC))
{
if (memoryBMP.CreateCompatibleBitmap(pDC, bmpRect.Width(), bmpRect.Height()))
{
OnPrepareDC(&memoryDC, NULL);
pCanvas = &memoryDC;
memoryDC.OffsetViewportOrg(-bmpRect.left, -bmpRect.top);
pOldBitmap = memoryDC.SelectObject(&memoryBMP);
memoryDC.SetBrushOrg(bmpRect.left % 8, bmpRect.top % 8);
memoryDC.IntersectClipRect(clipRect);
}
}
}
//Background fill
CBrush brush;
if (!brush.CreateSolidBrush(RGB(255,255,255)))
return;
brush.UnrealizeObject();
pCanvas->FillRect(clipRect, &brush);
//
Gdiplus::Graphics myGraphics(pCanvas->m_hDC);
myGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
Gdiplus::Pen bluePen(Gdiplus::Color::Blue,4.0f);
Gdiplus::Pen redPen(Gdiplus::Color::Red,4.0f);
Gdiplus::SolidBrush redBrush(Gdiplus::Color::Red);
Gdiplus::FontFamily fontFamily(L"Times New Roman");
Gdiplus::Font font(&fontFamily, 24, FontStyleRegular, UnitPixel);
PointF pointF(30.0f, 10.0f);
Gdiplus::SolidBrush solidBrush(Color(255, 0, 0, 255));
myGraphics.DrawString(L"Bayesian Network", -1, &font, pointF, &solidBrush);
myGraphics.DrawLine(&redPen,PointF(0.0f,0.0f),PointF(5000,5999));
//
if (pCanvas != pDC)
{
pDC->SetViewportOrg(0, 0);
pDC->SetWindowOrg(0,0);
pDC->SetMapMode(MM_TEXT);
memoryDC.SetViewportOrg(0, 0);
memoryDC.SetWindowOrg(0,0);
memoryDC.SetMapMode(MM_TEXT);
pDC->BitBlt(bmpRect.left, bmpRect.top, bmpRect.Width(), bmpRect.Height(),
&memoryDC, 0, 0, SRCCOPY);
memoryDC.SelectObject(pOldBitmap);
}
}