SOFTIST 编程方法筆記 目录

防止描画時画面闪烁(VC++)

Screen Flicker Free Drawing

描画領域很大,描画時間很长的情况下,会出现画面闪烁现象。为了防止这个不良现象发生,使用内存DC。先在内存DC上描画,画完了再用BitBlt()函数把内存DC的内容拷贝到窗口的DC上。

1.生成内存DC。用BOOL CreateCompatibleDC(CDC* pDC)函数,以窗口DC为基础生成一个内存DC。用BOOL CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight)函数生成内存位图。用CBitmap* SelectObject(CBitmap* pBitmap)函数把内存位图挂到内存DC上。

2.用通常的方法在内存DC上作必要的描画処理。

3.用BOOL BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop)函数把内存DC的内容拷贝到窗口的DC上。

4.例:CView的OnDraw()函数的再描画処理。注意点:OnTimer()函数中的Invalidate(BOOL bErase)的参数bErase必须是FALSE。也就是说,拷贝内存DC之前不清屏,以减少闪屏现象的发生。

void CTestView::DoDrawMem(CDC* pDC)
{
    CRect rc;
    GetClientRect(&rc);
    pDC->FillSolidRect(&rc, (COLORREF)0x00ffffff);
    CBrush brsh(RGB(rand()%256, rand()%256, rand()%256));
    pDC->SelectObject(&brsh);
    pDC->Ellipse(&rc);
}

void CTestView::OnDraw(CDC* pDC)
{
    CDC dcMem;
    CBitmap bmpMem;
    CRect rc;
    GetClientRect(&rc);
    dcMem.CreateCompatibleDC(pDC);
    bmpMem.CreateCompatibleBitmap(pDC, rc.right, rc.bottom);
    CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem);
    DoDrawMem(&dcMem);
    pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY);
}

void CTestView::OnTimer(UINT nIDEvent) 
{
    Invalidate(FALSE);
    CView::OnTimer(nIDEvent);
}