Playing a Movie File

Once you open a movie file, you can use the MCI_PLAY command message to begin playing a movie. If the stage window is hidden or overlapped, the MCI Movie Driver displays the stage window before starting the playback.

The MCI Movie Driver handles all tasks associated with the playback, including starting the animation, updating the window, and advancing the frames. Using the flags for the MCI_PLAY command, you can play the movie reverse or forward and specify a starting and/or ending frame for the playback.

If an application sends an MCI_PLAY command message while the movie is already playing, one or both of the following might occur:

If the new playback request specifies a starting or stopping frame number, or if it specifies a different playback direction, the MCI Movie Driver stops playback and then restarts playback using the parameters specified by the new request.

If the new playback request specifies the MCI_NOTIFY flag, and notifi-cation is pending on the previous playback request, the new notification request supersedes the previous one. The MCI Movie Driver posts an MCI_NOTIFY_SUPERSEDED or an MCI_NOTIFY_ABORTED message to the notification function specified by the previous playback request.

Summary: Reverse Playback

To play a movie in reverse, you can use one of the following techniques:

Specify an ending frame number less than the starting frame number. The MCI Movie Driver plays the movie in reverse, from the starting frame number to the ending frame number.

Specify the MCI_REVERSE flag with the MCI_PLAY command. The MCI Movie Driver plays the movie in reverse from the current position (or the specified starting position) through the first frame in the movie. You can't specify an ending frame with the MCI_REVERSE flag.

Summary: MCI_PLAY Parameter Block

For animation devices, the MCI_PLAY command requires either the MCI_PLAY_PARMS or MCI_ANIM_PLAY_PARMS parameter blocks. The MCI_ANIM_PLAY_PARMS block is defined as follows:

typedef struct {
        DWORD   dwCallback;         // Callback for MCI_NOTIFY flag
        DWORD   dwFrom;             // Optional starting position
        DWORD   dwTo;               // Optional ending position
        DWORD   dwFPS;              // Not used with the MCI Movie Driver
} MCI_ANIM_PLAY_PARMS;

Since the MCI Movie Driver cannot use the frames-per-second setting, you can use the MCI_PLAY_PARMS parameter block when playing movie files. Playback begins at the current frame or the frame specified in the dwFrom field. Playback continues through the last frame or through the frame specified in the dwTo field (or, in the case of the MCI_REVERSE flag, through the first frame in the movie). You must specify the MCI_FROM and/or MCI_TO flags to notify the MCI Movie Driver that there are values in the dwFrom and dwTo fields.

Playing a Movie File

This section discusses one possible use of the MCI_PLAY and MCI_STOP commands. For example, if an application responds to a WM_COMMAND message by sending the MCI_PLAY or MCI_STOP commands to the MCI Movie Driver. The application uses the MCI_NOTIFY flag with the MCI_PLAY command, so the MCI Movie Driver notifies the window function when playback is finished. The application uses a global variable to identify the last operation that requested notification.

The following code fragment shows the IDM_STARTSTOP block of the main message handler for such an application:

long FAR PASCAL MainWndProc(HWND hWnd, unsigned iMessage, WORD wParam,
        LONG lParam)
{
    MCI_ANIM_PLAY_PARMS   mciPlay;
        .
        .                                                                                        // Other message cases
        .


        case WM_COMMAND :
            switch(wParam)
            {
                case IDM_STARTSTOP :
                    if(bRunning = !bRunning)
                    {
                        // Create window if in full-screen mode 
                        if(bFull)
                            CreateStage(hWnd);

                        // Record source of last notify request
                        wNotify = IDM_STARTSTOP;

                        mciPlay.dwCallback = hWnd;
                        dwError = mciSendCommand(wDeviceID, MCI_PLAY, 
                                                MCI_NOTIFY, (DWORD)(LPVOID)&mciPlay);
                        if(dwError)
                            showError(dwError);
                    }
                    else
                    {
                        dwError = mciSendCommand(wDeviceID, MCI_STOP, 0,
                                                    NULL);
                        if(dwError)
                            showError(dwError);
                    }
                    ChangeMenuItem(hWnd, bRunning, IDM_STARTSTOP,
                                   "&Stop animating", "&Start animating");
                    break;

Using the Notification Message

The MCI Movie Driver sends the MM_MCINOTIFY message to the window function when it finishes an operation that was started with the MCI_NOTIFY flag. In the following code fragment, an application responds to the notification message by setting some global variables and, if the movie is being played on a full-screen window, destroying the stage window:

case MM_MCINOTIFY:
    switch(wNotify)             // Global variable identifies the source
    {                           // of the notification request.
        case IDM_STARTSTOP:
            bRunning = FALSE;
            if(bFull)           // If playing on a full-screen window.
            {
                                MessageBeep(MB_ICONINFORMATION);
                MessageBox(hWnd, "The movie's over!", szAppName,
                                                                MB_OK | MB_ICONINFORMATION);

                // Note: In the WM_DESTROY case of the full-screen window
                // function, the application switches playback to the
                // default window.

                DestroyWindow(hWndFull);
            }
            ChangeMenuItem(hWnd, bRunning, IDM_STARTSTOP,
                            "&Stop animating", "&Start animating");
            break;

        default:
            break;
    }
    wNotify = NULL;
    return 0L;