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.
|
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)
Ill 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. Im 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. Weve 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. Thats an animated
control.
It isnt that the control is so hard to understand.
Its really very easy to use, and the MFC class CAnimateCtrl does a great job
encapsulating this simplicity. "Open". "Play". "Stop". It
doesnt 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, dont have any such capability, and most
video editing software Ive heard of doesnt really support what we want to do,
which is draw pictures ourselves instead of capturing them from video. Ive heard
there are some packages out there which work with AVI files, such as
"CorelDraw!", but I cant 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 issues
demonstration program). Using VidEdit, lets create an AVI file (this issue) and see
how we might take that and actually generate an animated control (next issue). Ill
first give you all of the steps, then Ill 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 youve 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. Lets now go step by step and talk some bits and
bytes. Creating frames is an artistic endeavor, so if youre artistic, great! If not,
you still need to create the animation sequence, and there isnt much anyone who
isnt 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 youre successful in creating a good animation
sequence, though, it will be worth the pain later! They really look great.
So lets 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
wont yet apply to us (open AVIs, movies, etc.). We want to open our first
frames bitmap file, which for the sake of argument weve named
"frame0.bmp". VidEdit will look at the bitmap file and know it isnt 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. Dont like it? Modify the offending frames and reload the
entire sequence into VidEdit. Like it, except for the strange flicker at the end?
Youll 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 VidEdits "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 were ready to build an AVI file.
Under File-Save As
, type in a filename. Youll
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, lets 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 isnt
there, you may have to load the "Multimedia" programs from your original Windows
CD-ROM using the Control Panels "Add/Remove Software" applet). Under
File-Open, find your AVI file and open it. Give it a run. Look good still? Now youre
set. Oh, dont be worried if Media Player gets the aspect ratio of your AVI frames
incorrect
this wont 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,
weve 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, Ill analyze the demo code. By the
way, I built the project using Visual C++ 5.0, so if youre using an earlier version,
youll need to rebuild the project file (build a blank project and "insert"
the ".cpp" and ".rc" files). Unless youre good, I wouldnt
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 lets 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. Thats 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 arent part of the "standard" resource types! What do we do?
Well, its a secret, and though its not too
difficult, its 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" isnt a standard resource, so itll 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 youre there, however, there are a couple of
things you may want to adjust. Click the "Styles" tab and lets 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 wont 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,
well fire up ClassWizard to add a Member Variable for our control. Go ahead and add
the member variable in the usual wayselect 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 cant change). Press "OK" twice to return to
editing your code.
In the dialog boxs 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 AVIs
resource ID was "IDR_AVI1", insert this code:
m_CAnimCtrl.Open(IDR_AVI1);
Thats 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, were saying "play from frame 0 through the
last frame, looping forever". I also change the buttons text to correspond with
the action the button will take when next pressed.
You may chuckle at the AVI file Ive created. Yeah,
its pretty funny lookinga twirling lamp. But I use this control for error
conditions, as it really gets your attention. Its 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. Theyre super controls to use when you need to provide some visual feedback to
your applications user, such as for attention-grabbing, or for a visual cue
indicating some operation youre 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!