Redrawing problems

I have created a small class to play a GIF file by using GDI. (the class is derived from CStatic), but I have some problems with the redrawing. Basically I have a timer, and when the timer is signaled I will read the next frame from the GIF. The problem is that the previously disaplayed frame from the gif is not erased from the dialog.

Thanks,
A-

//Load the GIF file
BOOL CImageView::LoadImage(CString strFileName)
{
      if( m_pBitmap )
      {
            delete m_pBitmap;
      }

      m_pBitmap = Bitmap::FromFile(strFileName.AllocSysString());

      if( !m_pBitmap ) return 0;

      UINT nCount = m_pBitmap->GetFrameDimensionsCount();
      GUID* pDimensionID = new GUID[nCount];

      // Get the list of frame dimensions from the Image object.
      m_pBitmap->GetFrameDimensionsList(pDimensionID, nCount);

      // Get the number of frames in the first dimension.
      UINT uFrameCount = m_pBitmap->GetFrameCount(&pDimensionID[0]);

      if( uFrameCount > 1 )
            m_bAnimateBmp = 1;

      SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE)|WS_EX_TRANSPARENT);

      UpdateWindow();

      m_Play = SetTimer(1, 100, NULL);

      return 1;      
}

LRESULT CImageView::OnPaint(HDC hDC)
{
      if( !m_pBitmap ) return 1;

      
      CRect rcClient;
      GetClientRect(rcClient);

      Graphics gr(hDC);

      Point pt(0,0);
      if( m_bAnimateBmp )
      {
            GUID pageGuid = FrameDimensionTime;
            m_pBitmap->SelectActiveFrame(&pageGuid, frame);
            frame++;
            if (frame > uFrameCount-1)
                  frame  = 0;
      }

      pt.X = (rcClient.Width()-m_pBitmap->GetWidth())/2;
      pt.Y = (rcClient.Height()-m_pBitmap->GetHeight())/2;
      
      gr.DrawImage(m_pBitmap, pt);


      return 0;
}
LRESULT CImageView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
      if( message == WM_PAINT )
      {
            PAINTSTRUCT ps;
            HDC hdc = ::BeginPaint(m_hWnd, &ps);
            LRESULT lres = OnPaint(hdc);
            ::EndPaint(m_hWnd, &ps);
            return lres;
      }
      if( message == WM_ERASEBKGND )
      {
            return 1;
      }
      
      return CStatic::WindowProc(message, wParam, lParam);
}

void CImageView::OnTimer(UINT nIDEvent)
{
      
      if (m_Play == nIDEvent)
      {
            Invalidate();
            UpdateWindow();
      }
      
      CStatic::OnTimer(nIDEvent);
}

sparkythedogAsked:
Who is Participating?
 
Knut HunstadCommented:
Althought my previous suggestion might give you what you specifically asked for, I am guessing you won't be happy, because this will result in flickering? Take a look at: http://www.codeproject.com/bitmap/pictureex.asp for help on this. Or other articles at: http://www.codeproject.com/bitmap/#Bitmaps, which seems to handle about every aspect there is around this...
0
 
Knut HunstadCommented:
Have you tried simply with:

gr.clear()

before:

gr.DrawImage(m_pBitmap, pt);

??
0
 
sparkythedogAuthor Commented:
Yeap, I already tried that one with Clear, and is flickering.
Thanks for the links I will take a look

A-
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

 
AndyAinscowFreelance programmer / ConsultantCommented:
<The problem is that the previously disaplayed frame from the gif is not erased from the dialog.>

In your WindowProc you have
 if( message == WM_ERASEBKGND )
     {
          return 1;
     }

This means you will redraw your background yourself (overpaint the previous image).  I don't see you doing that in your OnPaint handler.
0
 
mahesh1402Commented:
I am not sure or may be the case your Frame is not fully loaded in static control ?......

Following may be Useful for you...

A CStatic derived class for displaying GIF Animations with Full Src Code :
http://www.codeproject.com/staticctrl/gifanimation.asp <==  Uses Threads.. Have look at GifAnimation.H/GifAnimation.CPP and WinImage.H/WinImage.CPP files !

Hope This Helps.

-MAHESH
0
 
sparkythedogAuthor Commented:
Here is the solution guys:

