
Introduction
A friend of mine recently asked for advice related to showing animations on a C# WinForm. The question reminded me of some code I wrote back in 2001 to create a managed wrapper for the Windows common animation control. This article outlines that control and demonstrates a possible use of the control with a small sample application.
Using the code
Using the control in an application is no different than using any other WinForm control. Essentially, you should follow these steps:
- In Visual Studio, select the 'View' | 'Toolbox' option to display the toolbox.
- Right mouse click over the toolbox (not on an icon) and choose 'Add/Remove items...'
- On the 'Customize Toolbox' form, click the 'Browse...' button.
- Browse to the place where you downloaded the CG.Animation.dll file (see the links at the top of the article).
- Click OK (the toolbox should now include an icon for the animation control).
- Open a form in the Visual Studio designer and drag/drop the animation control onto the form.
Once an instance of the animation control exists on the form, you may adjust the properties using the Visual Studio property designer. The properties exposed by the control include:
AVIFileType - Allows a developer to choose from a list of standard animations or select a custom animation.
AutoCenter - Automatically centers the animation in the control.
AutoPlay - Starts playing the animation automatically.
FileName - Used to specify the name of a custom animation file.
Transparent - Forces the animation to use the background color of the control.
UseTimer - Directs the underlying control to use a timer for internal updates.

The control also exposes a few methods for altering the behavior at runtime. Here is a list of those methods:
Open() - Opens the animation file specified by the AnimationType and FileName properties.
Close() - Closes the currently open animation.
Stop() - Stops the currently playing animation.
Play() - Plays the currently open animation from start to finish in an endless loop.
Play(int repetitions) - Plays the currently open animation from start to finish, the specified number of times.
Play(int repetitions, int startFrame, int endFrame) - Plays the currently open animation from the specified frames, looping the specified number of times.
Seek(int frame) - Positions the currently open animation to the specified frame.
That's pretty much it. The control is simple to use.
Inside the control
The control gains the ability to play animations by subclassing the 'SysAnimate32' Windows common control class. The subclassing step is performed by overriding the CreateParms property and specifying the name of the Windows class. Here is what that code looks like:
protected override CreateParams CreateParams
{
get
{
CreateParams parms = base.CreateParams;
parms.ClassName = "SysAnimate32";
if (AutoCenter)
parms.Style |= NativeMethods.ACS_CENTER;
if (AutoPlay)
parms.Style |= NativeMethods.ACS_AUTOPLAY;
if (Transparent)
parms.Style |= NativeMethods.ACS_TRANSPARENT;
if (UseTimer)
parms.Style |= NativeMethods.ACS_TIMER;
return parms;
} }
In order to use a Windows common control class, you should start by initializing the common control library. That step is performed using the following code:
protected override void CreateHandle()
{
if (!RecreatingHandle)
{
NativeMethods.INITCOMMONCONTROLSEX iccex =
new NativeMethods.INITCOMMONCONTROLSEX(
NativeMethods.ICC_ANIMATE_CLASS
);
NativeMethods.InitCommonControls(iccex);
}
base.CreateHandle();
}
The standard Windows animations are loaded dynamically from the shell32.dll library. I used this approach because I didn't want to embed standard AVI files in my application resources, and I figured most other people would feel the same way. The code to load the library resources is shown here:
private void OpenHelper(
CGAVIFileType aviFileType
)
{
if (!IsHandleCreated)
return;
Close();
if (m_hShellModule == 0)
m_hShellModule = NativeMethods.LoadLibraryEx(
"shell32.dll",
0,
2
);
m_isOpen = (NativeMethods.SendMessage(
new HandleRef(this, Handle),
NativeMethods.ACM_OPEN,
m_hShellModule,
(int)aviFileType
) != 0);
if (AutoPlay)
Play();
}
The ACM_OPEN message is defined by Windows and is used to load an AVI resource at runtime. In this case, from the shell32.dll library. To open a custom (external) AVI file instead, the control uses the following code:
private void OpenHelper(
string fileName
)
{
if (!IsHandleCreated)
return;
Close();
m_isOpen = (NativeMethods.SendMessage(
new HandleRef(this, Handle),
NativeMethods.ACM_OPEN,
0,
fileName
) != 0);
if (AutoPlay)
Play();
}
Conclusion
That's pretty much all that is interesting about the internals of the control. I have used the code for a number of years without problems but there is always room for improvement - right? I cleaned things up somewhat before I published the project (be glad you don't have to look at my C# code from 2001). As always, I am interested in any feedback or suggestions.
Have fun! :o)
History
I wrote the original code in 2001. I have updated things sporadically since then but I haven't always maintained versions and change history. I decided to bump the version number up to 2.0 for this release.
Version 2.1 --> I changed the names of the enumerated animation types and the default size of the control in order to differentiate my code from other animation controls.
I am a C# developer specializing in creating object-oriented software for Microsoft Windows. When I am not programming I enjoy reading, playing the guitar/piano, running, watching New York Ranger hockey, designing and building wacky electronic devices, and of course enjoying good times with my wife and children.