By: Kenn Scribner for TechTalk
| I had planned to provide only the VidEdit program file and
its associated help file, but that won't be possible due to dynamic link library
dependencies. Therefore, I have for you the Video for Windows support, of which VidEdit is
a part. I do not honestly know if I may disribute this, and if I find I cannot, I will
have to remove it from this page and try to find for you another alternative. As it is,
you're faced with a 3MB download, but it's the only way to get all of the files you need
installed properly. My apologies the "easy way" didn't work out! I also received this note from Reader Mark Durham...this may well be worth a try! Thanks, Mark! Dear Mr. Scribner,
Copyright Note: Also, in this article I made a comment about "swiping" artwork. I *really* didn't mean steal, I meant re-use artwork you already had, or artwork in the public domain you would be legally authorized to use. Reader Mark Stewart (mark.c.stewart@eds.com) correctly pointed this out, and I apologize if this caused any confusion. Please check with the artist before using their artwork! |
|---|
| Run the demo program (all demos require Visual C++ 5.0!) | |
| Download the demo source | |
| Download VidEdit (a whopping 3,231,706 bytes) |
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 as IDC_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!
Comments? Questions? Find a bug? Please send me a note! |