Nigel Thompson
Microsoft Developer Network Technology Group
Created: March 20, 1992
ABSTRACT
This article reviews considerations for creating multimedia-dependent and multimedia-aware applications in the MicrosoftÒ WindowsÔ graphical environment. If your application is dedicated to the multimedia personal computer (MPC) environment, you will find useful information in the “Coping with Resource Availability” and “Yielding Resources to Other Applications” sections. If you are writing an application for Windows version 3.1 or for the Win32Ô Application Programming Interface, this article points out some potential hazards.
Multimedia applications fall loosely into two classes: applications that are completely dependent on the multimedia extensions and applications that use the extensions if they are available.
Some applications make sense only in a multimedia environment. For example, a speak-and-spell tutor requires support for playing sounds. The application will not run on a computer that has no multimedia support. Attempting to run the application under the MicrosoftÒ WindowsÔ version 3.0 graphical environment results in a dialog box that tells the user that Windows can’t find MMSYSTEM.DLL. This isn’t a friendly way to inform the user that we can’t run an application, but it’s the best we can do if the application is linked with MMSYSTEM.LIB during creation. It would be preferable to inform users that they need the multimedia extensions to use the application. Unfortunately, we can’t go back in time and make Windows “multimedia aware.” The best we can do is create applications that either fail gracefully or have reduced functionality if a feature they require is unavailable.
Instead of linking an application directly with MMSYSTEM.DLL, you can link it with an intermediate library that determines whether a particular function exists in the system and, if so, links to it at run time. If the function is not present, a default action can take place. For example, the intermediate library may return an error code to inform the application that the function failed. Alternatively, it may contain code to emulate the required function.
Applications can be sensitive to the presence of the extensions or to individual components. For example, an application that displays text and uses animations, waveform, the musical instrument digital interface (MIDI), and CD audio sounds in various places seems doomed without multimedia support. Let’s assume that the application is an encyclopedia that displays text occasionally augmented by multimedia inserts. This application can provide most of its functionality on a regular Windows version 3.0 platform because it requires support for only the standard Windows user and graphics device interface (GDI) libraries to display its text.
To create a version of this application that runs under both standard Windows and Windows with Multimedia Extensions, we must check whether the multimedia extensions exist and whether support is available for the data types we want to use. Is the CD audio device available? Can the wave device handle the format we want?
In the simplest case, we can detect the presence of the multimedia extensions at run time and disable all multimedia features if the extensions are not found. However, we cannot assume that all the devices we want to use are present, even if the extensions exist. Another application may currently be using the features we need.
The ideal solution is to use a device or a feature only when it’s needed and to close it when it’s no longer required. If the resource is not available, the application should either continue without it (for example, disable the button that plays sound) or ask the user to release the device or feature from another application.
Unfortunately, this solution results in significant timing delays because the application uses the media control interface (MCI) to open a device. Loading and initializing the dynamic link library (DLL) of the MCI device handler takes time, which is often unacceptable in the application.
A good compromise is to open the device before it’s required and release it when someone else needs it or when the application is terminated. Your application will know whether the device is available well before it needs to use it, thus avoiding the delays associated with loading code. To do this well, your application must process any WM_ACTIVATEAPP messages it receives. If it receives WM_ACTIVATEAPP with a wParam value of 0, the application is no longer active and should close any devices it has open. A subsequent WM_ACTIVATEAPP message with a nonzero wParam value indicates that the application is active once again and should attempt to reopen any devices it needs.
The application can determine the availability of the multimedia features it uses and selectively disable the parts that are not going to work. Optionally, the application can also notify the user of this reduced functionality.
To create a tolerant application in this environment, you must check the error return code from each attempt to open a device. Your application will thus avoid failing when the system configuration changes. You can inform the user either directly (through a dialog box) or indirectly (by disabling a button) that a feature has been lost.
Applications that hold devices open for long periods should process the WM_ACTIVATEAPP messages sent to them so that other applications can use multimedia facilities. For example, consider a game that allows the user to speak a part by recording his or her own voice. During the game, the user may decide to bring up Sound Recorder to alter a sound file recorded previously. If the game does not yield the wave output device, the Sound Recorder will not function as the user expects.
As a rule, applications shouldn’t play animations or sounds while they are inactive. An application like Music Box that plays audio CDs is an exception because it is unreasonable to stop playing the CD simply because the user wants to run another application. If your application needs to use a CD that is unavailable because another application has it open, you must tell the user about it.
Windows version 3.1 supports many of the multimedia extensions. The Win32Ô Application Programming Interface also supports some of the extensions. However, the existence of MMSYSTEM.DLL (or the support library in Win32) does not guarantee the existence of the appropriate device drivers. For example, the system may be installed on a computer with no sound card. In fact, the computer may have no multimedia features at all.
To survive in this new world, your application must either fail gracefully with a message at startup or tolerate the unavailability of multimedia support at run time.
You should also consider the role of your setup or installation program in this process. If your setup program cannot find multimedia support and consequently disables your application’s features, you should provide a mechanism to enable these features if the user adds multimedia support (for example, a sound card) at a later time. This may involve rerunning the setup program or, preferably, putting a detection mechanism into the startup code for the application. The application need not worry about which sound driver to add; it must simply recognize that those application programming interfaces (APIs) are now supported. This is easy to detect at run time.
At some point, the system may have the facility to load and unload drivers on demand. This mechanism can be used to implement an installable filter such as a 16-bit to 8-bit wave converter. This adds another level of complication because it means that the number of available drivers during the run time of your application may vary. It is not sufficient to simply enumerate them at application startup if you want to use every available driver.