Jump to content
  • Advertisement
Sign in to follow this  
PlayfulPuppy

(GDI) Resource leak and double-buffered windows

This topic is 4916 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm creating a Win32 GDI 'wrapper' of sorts, and I'm using a secondary DC to do double buffering. This was working fine until I realised I had to resize objects, in which case I couldn't really find a good way to resize the DC without deleting it and creating a new one each time something on the window changed. Problem is, I appear to be leaking resources at an alarming rate from creating and deleting the secondary DC:
if(requireUpdate)
{
	DeleteDC(m_drawDC);
	m_drawDC = CreateCompatibleDC(m_hDC);
	HBITMAP tmpBitmap = CreateCompatibleBitmap(m_hDC, m_width, m_height);
	DeleteObject(SelectObject(m_drawDC, tmpBitmap));
	// Draw object...
}
BitBlt(m_hDC, 0, 0, m_width, m_height, m_drawDC, 0, 0, SRCCOPY);

Just for note, an m_drawDC is created during the window initialisation, just in case it seems wierd that I'm destroying it before creating it. First off, what's causing the resource leak? If I comment this section out and just let it use the originally created m_drawDC it works fine, but this method causes my machine to chew up about 20 megs after a few seconds of resizing the window. Secondly, is there a better way to do this with the GDI? Deleting and re-creating the DC every time makes it slow as hell comparitivly, and although I could probably just make it recreate the DC on resize, I'm a sucker for a smoothly resizing window.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by PlayfulPuppy
First off, what's causing the resource leak? If I comment this section out and just let it use the originally created m_drawDC it works fine, but this method causes my machine to chew up about 20 megs after a few seconds of resizing the window.

You don't need to free the DC, only the associated bitmap. Also, you're calling DeleteObject() on a HBITMAP owned by the GDI, which probably isn't doing anything. Try this:

// You'll need this as a member variable of the class:
// HBITMAP m_hOldBmp;

if(requireUpdate)
{
// Put the old bitmap back. We should get our bitmap out
HBITMAP hMyBitmap = SelectObject(m_drawDC,m_hOldBmp);

// Delete and re-create
DeleteObject(hMyBitmap);
HBITMAP tmpBitmap = CreateCompatibleBitmap(m_hDC, m_width, m_height);

// Select the new bitmap in, and store the GDI one
m_hOldBmp = (HBITMAP)SelectObject(m_drawDC, tmpBitmap)

// Draw object...
}


It may be "better" to store the HBITMAP that you create as another member variable, and ignore the return value of the first SelectObject() call there.

Quote:
Original post by PlayfulPuppy
Secondly, is there a better way to do this with the GDI? Deleting and re-creating the DC every time makes it slow as hell comparitivly, and although I could probably just make it recreate the DC on resize, I'm a sucker for a smoothly resizing window.

This should be slightly faster (You only re-create the HBITMAP now). You could try allocating a slightly larger bitmap, so if the screen is 300x200, you coukld allocate 450x300. Then, if the window is resized, you don't need to do anything until it gets to 450x300. Of course it'll use up more resources, but its the usual speed vs memory tradeoff.

Share this post


Link to post
Share on other sites
That's a dangerous piece of code that your using.

// Put the old bitmap back. We should get our bitmap out
HBITMAP hMyBitmap = SelectObject(m_drawDC,m_hOldBmp);

// Delete and re-create
DeleteObject(hMyBitmap);

Your deleting a bitmap that you may not own!! Dont do this, or atleast realize that you may delete soemthing you don't own by doing this.

CHeers
Chris

Share this post


Link to post
Share on other sites
Quote:
Original post by chollida1
That's a dangerous piece of code that your using.

// Put the old bitmap back. We should get our bitmap out
HBITMAP hMyBitmap = SelectObject(m_drawDC,m_hOldBmp);

// Delete and re-create
DeleteObject(hMyBitmap);

Your deleting a bitmap that you may not own!! Dont do this, or atleast realize that you may delete soemthing you don't own by doing this.

CHeers
Chris

Actually, that bitmap is owned ;)
We create a bitmap, and then select it into the DC. When this piece of code runs, we put the old bitmap back and get the bitmap we own out of it. Although I don't like it, which is why I said:
Quote:
Original post by Evil Steve
It may be "better" to store the HBITMAP that you create as another member variable, and ignore the return value of the first SelectObject() call there.

Share this post


Link to post
Share on other sites
My mistake, I didn't see any code that created teh bitmap so I assumed it was teh one that came from the DC:)

Cheers
Chris

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!