多數情況下窗口重繪的產生大多是因爲窗口部分被遮擋或者窗口有滾動發生,改變的區域並不是整個圖形而只有一小部分,這一部分需要改變的就是pDC中的裁剪區了。因爲顯示(往內存或者顯存都叫顯示)比繪圖過程的計算要費時得多,有了裁剪區後顯示的就只是應該顯示的部分,大大提高了顯示效率。但是這個裁剪區是MFC設置的,它已經爲我們提高了顯示效率,在進行復雜圖形的繪製時如何進一步提高效率呢?那就只有去掉在裁剪區外的繪圖過程了。可以先用pDC->GetClipBox()得到裁剪區,然後在繪圖時判斷你的圖形是否在這個區內,如果在就畫,不在就不畫。
以下是我編寫的shape文件讀寫關於重繪部分的實例
void CShpviewView::OnDraw(CDC* pDC)
{
CShpviewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
/*雙緩存繪圖*/
CDC MemDC; //定義一個顯示設備對象
CBitmap MemBitmap; //定義一個位圖對象
CRect rcClient; //客戶區
CRect rcClip; //裁剪區
pDC->GetClipBox(rcClip); //得到整個無效區
GetClientRect(&rcClient); //得到客戶區範圍
//建立與屏幕顯示兼容的內存顯示設備
MemDC.CreateCompatibleDC(pDC);
//建立一個與屏幕顯示兼容的空位圖,用窗口的大小
MemBitmap.CreateCompatibleBitmap(pDC,rcClient.Width(),rcClient.Height());
OnPrepareDC(&MemDC, NULL);
//將位圖選入到內存顯示設備中
//只有選入了位圖的內存顯示設備纔有地方繪圖,畫到指定的位圖上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
MemDC.SelectClipRgn(NULL);
MemDC.IntersectClipRect(rcClip); //使窗口範圍等於無效區
//先用背景色將位圖清除乾淨,用的是白色作爲背景
MemDC.FillSolidRect(0,0,rcClient.Width(),rcClient.Height(),RGB(255,255,255));
/*繪圖*/
int i = 0;
//畫點
int ptCount;
ptCount = pDoc->m_pointArray.GetSize();
for(i=0; i<ptCount; i++)
{
((CshpPoint*)pDoc->m_pointArray.GetAt(i))->DrawPoint(&MemDC); //應該選入MemDC
}
//畫線
int lCount;
lCount = pDoc->m_lineArray.GetSize();
for(i=0; i<lCount; i++)
{
((CshpLine*)pDoc->m_lineArray.GetAt(i))->DrawLine(&MemDC); //要修改成GDI+
}
//畫面
int pCount;
pCount = pDoc->m_polygonArray.GetSize();
for(i=0; i<pCount; i++)
{
((CshpPolygon*)pDoc->m_polygonArray.GetAt(i))->DrawPolygon(&MemDC); //要修改成GDI+
}
//將內存中的圖拷貝到剪裁區上進行顯示
pDC->BitBlt(rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(),
&MemDC, rcClip.left, rcClip.top, SRCCOPY);
//繪圖完成後的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();
// TODO: add draw code for native data here
}