Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Redrawing problems

Posted on 2006-05-26
8
Medium Priority
?
694 Views
Last Modified: 2013-11-20
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);
}

0
Comment
Question by:sparkythedog
6 Comments
 
LVL 8

Expert Comment

by:Knut Hunstad
ID: 16772075
Have you tried simply with:

gr.clear()

before:

gr.DrawImage(m_pBitmap, pt);

??
0
 
LVL 8

Accepted Solution

by:
Knut Hunstad earned 672 total points
ID: 16772134
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
 

Author Comment

by:sparkythedog
ID: 16772149
Yeap, I already tried that one with Clear, and is flickering.
Thanks for the links I will take a look

A-
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 664 total points
ID: 16772457
<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
 
LVL 22

Assisted Solution

by:mahesh1402
mahesh1402 earned 664 total points
ID: 16774524
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
 

Author Comment

by:sparkythedog
ID: 16820717
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

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
How can you see what you are working on when you want to see it while you to save a copy? Add a "Save As" icon to the Quick Access Toolbar, or QAT. That way, when you save a copy of a query, form, report, or other object you are modifying, you…
Suggested Courses
Course of the Month10 days, 22 hours left to enroll

572 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