Amimated bitmap

Posted on 1998-06-14
Last Modified: 2010-04-01
I need to animate 2 bitmaps: my idea is to switch from first one to second one using a timer.
Every tick of timer I show the other bitmap (that I've previously loaded from file)

And it works, but with Win95 after a while the window refresh stops and I must restart the application.

Question by:cipeciop
  • 7
  • 4
LVL 22

Expert Comment

ID: 1165872
answer coming.
LVL 22

Expert Comment

ID: 1165873
It sounds like you have a resource leak.  For example, if you select the bitmap into a DC for drawing and then don't select the original bitmap back in, the original bitmap won't be deleted.  This will cause a slow, but steady consumption of GDI resources until GDI or your application can't function.

If you post your code, I might be able spot your error.  Otherwise, you should look for instances where you application does not clean up as it should.
LVL 22

Expert Comment

ID: 1165874
What is wrong with my answer?  You've rejected it, but not indicated why you think it is wrong or what additinal information you would like.  I suspect, in fact, that it is still right.
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.


Expert Comment

ID: 1165875

1. It is customary to leave a comment when rejecting an answer. The reason is that another expert comes along, sees that someone gave an answer and you rejected him/her without any a comment or further information and figures Why try and help if this person isn't going to give any feedback on proposed answers/comments.

2. I would be really interested in hearing why you rejected nietod's answer since it is definitely the first thing that I would think of as well.



Author Comment

ID: 1165876
I'm sorry, but I was sure to have added this information: with
Windows NT works (that's why I rejected: it gave no hints
about this difference, NT OK, 95 NOK)
LVL 22

Accepted Solution

nietod earned 100 total points
ID: 1165877
NT has a 32 bit GDI and 95 has only a 16 bit GDI.  This means 95 runs out of GDI resources much more easily than NT.  95 tries to get around the limitation somewhat by using several different 16 bit heaps (3 of them???), but they are still only 64K and run out long before NT's single heap of comparibly limitless size.

Author Comment

ID: 1165878
I think to deselect all resources..

here's my code

CMyBitmap::MyDrawBitmap(CDC * pDC, CBitmap & bitmap, CPalette * pPal)
      // Create a compatible memory DC
      CDC memDC;
      BOOL fRes;
      fRes = memDC.CreateCompatibleDC( pDC );
      ASSERT (fRes != FALSE);
      CBitmap *oldbitmap=NULL;
      oldbitmap = memDC.SelectObject( &bitmap );
      ASSERT (oldbitmap != NULL);
      CPalette *oldpalette=NULL;

      // Select and realize the palette
      if( pPal != NULL && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
            oldpalette = pDC->SelectPalette( pPal, FALSE );
            ASSERT (oldpalette != NULL);

      BITMAP bm;
      bitmap.GetBitmap( &bm );

      //pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0,SRCCOPY);
      fRes = pDC->BitBlt(m_Newx, m_Newy, bm.bmWidth, bm.bmHeight, &memDC, 0, 0,SRCCOPY);
      ASSERT (fRes != FALSE);

      if (oldpalette != NULL)
            memDC.SelectPalette(oldpalette, FALSE );
      if (oldbitmap != NULL)

LVL 22

Expert Comment

ID: 1165879
First of all.  Never accept an answer until you have a working solution.  My answer was just a guess.  You should wait until we get it worked out.

The code above seeems to clean up correctly.  Does the code that uses it?  The three objects passed to it all need to be (eventually) deleted.  Can you post that code?

One small point.  The lines at the end that select back to original palette and bitmap don't need to be in if's, somce you have asserts to make sure these are not NULL above.  In addition, if you didn't select back the original objects, it would leave your objects selected in and that would be as bad an error as selected in a NULL pointer.  

Try to post the code that uses this.

Author Comment

ID: 1165880
Your answer seems to be THE correct guess (now the program
is working since yesterday without problems).
Yes, the objects are attributes of the class containing the
function I've sent, they are (implicitly) deleted in the destructor.
I've put the Asserts after the if just to check everything.
I don't understand the "if you didn't select back...." period.
LVL 22

Expert Comment

ID: 1165881
>> Your answer seems to be THE correct guess (now the program  is working since yesterday without problems).

I proposed something to look for.  But I didn't see any examples of that problem in the source you sent.  Did you fix something before you sent it?  

My last point is that what you get back fromf SelectObject has to be selected back in at the end.  You have those statements inside if's.  However you can assume that those if's will allways execute their code.   So you don't neeed the if's, just the SelectObjects inside them.  That will be faster and shorter.

Author Comment

ID: 1165882
The function I've modified is

CNIMMIView::DrawBackGround(CDC & pDC)
      CRect rect;
      CBrush *oldbru=NULL;
      CPen *oldpen=NULL;
      GetClientRect (&rect);
      CBrush bru(clSilver);
      CPen pen(PS_NULL, 1, clSilver);

      oldbru = pDC.SelectObject (&bru);
      ASSERT (oldbru != NULL);
      oldpen = pDC.SelectObject (&pen);
      ASSERT (oldpen != NULL);

      pDC.Rectangle (&rect);

      pDC.SelectObject (oldpen);
      pDC.SelectObject (oldbru);
}// end of DrawBackGround()

I had forgot the last 2 SelectObject(): that was the error.
About the if's: but the do the asserts work even in release build ? (if they do work
only with debug build I must avoid to Select() a NULL object isn't it ?

LVL 22

Expert Comment

ID: 1165883
Okay so it was the problem I suggested.

The asserts don't work int he release code (they are not included in the code).  However, that;'s not the issue.  The if's I suggested you remove, protect you from one error by causing another one.  (one that will harder to track down.)

Take a look at
   CBrush newbru(clSilver);
   CBrush *oldbru = pDC.SelectObject (&newbru);

   if (oldbrh)
      pDC.SelectObject (oldbru)

Now say that oldbrh is set to NULL but the select object.  So you don't select in a NULL pointer.  That prevents an error their.  However, it leaves in the pointer to the "newbru".  That newbrh is then destroyed, but the pDC contains a pointer to it.  Thus you still have an error.

You can safely assume that selectobject will not return a NULL pointer.  If it does return a NULL pointer things are going to h**l anyways, so don't bother trying to prevent an error.


Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

860 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