Click to See Complete Forum and Search --> : Drawing on a bitmap - double buffering


Frederic Naudeau
May 14th, 1999, 04:28 AM
Hi,

I load a 256 colors bitmap and display it, and I want to draw on it some lines, rectangles, circles, etc....
My problem is that when I draw something in the DC directly, the only way to refresh is to display the bitmap and then the draws. And when I move the draws it flicked, and it has an horrible effect !!

How can I manage to do a double buffering ?

I've try to do something like :

CDC * thisDC = GetDC();
CDC * pDC = new CDC;
pDC->CreateCompatibleDC(thisDC);
CBitmap cbm;
cbm.CreateBitmap(m_size.cx,m_size.cy,1,8,NULL);
pDC->SelectObject(&cbm);
DrawBitmap(pDC);

CPen pen(PS_SOLID, 1, RGB(0,255,0));
pDC->SelectObject(&pen);
pDC->MoveTo(CPoint(20,20));
pDC->LineTo(CPoint(100,100));

thisDC->BitBlt(0, 0, m_size.cx, m_size.cy, pDC, 0, 0, SRCCOPY);

..... Delete Objects .....




With this method I never get a green line !! And I don't see my picture.
I have notice that my window is in monochrome and not in color !! If I remove the compatible DC it works.

My question would be : How can I display a bitmap and draw ( and move ) things on it without flicking ?

Where can I find samples which manage double buffering ( in color ) ?


Thanks in advance.

Frédéric Naudeau.

Jason Teagle
May 14th, 1999, 06:56 AM
First, although you probably chose the correct number of colour planes and bits per pixel for your display, you should use CreateCompatibleBitmap() and pass it the DC WHICH BELONGS TO THE WINDOW (thisDC in your case).

Second, don't forget to select the bitmap, pen and brush (or any GDI object you selct in) BACK OUT of the DC before trying to delete or release DCs (you ARE releasing the DC back to the window, aren't you? - you should be!). Leaving them in can have an undefined effect.

Here is an example of code which will successfully draw on a bitmap before displaying:

---

void CMyView::OnDraw(CDC *pDC)
{
BITMAP sBitmapInfo ;
CBitmap bmpTemp, *pBmpOld ;
CBrush *pBrOld ;
CDC dcScreen ;
CPen *pPenOld ;
CRect rctClient ;
HBITMAP hBmp ;
HINSTANCE hInst ;

dcScreen.CreateCompatibleDC(NULL);

hInst = AfxGetInstanceHandle();
// Contrary to the help file, this DOES work under NT.
hBmp = (HBITMAP)::LoadImage(hInst,"d:\\winnt\\winnt256.bmp",
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
bmpTemp.Attach(hBmp);
pBmpOld = (CBitmap *)dcScreen.SelectObject(&bmpTemp);

// You DON'T need to replace GDI objects if you select stock objects
// in - they can be safely left in - but it does not do any harm, and
// is good practice.
pPenOld = (CPen *)dcScreen.SelectStockObject(BLACK_PEN);
pBrOld = (CBrush *)dcScreen.SelectStockObject(WHITE_BRUSH);

// Draw on our bitmap before blitting...
dcScreen.Ellipse(64, 64, 192, 160);

dcScreen.SelectObject(pBrOld);
dcScreen.SelectObject(pPenOld);

// Paint it!
GetClientRect(&rctClient);
bmpTemp.GetObject(sizeof(BITMAP), &sBitmapInfo);
dc.StretchBlt(0, 0, rctClient.Width(), rctClient.Height(),
&dcScreen, 0, 0, sBitmapInfo.bmWidth,
sBitmapInfo.bmHeight, SRCCOPY);

// Tidy up resources.
dcScreen.SelectObject(pBmpOld);
bmpTemp.DeleteObject();

dcScreen.DeleteDC();
}



---

I can confirm that using CreateCompatibleBitmap() to create the bitmap rather than loading it from file ALSO works.

Does this help?