BOOL CImageView::LoadImage(CString strFileName)
{
      if( m_pBitmap )
      {
            KillTimer(m_uTimerID);
            delete m_pBitmap;
            m_nFrameCount = 0;
            m_nCurrentFrame = 0;
      }

      m_pBitmap = Bitmap::FromFile(strFileName.AllocSysString());

      if( !m_pBitmap ) return 0;

      UINT nCount = m_pBitmap->GetFrameDimensionsCount();
      GUID* pDimensionID = new GUID[nCount];

      // Get the list of frame dimensions from the Image object.
      m_pBitmap->GetFrameDimensionsList(pDimensionID, nCount);

      // Get the number of frames in the first dimension.
      m_nFrameCount = m_pBitmap->GetFrameCount(&pDimensionID[0]);

      SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE)|WS_EX_TRANSPARENT);

      m_uTimerID = SetTimer(TIMERID, 100, 0);

      UpdateWindow();

      return 1;      
}


LRESULT CImageView::OnPaint(HDC hDC)
{
      if( !m_pBitmap ) return 1;

      CRect rcClient;
      GetClientRect(rcClient);

      Bitmap bitmap(rcClient.Width(), rcClient.Height(), PixelFormat24bppRGB);
      Graphics gr(&bitmap);

      //////////////////////////////////////////////////////////////////////////
      HBITMAP hBmp = 0;

      HWND hParent = ::GetParent(m_hWnd);
      CRect rcParent;
      ::GetClientRect(hParent,rcParent);

      
      // get a copy of the parent's background
      {
            HDC hScreenDC = ::GetDC(0);
            HDC hTempDC = ::CreateCompatibleDC(hScreenDC);
            hBmp = CreateCompatibleBitmap(hScreenDC, rcParent.Width(), rcParent.Height());
            HGDIOBJ hOldBmp = ::SelectObject(hTempDC, hBmp);

            ::SendMessage(hParent, WM_ERASEBKGND, (WPARAM)hTempDC, 0);

            ::SelectObject(hTempDC, hOldBmp);
            ::DeleteDC(hTempDC);
            ::ReleaseDC(hParent, hScreenDC);
      }
      
      
      Bitmap BmpBkg(hBmp,0);
      DeleteObject(hBmp);

      CRect rcBkg(rcClient);

      ::ClientToScreen(m_hWnd, (LPPOINT)(LPRECT)rcBkg);
      ::ClientToScreen(m_hWnd, ((LPPOINT)(LPRECT)rcBkg)+1);
      ::ScreenToClient(hParent, (LPPOINT)(LPRECT)rcBkg);
      ::ScreenToClient(hParent, ((LPPOINT)(LPRECT)rcBkg)+1);

      // draw background
      gr.DrawImage(&BmpBkg, 0,0,rcBkg.left,rcBkg.top, rcBkg.Width(), rcBkg.Height(), UnitPixel);
      //////////////////////////////////////////////////////////////////////////
      
      // draw image
      Point pt(0,0);
      if( m_nFrameCount > 1 )
      {
            GUID pageGuid = FrameDimensionTime;
            m_pBitmap->SelectActiveFrame(&pageGuid, m_nCurrentFrame);
      }

      long width1 = m_pBitmap->GetWidth();
      long height1 = m_pBitmap->GetHeight();
      long width2 = rcClient.Width();
      long height2= rcClient.Height();
      
      pt.X = (width2 - width1)/2;
      pt.Y = (height2 - height1)/2;
      
      gr.DrawImage(m_pBitmap, pt);


      // flicker free drawing
      Graphics grOrig(hDC);
      grOrig.DrawImage(&bitmap, 0,0);

      return 0;
}

LRESULT CImageView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
      if( message == WM_PAINT )
      {
            PAINTSTRUCT ps;
            HDC hdc = ::BeginPaint(m_hWnd, &ps);
            LRESULT lres = OnPaint(hdc);
            ::EndPaint(m_hWnd, &ps);
            return lres;
      }
      if( message == WM_ERASEBKGND )
      {
            return 1;
      }
      
      return CStatic::WindowProc(message, wParam, lParam);
}

void CImageView::OnTimer(UINT nIDEvent)
{
      if( nIDEvent == m_uTimerID )
      {
            m_nCurrentFrame++;

            if( m_nCurrentFrame >= m_nFrameCount )
                  m_nCurrentFrame = 0;

            InvalidateRect(0,0);
      }
      
      CStatic::OnTimer(nIDEvent);
}

Thanks for your help, I'm gonna split the points anyway for helping me finding the answer.

Thanks,
A-
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.