MemDC dcMem(&dc, &rect); //创建内存dc这个 rect 必须 只包含 重绘 部分,GetUpdateRect
例子: void CMyListCtrl::OnPaint() {// get the update rect 1st; CRect rc1; GetUpdateRect(&rc1); afxDump << rc1 << "\n"; // (L 0, T 99, R 201, B 120) scroll off 1st line 120-99 = 21 last line // (L 0, T 26, R 201, B 47) bring 1st line back 47-26 = 21 = first line CPaintDC dc(this); // device context for painting // get size CRect rc; GetClientRect(&rc); // Create a compatible memory DC CDC memDC; memDC.CreateCompatibleDC(&dc); // Select a compatible bitmap into the memory DC CBitmap bitmap; bitmap.CreateCompatibleBitmap( &dc, rc.Width(), rc.Height()); HBITMAP oldBmp=(HBITMAP)memDC.SelectObject(&bitmap); // fill the region not occupied memDC.FillRect(&rc,CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); // Let the control draws the list. CRgn rgn; rgn.CreateRectRgn(rc1.left,rc1.top,rc1.right,rc1.bottom); memDC.SelectClipRgn(&rgn); DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); // copy to CB for checking #ifdef TEST memDC.SelectObject(oldBmp); OpenClipboard(); EmptyClipboard(); SetClipboardData(CF_BITMAP,bitmap); CloseClipboard(); oldBmp=(HBITMAP)memDC.SelectObject(&bitmap); #endif // 'and' to the background dc.BitBlt(rc.left,rc.top, rc.Width(), rc.Height(),&memDC,0,0,SRCAND);// SRCCOPY // set back memDC.SelectObject(oldBmp); // free DeleteObject(bitmap.m_hObject); DeleteObject(memDC);
// Do not call CListCtrl::OnPaint() for painting messages }
滚动只引起 部分重绘, 用 memDC 要 指定 重绘区。
因为平台cpu不够快,如果我直接在dc上画那么有点闪烁。所以才用双缓冲。使用效果还不错,就是滚动是比较卡,无法接受。
void CMyListCtrl::OnPaint()
{// get the update rect 1st;
CRect rc1;
GetUpdateRect(&rc1);
afxDump << rc1 << "\n";
// (L 0, T 99, R 201, B 120) scroll off 1st line 120-99 = 21 last line
// (L 0, T 26, R 201, B 47) bring 1st line back 47-26 = 21 = first line
CPaintDC dc(this); // device context for painting
// get size
CRect rc;
GetClientRect(&rc);
// Create a compatible memory DC
CDC memDC;
memDC.CreateCompatibleDC(&dc);
// Select a compatible bitmap into the memory DC
CBitmap bitmap;
bitmap.CreateCompatibleBitmap( &dc, rc.Width(), rc.Height());
HBITMAP oldBmp=(HBITMAP)memDC.SelectObject(&bitmap);
// fill the region not occupied
memDC.FillRect(&rc,CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
// Let the control draws the list.
CRgn rgn;
rgn.CreateRectRgn(rc1.left,rc1.top,rc1.right,rc1.bottom);
memDC.SelectClipRgn(&rgn);
DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
// copy to CB for checking
#ifdef TEST
memDC.SelectObject(oldBmp);
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,bitmap);
CloseClipboard();
oldBmp=(HBITMAP)memDC.SelectObject(&bitmap);
#endif
// 'and' to the background
dc.BitBlt(rc.left,rc.top, rc.Width(), rc.Height(),&memDC,0,0,SRCAND);// SRCCOPY
// set back
memDC.SelectObject(oldBmp);
// free
DeleteObject(bitmap.m_hObject);
DeleteObject(memDC);
// Do not call CListCtrl::OnPaint() for painting messages
}
特别感谢schlafenhamster。