Solved

Resource leak in my application...

Posted on 2001-08-30
9
239 Views
Last Modified: 2013-11-20
hi... I am having this problem... I am working on a tetris game, very simple.
But when I draw the blocks to the screen, I want to draw everything to a
temporary CDC first and then copy this CDC to the window DC, so I don't have
any flickering. I have worked on some code, and it works fine under windows
2000, but under windows 95/98/ME I end up running out of resources. I am
sure I am doing something wrong, I just can't figure that out. The code that
I have is....

void CChildView::RedrawGameScreen()
{
     int blockSize;
     int centerPoint;

     CDC * dc;
     CDC memdc;
     CRect clientRect;

     CBitmap membmp;
     CBitmap * pOldBmp;
     CBrush blackBrush;
     CBrush * pOldBrush;

     // Create the brush
     blackBrush.CreateSolidBrush(RGB(0,0,0));

     dc = this->GetDC();

     // Get the client are size
     GetClientRect(&clientRect);
     clientRect.NormalizeRect();
     
     // Create the dc and prepare to copy
     
     memdc.CreateCompatibleDC(dc);
     membmp.CreateCompatibleBitmap(dc,200,400);
     pOldBmp = memdc.SelectObject(&membmp);
     

     // Screen proportion
     blockSize = (int) (20 * ScreenRatio);
     centerPoint = clientRect.CenterPoint().x - (100*ScreenRatio);

     // Clear the background
     pOldBrush = memdc.SelectObject(&blackBrush);
     memdc.Rectangle(0,0,200,400);
     //dc->Rectangle(centerPoint,20,centerPoint+200,420);
     //pOldBrush = dc->SelectObject(&blackBrush);

     CGS.DrawGameDevice(&memdc,0,0,true);
     //CGS.DrawGameDevice(dc,centerPoint,20,true);

     dc->StretchBlt(centerPoint,20,(int) (200*ScreenRatio),(int) (400*ScreenRatio),&memdc,0,0,200,400,SRCCOPY);
     DrawScoreWindow(centerPoint + (200*ScreenRatio) + 20, 20);

     //dc->SelectObject(pOldBmp);
     dc->SelectObject(pOldBrush);

     // Cleanup
     membmp.DeleteObject();
     blackBrush.DeleteObject();
     memdc.DeleteDC();
     ::ReleaseDC(this->GetSafeHwnd(),dc->m_hDC);
}

I also posted the first way I did it, commented out, which is writing everything
straight to the window dc. It works fine under all windows, but the flickering
is so annoying that no one can stand it. I would really appreciate some feedback
on this. Thank you...

Roger
0
Comment
Question by:cracel
  • 4
  • 3
  • 2
9 Comments
 
LVL 3

Expert Comment

by:krispols
ID: 6443961
Hello, to delete an object it must be not used by a DC.

void CChildView::RedrawGameScreen()
{
    int blockSize;
    int centerPoint;

    CDC * dc;
    CDC memdc;
    CRect clientRect;

    CBitmap membmp;
    CBitmap * pOldBmp;
    CBrush blackBrush;
    CBrush * pOldBrush;

    // Create the brush
    blackBrush.CreateSolidBrush(RGB(0,0,0));

    dc = this->GetDC();

    // Get the client are size
    GetClientRect(&clientRect);
    clientRect.NormalizeRect();
   
    // Create the dc and prepare to copy
   
    memdc.CreateCompatibleDC(dc);
    membmp.CreateCompatibleBitmap(dc,200,400);
    pOldBmp = memdc.SelectObject(&membmp);
   

    // Screen proportion
    blockSize = (int) (20 * ScreenRatio);
    centerPoint = clientRect.CenterPoint().x - (100*ScreenRatio);

    // Clear the background
    pOldBrush = memdc.SelectObject(&blackBrush);
    memdc.Rectangle(0,0,200,400);
    //dc->Rectangle(centerPoint,20,centerPoint+200,420);
    //pOldBrush = dc->SelectObject(&blackBrush);

    CGS.DrawGameDevice(&memdc,0,0,true);
    //CGS.DrawGameDevice(dc,centerPoint,20,true);

    dc->StretchBlt(centerPoint,20,(int) (200*ScreenRatio),(int) (400*ScreenRatio),&memdc,0,0,200,400,SRCCOPY);
    DrawScoreWindow(centerPoint + (200*ScreenRatio) + 20, 20);

    //dc->SelectObject(pOldBmp);
    memdc->SelectObject(pOldBrush);
    memdc.SelectObject(pOldBmp);

    // Cleanup
    membmp.DeleteObject();
    blackBrush.DeleteObject();
    memdc.DeleteDC();
    ::ReleaseDC(this->GetSafeHwnd(),dc->m_hDC);
}
0
 

Author Comment

by:cracel
ID: 6443976
Sorry, I forgot to uncomment the memdc->SelectObject(pOldBmp). But on my original program the pOldBmp is selected back to the memdc.
0
 
LVL 3

Expert Comment

by:krispols
ID: 6444538
Ok, but the important thing is you must use memdc and not dc like there is in your program
0
Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
LVL 4

Expert Comment

by:jtwine100697
ID: 6445264
[Slightly Off Topic:]
> I am working on a tetris game, very simple

Be careful where you post the code to it when done!  I recently removed the code and exe to a multi-player version that I was working on because of licensing requirements by the current "agent" of the Tetris Brand.(http://www.blueplanetsoftware.com/tetrislicensing.htm)

While they should only have problems with anything that uses the name "Tetris", they have gone after shareware and freeware authors that have built tetris-like games.

Just make sure to CYA... It saves a lot of hassle and lost work! :(

-=- James.
0
 

Author Comment

by:cracel
ID: 6445593
but I am using a memdc, aren't I ?

CDC memdc;
memdc.CreateCompatibleDC(dc);
membmp.CreateCompatibleBitmap(dc,200,400);

is this not they way I should have done it ? I am sorry, I am pretty new to C and windows programming, just learned it through a book a couple months ago. If this is wrong please explain to me the way this should be done. Thanks.

Roger
0
 

Author Comment

by:cracel
ID: 6445599
thanks for the advice... but if I call it something like DTris, I should be fine right?

Roger
0
 
LVL 3

Accepted Solution

by:
krispols earned 75 total points
ID: 6450117
I talked about when you release it. It's correct to use memdc but you must release it with the same dc. so, at the bottom of your code, use:

memdc.SelectObject(pOldBmp);
memdc.SelectObject(pOldBrush);

instead of:

dc->SelectObject(pOldBmp);
dc->SelectObject(pOldBrush);
0
 
LVL 4

Expert Comment

by:jtwine100697
ID: 6450987
[Slighty Off-Topic]
> >  they have gone after shareware and freeware authors that have built tetris-like games.

If you search for "tetris blue planet legal" (http://www.google.com/search?q=tetris+blue+planet+legal), you should find instances where they have "gone after" authors of Tetris-like games...  you will also find arguments that they are full of hot air and are only trying to scare shareware authors.  Perhaps.  But do you have the legal money to find out?  I know that I do/did not...

------------

[Back On-Topic]
Also, for the selecting-back of previous objects into the DC, you might want to look into the SaveDC(...) and  RestoreDC(...) functions, they can help reduce the calls to return the DC back to its previous state.

-=- James.
0
 

Author Comment

by:cracel
ID: 6451211
thanks krispols....

I posted that code in a couple different discussion boards and nobody spoted that. I went through that code myself over 100 times and didn't spot that. I knew it was something simple... thank you...
Roger
0

Featured Post

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question