再描画時の画面ちらつき防止(VC++) Screen Flicker Free Drawing 描画領域が大きい、描画時間がちょっと長い場合は、画面のちらつきが出てしまいます。画面のちらつきを抑えるために、メモリDCを用意して、メモリDC上で描画を行います。メモリDC上の描画が終わったら、BitBlt()関数で、WindowのDCにコピーします。 1.メモリDCを作成します。BOOL CreateCompatibleDC(CDC* pDC)関数で、WindowのDCからメモリDCを作成します。BOOL CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight)関数でビットマップを作ります。CBitmap* SelectObject(CBitmap* pBitmap)関数で、ビットマップをメモリDCに設定します。 2.従来の方法と同じように、メモリDC上で描画処理を実装します。 3.メモリDCに描画したイメージを、BOOL BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop)関数で、WindowのDCにコピーします。 4.例:CViewのOnDraw()で、再描画処理。注意点:OnTimer()関数の中で、Invalidate(BOOL bErase)の引数はFALSEと設定しまいます。DCをコピーする前に、Windowの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); } |