Animated Controls

By: Kenn Scribner for TechTalk

Originally this article used a Microsoft tool called VidEdit. However that tool has since joined the brontosaurus (it was written in 1993 after all). However, there are other AVI editing tools out there. This one, AVI Creator, is available as a free download.

Copyright Note: I also used the word "steal" in reference to using artwork. Reader Mark S. long ago elevated my thinking, so please believe me when I say I didn't mean use copyrighted materials from other sources. I meant reuse your own artwork where you can. If you do use someone else's artwork, always do so with permission.

Run the demo program (all demos require Visual C++ 5.0!)
Download the demo source

Background: I was faced with this very dilemna...how to build an animated control to be placed in an application I was coding at the time. I read several books, some of which mentioned there existed such things as "animated controls". Others gave no mention of them at all. None told me how to actually build the AVI file the controls would require! Finally, I had to call Microsoft Technical Support (I hate doing that...I'd much rather fight it out), and after a couple of weeks we had it figured out. Microsoft Technical Support is top-notch, no doubt. It's just the tools Microsoft had delivered to the developer community didn't provide for AVI file generation, with the exception of this 16-bit SDK, if you can believe that. Real-life solution to a real-life programming problem!

Creating and Using Animation Controls in Windows 95 and NT 4.0

Part I, Creating the AVI File
(Part II, Creating the Animated Control)

I’ll admit it. I like the gadgets Microsoft included in Windows 95 and Windows NT 4.0, so I use a lot of the various "custom controls" in my own applications. I’m sure we all want our applications to be more professional in appearance, so using the cool controls Windows users are now familiar with is a good start. One particular custom control has eluded me for some time, though. This would be the animated, or animation, control. We’ve all seen them in action. To see an example, copy a large file to a floppy disk and watch the animated "paper" fly from one "folder" to the other. That’s an animated control.

It isn’t that the control is so hard to understand. It’s really very easy to use, and the MFC class CAnimateCtrl does a great job encapsulating this simplicity. "Open". "Play". "Stop". It doesn’t get much easier than that, right? There is just one major hurdle. Okay, maybe a few, but this one is a really BIG one. The animated custom control requires an "AVI" file. So what is an AVI file and how do we create one?

Well, the AVI file is really a special file format Microsoft uses to contain a series of device independent bitmaps, or DIBs. The DIBs are shown in sequence, which gives the illusion of motion. If you happen to have video editing software, you are most likely are able to capture video and store the digitized video to an AVI file. Most people, myself included, don’t have any such capability, and most video editing software I’ve heard of doesn’t really support what we want to do, which is draw pictures ourselves instead of capturing them from video. I’ve heard there are some packages out there which work with AVI files, such as "CorelDraw!", but I can’t say with certainty. As with the video editing software, not everyone can afford the heavy price tag of some of the hard-core image editing software packages, including me.

So, what do we do? It turns out Microsoft has written and distributes a small utility called "VidEdit", which is included with their "Video for Windows" SDK (you can download it along with this issue’s demonstration program). Using VidEdit, let’s create an AVI file (this issue) and see how we might take that and actually generate an animated control (next issue). I’ll first give you all of the steps, then I’ll get into the details. Here are the steps:

1) Create your "frames". (The "content" of the AVI file.) – part I, this issue
2) Run VidEdit and load your frames.
3) Save your frames as an AVI file and test.
4) Build/Open your Visual C++ project/application file -- part II, next issue
5) Incorporate your new AVI file as a resource.
6) Place an animated control where you need one (like a dialog box you’ve created)
7) Go though the usual ClassWizard exercise to generate a member variable for DDX
8) Modify your source code to load the AVI resource and play the sequence.
9) Compile and test.

Sounds easy, and it is, but there are some details you need to understand to be successful. Let’s now go step by step and talk some bits and bytes. Creating frames is an artistic endeavor, so if you’re artistic, great! If not, you still need to create the animation sequence, and there isn’t much anyone who isn’t particularly gifted artistically can do unless they hire an artist. You could "swipe" existing animated controls using screen capture (<alt>-<prtscn> or something) and cut/paste in "Paint", or convert an animated GIF sequence from the Internet to a series of bitmaps (see note above!). In any case, once you have a bitmap for a frame, how you name the individual frame filename is critical…it must be named such that the name ends with the frame number (frame0.bmp, frame1.bmp, etc.). It also must be stored as 256-color bitmap (.bmp files). If you want "transparency" (allow background window color through), you should know the upper left-hand corner pixel of the first frame will dictate the transparent color. Any pixel of this color in this or any other frame in the AVI file will be transparent. Building this animated sequence is the most painful part of the animated control process, I believe. But if you’re successful in creating a good animation sequence, though, it will be worth the pain later! They really look great.

