Jump to content
Xtreme .Net Talk

Recommended Posts

Posted (edited)

With help from this forum I was able to figure out the double buffer solution using gdi32's BitBlt in C#.net.

 

GDI+ is well known for its lack of speed in the performance arena.

 

To solve the "flicker" solution, and add a fast back buffer to my application, i dipped back into gdi32.

 

What you'll want to do is this..

 

On your form, create a picturebox that will show your live drawing. Lets call it picChart.

 

Now, what we need to do is create a back buffer for our picChart.

private Bitmap memBmp;	// Backbuffers bitmap
private IntPtr hMemBmp;	// Handle to our memBmp
private Graphics memDC;	// We draw on this
private IntPtr hMemdc;	// Handle to our memDC
private void picChart_Resize(object sender, EventArgs e)
{
// If we have already created a dc for mem, lets free it up first
if (hMemdc.ToInt32() != 0)
{
	// Clean up
	DeleteObject(hMemBmp);
	DeleteDC(hMemdc);
	memBmp.Dispose();
}

// Resize our backbuffer
memBmp = new Bitmap(picChart.Width, picChart.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555 );
Graphics clientDC = picChart.CreateGraphics();

IntPtr hdc = clientDC.GetHdc();
hMemdc = CreateCompatibleDC(hdc);	// hMemdc is the handle to our memDC
hMemBmp = memBmp.GetHbitmap();
SelectObject(hMemdc, hMemBmp);
memDC = Graphics.FromHdc(hMemdc);	// We draw on memDC

// Clean up
clientDC.ReleaseHdc(hdc);
clientDC.Dispose();
}

private void picChart_Paint(object sender, PaintEventArgs e)
{
// Copy Region from memDC
IntPtr hdc = e.Graphics.GetHdc();

BitBlt(hdc, e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height, hMemdc, e.ClipRectangle.X, e.ClipRectangle.Y, 0x00CC0020);

e.Graphics.ReleaseHdc(hdc);
}

 

What the above code does is create a backbuffer the same size of our picChart every time the picChart is resized. If we have already created a backbuffer from a previous resize event, we delete the previous backbuffer from memory.

 

Then in the picChart paint event, we will bitblt the exact region that was invalidated to our main picChart paint area.

 

Also, in your form/controls dispose() method you will need to add:

// If we have already created a dc for mem, lets free it up first
if (hMemdc.ToInt32() != 0)
{
	// Clean up
	DeleteObject(hMemBmp);
	DeleteDC(hMemdc);
	memBmp.Dispose();
}

 

That will free up your backbuffer if it was created before the form/control disposes.

 

 

To draw on your backbuffer, all you have to use is memDC.Drawxxx to draw whatever you like.

 

It still uses GDI+ drawing techniques but will use the faster gdi32 bitblt to doublebuffer and repaint your form.

 

Hope this helps.

Edited by PlausiblyDamp
  • Like 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...