MFC 窗口重繪問題
在客戶區畫直線等圖形時, 發現當其最小化或者其他窗口遮擋時,出現窗口重繪,而將原來繪制的圖形刪除,上網上搜索知道,繪制圖形的代碼必須放置在Ondraw函數中,才能避免重繪時圖形消失(因為一直在響應WM_PAINT消息,不斷的重繪),但是這樣做卻只能保存最近的一次繪圖,只適用于單幅固定的圖形,對于其中有多幅圖形就不能這么做了,解決的思路是:考慮到MFC時 文檔/視圖 類,視圖CView負責數據的顯示和修改,文檔CDocument類負責數據的存儲和加載,從而把數據管理和顯示方法分離開來。我們在CDocument類中添加一個CBitMap對象,將每次中間繪圖時的客戶區的內容保存成BitMap,當所有的操作都執行好以后,將最終的BitMap拷貝到屏幕中,這就是所謂的內存緩存畫圖方式。這么做還有一個好處就是更新是看不到閃爍。
具體代碼如下:
1、中間圖形處理過程(事先已經在CDrawDoc類中添加了變量CBitmap m_bmpBuf;):
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
CDC *pDC = GetDC();
CDrawDoc *pDoc = GetDocument();
CDC dcMem;
dcMem.CreateCompatibleDC(NULL);
CRect rect;
GetClientRect(&rect); //獲取客戶區域
pDoc->m_bmpBuf.DeleteObject();
pDoc->m_bmpBuf.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
CBitmap *pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuf);//將創建好的m_bmpBuf添加到臨時的CDC的Object中,類似于在墻上先糊上墻紙^_^,先在墻紙上作畫,最后將最終形成的畫拷貝到墻上。
m_ptEnd = point;
dcMem.BitBlt(0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY);
dcMem.SelectObject(pOldBitmap); //將pDC即當前客戶區里面的內容拷貝到臨時的MEM中,MEM雖然過后會被delete掉,但是它更新了CDocument類中的m_bmpBuf
m_bDraw = false;
dcMem.DeleteDC();
}
2、最終顯示(在OnDraw中實現):
void CDrawView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CRect rect;
GetClientRect(&rect);
CDC dcMem;//以下是輸出位圖的標準操作
CBitmap *pOldBitmap = NULL;
dcMem.CreateCompatibleDC(NULL);
pOldBitmap = dcMem.SelectObject(&pDoc->m_bmpBuf);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);
dcMem.SelectObject(pOldBitmap); //將dcMeM中的bitmap拷貝到當前客戶區
dcMem.DeleteDC();
}
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成