So let’s assume you have an animation sequence, that the individual files are named correctly, that the transparent color (in the upper left-hand corner of the first image) is set, and the files are saved as 256-color bitmaps. We now run VidEdit. Under File-Open, using the standard "open" dialog box, we want to see "All Files (*.*)", as the default file extensions (types) probably won’t yet apply to us (open AVIs, movies, etc.). We want to open our first frame’s bitmap file, which for the sake of argument we’ve named "frame0.bmp". VidEdit will look at the bitmap file and know it isn’t one of the "standard" VidEdit files, so it will ask you, via dialog box, what this file will represent. You respond with "DIB Sequence"…just use the provided list box, select "DIB Sequence", and click "OK". VidEdit will load your bitmaps, in order based on their filenames, and keep this frame collection in memory as a device independent bitmap sequence.

Once the frames are loaded, VidEdit will allow you to "play" the sequence, so for the first time you can see what your animated control might look like. Don’t like it? Modify the offending frames and reload the entire sequence into VidEdit. Like it, except for the strange flicker at the end? You’ll probably note VidEdit inserted a "blank" frame at the end of your sequence. Using the "mark out" button, eliminate this blank frame from the sequence (see VidEdit’s "help" file for more detail). You may also want to modify the "frame rate" at which the AVI file will play. The default is 15 frames per second, so if this is too fast, you can slow it down using Video-Convert Frame Rate…. Now we’re ready to build an AVI file.

Under File-Save As…, type in a filename. You’ll note ".avi" was the default extension choice, which is what we want. Before you actually save the file, though, you should know the animated control will only accept AVI files which DO NOT have sound and are uncompressed. So, just to be sure, press the "Compression Options" button. In the resulting dialog box, be sure the "Target" is "CD-ROM (150 KB/Sec)" and the "Video Compression Method" is "Full Frames (Uncompressed)". Click "OK" and save your new masterpiece.

Just to be sure everything is fine, let’s test the AVI file we created by using the multimedia software provided with Windows. Click the "Start" button and select "Programs/Accessories/Multimedia/Media Player". This will bring up the generic multimedia file viewer (if this isn’t there, you may have to load the "Multimedia" programs from your original Windows CD-ROM using the Control Panel’s "Add/Remove Software" applet). Under File-Open, find your AVI file and open it. Give it a run. Look good still? Now you’re set. Oh, don’t be worried if Media Player gets the aspect ratio of your AVI frames incorrect…this won’t affect your animated control in the least. Simply "resize" the window accordingly and "play" the file again.

Now that we have an AVI file, we can begin using an animated control. Well, except for a few more details. Always details. But for now, we’ve run out of time and space, so the details will have to wait. I have generated a demonstration program for you to download, so be sure to take a look at that (see top of page). In the next issue, I’ll analyze the demo code. By the way, I built the project using Visual C++ 5.0, so if you’re using an earlier version, you’ll need to rebuild the project file (build a blank project and "insert" the ".cpp" and ".rc" files). Unless you’re good, I wouldn’t worry too much about that, though. You have a lot of work to do just to get your animation sequence looking great! So keep reading! And good luck, all of you budding artists!

Creating and Using Animation Controls in Windows 95 and NT 4.0

Part II, Creating the Animated Control

Last issue we discussed building an AVI file which we could use as the basis of a Windows animated control. You DO have your AVI files ready, right? Pull out your best one, or use the file I provided with the demonstration code (top of page) and let’s see what goes into an animated control.

First, let me show you a very useful trick. Probably the last thing a professional developer would want to do is distribute their application with a bunch of ancillary files, such as icon files, sound files, and yes, AVI files. Users lose them, play with them, and generally wreak havoc. That’s why so many "things" are stored as "resources", like your main application icon. What we want to do is find a way to incorporate our nifty AVI file into our resource file. But AVI files aren’t part of the "standard" resource types! What do we do?

