WTL的雙緩衝類非常好用,但是要注意一點。這個DoPaint的重載函數中,只有傳遞給WM_PAINT中CPaintDC中的m_ps.rcPaint地區才能更新,其他地區將無法得到更新。這點需要瞭解下。
如果你在緩衝DoPaint( CDCHandle dc) 擷取的DC中,在rcPaint之外的繪圖將無法在螢幕上顯示。因為這個記憶體緩衝只把rcPaint中的部分作為一個bitmap映射,其他部分沒有映射。因此會越界的。
解決的方法就是不要使用InvalidateRect,直接使用InvalidateWindow。或者修改程式,把那個rcPaint傳過來,自己DoPaint的時候小心。
修改的方法,可以參照atltheme.h中的CBufferedPaintImpl,把那個rect也一起傳進來
///////////////////////////////////////////////////////////////////////////////// CBufferedPaintImpl - provides buffered paint for any windowtemplate <class T>class ATL_NO_VTABLE CBufferedPaintImpl : public CBufferedPaintBase{public:CBufferedPaint m_BufferedPaint;BP_BUFFERFORMAT m_dwFormat;BP_PAINTPARAMS m_PaintParams;// Overrideablesvoid DoBufferedPaint(CDCHandle dc, RECT& rect){HDC hDCPaint = NULL;if(IsBufferedPaintSupported())m_BufferedPaint.Begin(dc, &rect, m_dwFormat, &m_PaintParams, &hDCPaint);T* pT = static_cast<T*>(this); if(hDCPaint != NULL)pT->DoPaint(hDCPaint, rect); //修改成類似這樣elsepT->DoPaint(dc.m_hDC, rect); //修改成類似這樣if(IsBufferedPaintSupported())m_BufferedPaint.End();}void DoPaint(CDCHandle /*dc*/, RECT& /*rect*/){// must be implemented in a derived classATLASSERT(FALSE);}};
參考:
http://www.cnblogs.com/wdhust/archive/2011/01/12/1934042.html
http://bbs.csdn.net/topics/390488347