Transparent Animation Control

.

Sample Program Window

Environment: VC6 SP3, NT4 SP4 German (demo application tested with Win98 German)

As I wanted to put some animations (animated GIFs converted to AVIs) in my application by using the standard CAnimateCtrl, I realized that Microsoft and I interprete the term "transparent" differently.
If you set the flag ACS_TRANSPARENT in CAnimateCtrl, the background of the animation is in no way transparent, instead it is changed to COLOR_WINDOW. Not what I expected...

Since my application has a bitmap background the standard control was useless for me, and after staring some time at the AVIView sample sources, I decided to make my own class that supports real transparency ;-)

The following list shows the public functions of my class CAVICtrl and the flags you can use when loading an animation:

// functions
HRESULT Load(UINT nIDResource, DWORD dwFlags = 0L,  COLORREF clrTransparent = LTGREEN); // load from resource
HRESULT Load(LPCTSTR lpszFile, DWORD dwFlags = 0L,  COLORREF clrTransparent = LTGREEN); // load from file

BOOL Play(BOOL bOnce = FALSE);
BOOL Stop(BOOL bResetToFirst = FALSE);
void Seek(UINT nTo);
BOOL IsPlaying();

// call this function if the background of the parent 
// window changesvoid ReinitBackground(); 

// flags to use with Load()

AVC_HALFSPEED 0x0000001 // plays video with half speed
AVC_DOUBLESPEED 0x0000002 // plays video with double speed

AVC_CENTERAVI 0x0000004 // centers video inside the window
AVC_STRETCHAVI 0x0000008 // stretches video to fit inside of the window
AVC_CENTERRECT 0x0000010 // resizes window, center point stays the same

AVC_AUTOPLAY 0x0000020 // starts playing automatically after Load()

// background is COLOR_WINDOW 
// instead of transparent (like CAnimateCtrl's // AVS_"TRANSPARENT")
AVC_MAPWINDOWCOLOR 0x0000040 // ignore clrTransparent parameter and uses color of first // frame's first pixel instead (works only with 8bit images)
AVC_FIRSTPIXTRANSPRNT 0x0000080 
If you have a dialog based application, simply add a static control to your dialog and subclass it with a CAVICtrl in OnInitDialog() before calling one of the loading functions.
I recommend downloading the demo project which demonstrates the classes usage and the working of some of the flags.
This sample program also uses Joerg Koenigs very useful CBitmapDialog class to display the background image.

One great flaw is that the animation function itself is driven by a timer, so it stops if you click on the parent window to move or resize it.
I'm planning to put the animation code in a different thread for better performance and appearance, but this will be my first travel into the alien world of multithreaded programming, so please be patient ;-)

Comments, suggestions, bug reports etc. are welcome! Put them here as a comment or send them directly to me.

Enjoy!

Downloads

Download demo project - 140 Kb
Download source - 6 Kb


Comments

  • I like it!

    Posted by chi_luci on 03/07/2005 04:32pm

    very nice job!

    Reply
  • What about the status bar

    Posted by andrew@appliedcytometry.com on 04/02/2004 05:23am

    I wish to use a small avi with transparent background in a status bar pane. Is it possible with this code?

    Reply
  • What about w/o MFC?

    Posted by Legacy on 11/05/2003 12:00am

    Originally posted by: Chris Brown

    How would you convert such a program to non-MFC code? would it be quite the project?

    Reply
  • Problem with Seek() fixed

    Posted by Legacy on 04/23/2003 12:00am

    Originally posted by: BennyK

    I built a dialog app similar to the sample app.  Everything was working great except for the Seek function, which I need.  When I seek to a specific frame, it crashes in CAVICtrl::DrawCurrentFrame at:
    
    

    lpBi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(m_pGF, (LONG)m_nCurrentFrame);
    _ASSERTE(lpBi);

    I discovered that the Seek function is setting the m_nCurrentFrame to one beyond the last frame in the video. If I replace this:

    m_nCurrentFrame = __max(nTo, (UINT)m_lFrames);

    with this:

    m_nCurrentFrame = __min(nTo, (UINT)(m_lFrames - 1));

    then it works.

    Reply
  • Doesn't run in a separate thread

    Posted by Legacy on 01/27/2003 12:00am

    Originally posted by: Marc

    If I load an AVI inside a thread function AVIStreamOpenFromFile() fails... what should I do?

    Reply
  • What about 24 bits AVIs???

    Posted by Legacy on 01/24/2003 12:00am

    Originally posted by: Marc

    I am loading a 24 bits avi and no transparency... where should I modify it???

    Reply
  • Writing Animation Control In Assembly

    Posted by Legacy on 10/29/2002 12:00am

    Originally posted by: Steve

    Can a true transparent animation control be written in assembly such as MASM32. I'm not familiar with C++ etc.

    Thanks in advance.

    Congratulations to the person who wrote that transparent animation. I know it's not easy.

    Reply
  • full-screen an AVI

    Posted by Legacy on 06/24/2002 12:00am

    Originally posted by: ran

    How to enlarge the AVI movie or how to full-screen it???

    Reply
  • Dialog moving problem fixed !!!

    Posted by Legacy on 04/30/2002 12:00am

    Originally posted by: BlueDragon

    First, don't call ReinitBackground from CAVCDemoDlg::OnWindowPosChanging (so we can delete this methode), but from an OnSize handler 
    
    

    void CAVCDemoDlg::OnSize(UINT nType, int cx, int cy)
    {
    m_AviCtrl.ReinitBackground();
    CBitmapDialog::OnSize(nType, cx, cy);
    }

    Second change CAVICtrl::InitBackground() code
    from :
    ------

    // calculate position of control in parent
    GetWindowRect(&rcAVIWnd);

    // border moves window later, so we move it here too
    if (GetExStyle() & (WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME))
    {
    rcAVIWnd.OffsetRect(GetSystemMetrics(SM_CXEDGE),GetSystemMetrics(SM_CYEDGE));
    }
    else if(GetStyle() & WS_BORDER)
    {
    rcAVIWnd.OffsetRect(GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
    }

    rcParent = rcAVIWnd;
    pParentWnd->ScreenToClient(&rcParent);


    to :
    ----

    GetClientRect(rcParent);
    ClientToScreen(rcParent);
    pParentWnd->ScreenToClient(&rcParent);


    Enjoy :O)


    Reply
  • Fix : Strange Behavior when moving dialog !!!

    Posted by Legacy on 07/04/2001 12:00am

    Originally posted by: Binh Nguyen

     Very nice work!
    
    

    I'd like to introduce a solution for this minor problem.

    Add one line of code to

    void CAVICtrl::InitBackground()
    {
    ............... Many lines of code

    // get parents dc
    CClientDC dcParent(pParentWnd);

    // cleanup old dc & bmp if exist
    if (m_pbmpBkgOld)
    {
    m_dcBkg.SelectObject(m_pbmpBkgOld);
    m_dcBkg.DeleteDC();
    m_bmpBkg.DeleteObject();
    pParentWnd->InvalidateRect(rcAVIWnd); //Add this
    }

    // get parent image from behind control
    .........etc...
    }

    It's not really fix the problem but improve it much.

    Enjoy!
    Nguyen Binh

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The hard facts on SaaS adoption in over 80,000 enterprises: Public vs. private companies Mid-market vs. large enterprise GoogleApps, Office365, Salesforce & more Why security is a growing concern Fill out the form to download the full cloud adoption report.

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

Most Popular Programming Stories

More for Developers

RSS Feeds