Well, it’s a secret, and though it’s not too difficult, it’s powerful. This will work for any binary "thing" you might like to keep with your application as a resource, which in this case is our AVI file. Under Insert-Resource, we want to select "Import" from the resulting dialog box and select our AVI file as the "thing" to import. Visual C++ will know this "thing" isn’t a standard resource, so it’ll bring up a new dialog box asking you what you want to call this "thing". I would type in "AVI", but you can call it anything you like. Visual C++ will then assign a resource identifier, which will default to "IDC_AVI1" for your first AVI resource. Feel free to change this identifier using View-Properties. While you’re there, however, there are a couple of things you may want to adjust. Click the "Styles" tab and let’s change a few settings. First, turn off the border (uncheck the border option). Then, select both "Transparent" and "Auto-Play" (check them both).

At this point, we need to decide where to place our control. So, assuming you have a project open and a new dialog box ready for editing in the dialog editor, go to the controls palette and select the "Animate" control button (it looks like a film strip). In the usual way, place this control onto your dialog box. The size of the control here in the editor won’t matter, as the size of the AVI file frames will dictate how large the control appears on the screen. However, the upper left-hand corner of the AVI file frames will be aligned with the upper left-hand corner of the control you lay our in the editor, so make sure the corner is set where you want it. Under the "Properties" dialog for this new control, give it a control identifier (such asIDC_ANIMCTRL or something). For my demonstration, I also added a command button to the dialog box to start and stop the animated control.

Now that we have the control inserted into a dialog box, we’ll fire up ClassWizard to add a Member Variable for our control. Go ahead and add the member variable in the usual way—select the control identifier you gave the animated control and press the "Add variable…" button. In the dialog box, type in an appropriate variable name, like m_CAnimCtrl or something similar. The variable will be selected as CAnimateCtrl-type (which you can’t change). Press "OK" twice to return to editing your code.

In the dialog box’s source code file, we need to edit its OnInitDialog() function to load the AVI resource into the MFC CAnimateCtrl-class variable we just created. Assuming you named the variable "m_CAnimCtrl" and the AVI’s resource ID was "IDR_AVI1", insert this code:

m_CAnimCtrl.Open(IDR_AVI1);

That’s all there is to it! Your animation control will start up and begin its animation sequence when you display the dialog box.

I wanted to demonstrate a bit more, so I added a command button to my dialog to start and stop the animation. In my OnInitDialog() function, I also added this line:

m_bIsActive = TRUE;

This boolean variable will keep track of our "state" (on or off). By the way, it begins life as TRUE because we selected "Auto-Play" in the dialog editor when we placed the control. In the ClassWizard, I added a message map for the button, OnStart(), which I edited like so:

void CMyDlg::OnStart()
{
	// Toggle active state. Ifwe're going active, we'll
	// start the animatedcontrol and modify the button's
	// text.
	m_bIsActive = !m_bIsActive;
	if ( m_bIsActive ) {
		// Start the control
		m_CAnimCtrl.Play(0,-1,-1);

		// Modify the button's text
		m_CStart.SetWindowText("&Stop Animation");
	} // if
	else {
		// Stop the control
		m_CAnimCtrl.Stop();
		m_CAnimCtrl.Seek(0);

		// Modify the button's text.
		m_CStart.SetWindowText("&Start Animation");
	} // else
}

Here you can see a bit more regarding animated control operations, in that I start it, stop it, and when it stops, I place it at a known frame (the first frame, in this case). The parameters for Stop() and Seek() are pretty obvious, but the ones for Play() need some explanation. Essentially, we’re saying "play from frame 0 through the last frame, looping forever". I also change the button’s text to correspond with the action the button will take when next pressed.

You may chuckle at the AVI file I’ve created. Yeah, it’s pretty funny looking—a twirling lamp. But I use this control for error conditions, as it really gets your attention. It’s certainly more interesting than the default ‘!’ or ‘?’ (MB_ICONINFORMATION or MB_ICONQUESTION message box icon styles), though you do need to create your own message box class rather than use AfxMessageBox(). This is more fun, anyway.

Well, there you have it. The animated controls themselves are the easy part, if you undertook the challenge of creating your own AVI file frame by frame. They’re super controls to use when you need to provide some visual feedback to your application’s user, such as for attention-grabbing, or for a visual cue indicating some operation you’re performing will take some time (see the top of page to download a demo). So knowing all of this, how would you add a control to your application which simulated the control you see in the upper right-hand corner of your favorite Web browser? How/when would you start/stop it? Happy coding and good luck!

Comments? Questions? Find a bug? Please send me a note!

[Back] [Left Arrow]   [Right Arrow] [Home]