Evan.zz
Evan.zz

Reputation: 165

MFC double buffering doesn't copy bitmap

BOOL CPaintView::OnEraseBkgnd(CDC* /*pDC*/)
{
    //return CPaintView::OnEraseBkgnd(pDC);
    return true;
}
void CPaintView::OnDraw(CDC* pDC)
{
    CDC shadowMem;
    CBitmap shadowBit, *pOldBmp;
    CRect currWin;
    GetClientRect(currWin);

    shadowMem.CreateCompatibleDC(pDC);
    shadowBit.CreateCompatibleBitmap(pDC,currWin.Width(), currWin.Height());
    pOldBmp = (CBitmap*)shadowMem.SelectObject(&shadowBit);
    shadowMem.FillSolidRect(0, 0, currWin.Width(), currWin.Height(), RGB(0, 255, 0));
    shadowMem.Rectangle(330, 300, 400, 500);

    pDC->BitBlt(0, 0, currWin.Width(), currWin.Height(), &shadowMem, 0, 0, SRCCOPY);
    shadowMem.SelectObject(pOldBmp);
}

The code is very simple and intuitive. I created a new CDC and a bitmap, set those to compatible to current CDC. Added new bitmap to new CDC. Then it fills the memory CDC to green color and draw a rectangle on it. then It copy the memory CDC's bitmap to current CDC.

And this is the result i got. You can clearly see a little green line draw near the top edge of the window. I'm not sure which part i messed up.

result


Update:

Thanks for all the help. I made some random adjustment of bitblt arguments and got a different result.

pDC->BitBlt(0, -400, currWin.Width(), currWin.Height(), &shadowMem, 0, 0, SRCCOPY);

update

That -400 was a random number when i was trying to figure out the issue. It appears that when i copy the bitmap from shadowMem to pDC, somehow it doesn't match the coordinates correctly.

I couldn't find the reason yet, but if i copy this code to a new project, it works totally fine. I think i may have something to do with MM_ANISOTROPIC mode that my pDC is set to.

Upvotes: 0

Views: 427

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 490768

As @RemyLebeau suggested in the comment, your Rectangle call probably isn't doing what you expect or want.

If we select a pen and brush, then draw a rectangle of (more or less) a size that's entirely inside the client area, we can see the result pretty easily. For example:

void CdoublebufferingView::OnDraw(CDC* pDC)
{
    CDC shadowMem;
    CBitmap shadowBit, * pOldBmp;
    CRect currWin;
    GetClientRect(currWin);

    shadowMem.CreateCompatibleDC(pDC);
    shadowBit.CreateCompatibleBitmap(pDC, currWin.Width(), currWin.Height());
    pOldBmp = (CBitmap*)shadowMem.SelectObject(&shadowBit);
    shadowMem.FillSolidRect(0, 0, currWin.Width(), currWin.Height(), RGB(0, 255, 0));

    shadowMem.SelectObject(GetStockObject(DKGRAY_BRUSH));
    shadowMem.SelectObject(GetStockObject(WHITE_PEN));
    shadowMem.Rectangle(50, 50, currWin.Width() - 100, currWin.Height() - 100);
    pDC->BitBlt(0, 0, currWin.Width(), currWin.Height(), &shadowMem, 0, 0, SRCCOPY);
    shadowMem.SelectObject(pOldBmp);
}

Result:

enter image description here

Upvotes: 0

Related Questions