home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cset21v6.zip / MMPM2TK / TK / SMVSAMP / MOVIE.C < prev    next >
C/C++ Source or Header  |  1993-04-29  |  63KB  |  1,604 lines

  1. /*************************************************************************
  2.  * File Name    :  movie.c
  3.  *
  4.  * Description  :  This file contains the C source code required for the
  5.  *                 movie sample program.
  6.  *
  7.  * Concepts     :  The sample program illustrates how an application
  8.  *                 can play a movie in a independent manner.
  9.  *
  10.  *                 This sample application will demonstrate device control
  11.  *                 of a Software Motion Video device, playing a movie
  12.  *                 in an application specified window and in a window
  13.  *                 provided by the Softare Motion Video subsystem.
  14.  *
  15.  * MMPM/2 API's :  List of all MMPM/2 API's that are used in
  16.  *                 this module
  17.  *
  18.  *                 mciSendCommand    MCI_OPEN
  19.  *                                   MCI_PLAY
  20.  *                                   MCI_PAUSE
  21.  *                                   MCI_RESUME
  22.  *                                   MCI_CLOSE
  23.  *                                   MCI_SET
  24.  *                                   MCI_WINDOW
  25.  *                                   MCI_PUT
  26.  *                  mmioGetHeader
  27.  *                  mmioSet
  28.  *                  mmioOpen
  29.  *                  mmioClose
  30.  *
  31.  * Required
  32.  *    Files     :  movie.c        Source Code.
  33.  *                 movie.h        Include file.
  34.  *                 movie.dlg      Dialog definition.
  35.  *                 movie.rc       Resources.
  36.  *                 movie.mak      Make file.
  37.  *                 movie.def      Linker definition file.
  38.  *                 movie.ico      Program icon.
  39.  *
  40.  * Copyright (C) IBM 1993
  41.  *************************************************************************/
  42.  
  43. #define  INCL_WIN                   /* required to use Win APIs.           */
  44. #define  INCL_PM                    /* required to use PM APIs.            */
  45. #define  INCL_WINHELP               /* required to use IPF.                */
  46. #define  INCL_OS2MM                 /* required for MCI and MMIO headers   */
  47. #define  INCL_MMIOOS2               /* required for MMVIDEOHEADER          */
  48. #define  INCL_MMIO_CODEC            /* required for circular, secondary    */
  49. #define  INCL_SW                    /* required for circular, secondary    */
  50.                                     /* windows and graphic buttons         */
  51. #define  INCL_WINSTDFILE            /* required for open file dlg          */
  52. #define  INCL_WINSTDDLGS            /* required for open file dlg          */
  53.  
  54. #include <os2.h>
  55. #include <os2me.h>
  56. #include <stdio.h>
  57. #include <stdlib.h>
  58. #include <string.h>
  59.  
  60. #include <sw.h>
  61.  
  62. #include "movie.h"
  63.  
  64. enum DeviceStates {ST_STOPPED, ST_PLAYING, ST_PAUSED};
  65. /*
  66.  * Procedure/Function Prototypes
  67.  */
  68.  
  69. MRESULT EXPENTRY MainDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  70.  
  71. BOOL    DoesFileExist( PSZ pszFileName );
  72. VOID    Finalize( VOID );
  73. VOID    Initialize( VOID );
  74. VOID    InitializeHelp( VOID );
  75. USHORT  MessageBox( USHORT usMessageID, ULONG  ulStyle );
  76. BOOL    PlayTheAppFile( HWND hwnd );
  77. BOOL    PlayTheDefaultFile( HWND hwnd );
  78. BOOL    PlayTheMovie( HWND hwnd );
  79. VOID    SetMovieVolume( VOID );
  80. VOID    ShowMCIErrorMessage( ULONG ulError );
  81. VOID    StopTheDevice( VOID );
  82. VOID    ResumeTheMovie( VOID );
  83. VOID    PauseTheMovie( VOID );
  84. VOID    CloseTheDevice( VOID );
  85. BOOL    OpenTheDevice( HWND );
  86. BOOL    SendString( HWND hwnd, PCHAR pcMCIString, USHORT usUserParm );
  87. VOID    ResizeMovieWindow(HWND hwnd);
  88.  
  89. /*************** End of Procedure/Function Prototypes *************************/
  90.  
  91.   /*
  92.   * Global Variables.
  93.   */
  94. HAB    hab;
  95. HMQ    hmq;
  96. HWND   hwndFrame;                      /* Handle to the frame window.         */
  97. HWND   hwndClient;                     /* Handle to the client App window     */
  98. HWND   hwndAppFrame;                   /* Handle to the App frame window      */
  99. HWND   hwndHelpInstance;               /* Handle to Main Help window.         */
  100. HWND   hwndMainDialogBox;              /* Handle to the dialog window.        */
  101. HWND   hwndPlayPB;                     /* Handle to the play push button      */
  102. HWND   hwndApplication;                /* Handle to the Application RB        */
  103. HWND   hwndStandard;                   /* Handle to the Standard RB           */
  104. HWND   hwndVolumeSlider;               /* Handle to the Volume slider         */
  105. ULONG  ulMovieLength;                  /* Length of movie in mmtimeperframe   */
  106. ULONG  ulMovieWidth;                   /* Width of movie                      */
  107. ULONG  ulMovieHeight;                  /* Height of movie                     */
  108. SWP    swpAppFrame;
  109. HMMIO  hFile;                          /* handle to file                      */
  110.  
  111. enum   DeviceStates   eState = ST_STOPPED;      /* state of the device       */
  112.  
  113. SHORT  sVolumeLevel   = INIT_VOLUME;   /* desired volume level                */
  114. BOOL   fPassedDevice  = FALSE;         /* for MCI_ACQUIRE to play the file    */
  115. BOOL   fDeviceOpen    = FALSE;         /* indicate we've opened for first time*/
  116. BOOL   fDevicePlaying = FALSE;         /* indicate we've opened for first time*/
  117. CHAR   achMsgBoxTitle[MAXNAMEL];       /* Error message box title             */
  118.  
  119. CHAR   szReturn[CCHMAXPATH];           /* return value from mciSendString     */
  120. SHORT  sResizeWindow = 0;              /* flag set for resizing the widow     */
  121. HPOINTER  hptrWait, hptrArrow;  /* Pointer handles for use during long waits. */
  122.  
  123. /************************** End of Global Variables ***************************/
  124.  
  125. /******************************************************************************
  126.  * Name         : main
  127.  *
  128.  * Description  : This function calls the Initialize procedure to prepare
  129.  *                everything for the program's operation, enters the
  130.  *                message loop, then calls Finalize to shut everything down
  131.  *                when the program is terminated.
  132.  *
  133.  * Concepts     : None.
  134.  *
  135.  * MMPM/2 API's : None.
  136.  *
  137.  * Parameters   : argc - Number of parameters passed into the program.
  138.  *                argv - Command line parameters.
  139.  *
  140.  * Return       : TRUE is returned to the operating system.
  141.  *
  142.  ******************************************************************************/
  143. INT main( VOID )
  144. {
  145.    QMSG    qmsg;
  146.  
  147.    Initialize();
  148.  
  149.    while ( WinGetMsg( hab, (PQMSG) &qmsg, (HWND) NULL, 0, 0) )
  150.       WinDispatchMsg( hab, (PQMSG) &qmsg );
  151.  
  152.    Finalize();
  153.  
  154.    return( TRUE);
  155.  
  156. } /* End of main */
  157.  
  158. /******************************************************************************
  159.  * Name         : Initialize
  160.  *
  161.  * Description  : This function performs the necessary initializations and
  162.  *                setups that are required to show/run a secondary window
  163.  *                as a main window.  The message queue will be created, as will
  164.  *                the dialog box.
  165.  *
  166.  * Concepts     : None
  167.  *
  168.  * MMPM/2 API's : WinLoadSecondaryWindow
  169.  *
  170.  * Parameters   : None.
  171.  *
  172.  * Return       : None.
  173.  *
  174.  ******************************************************************************/
  175. VOID Initialize( VOID)
  176. {
  177.    CHAR     szDefaultSize[CCHMAXPATH];   /* buffer for default size menu text */
  178.    CHAR     achTitle[MAXNAMEL];          /* buffer for window title text      */
  179.    LONG     lmciSendStringRC;            /* return code from SendString       */
  180.  
  181.    hab       = WinInitialize( 0);
  182.    hmq       = WinCreateMsgQueue( hab, 0);
  183.  
  184.    hptrArrow = WinQuerySysPointer ( HWND_DESKTOP, SPTR_ARROW, FALSE );
  185.    hptrWait  = WinQuerySysPointer ( HWND_DESKTOP, SPTR_WAIT,  FALSE );
  186.  
  187.    /*****************************************************************/
  188.    /* Initialize the window. First, change pointer to a waiting     */
  189.    /* pointer, since this might take a couple of seconds.           */
  190.    /*****************************************************************/
  191.  
  192.    WinSetPointer ( HWND_DESKTOP, hptrWait );
  193.  
  194.    WinLoadString(
  195.       hab,                                  /* HAB for this window.           */
  196.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  197.       IDS_DEFAULTSIZE,                      /* Which string to get.           */
  198.       sizeof(szDefaultSize),                /* The size of the buffer.        */
  199.       szDefaultSize);                       /* The buffer to place the string.*/
  200.  
  201.    WinLoadString(
  202.       hab,                                  /* HAB for this dialog box.       */
  203.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  204.       IDS_MOVIE_ERROR,                      /* Which string to get.           */
  205.       (SHORT) sizeof( achMsgBoxTitle),      /* The size of the buffer.        */
  206.       achMsgBoxTitle);                      /* The buffer to place the string.*/
  207.  
  208.    hwndFrame =                    /* Returns the handle to the frame.         */
  209.        WinLoadSecondaryWindow(
  210.           HWND_DESKTOP,           /* Parent of the dialog box.                */
  211.           HWND_DESKTOP,           /* Owner of the dialog box.                 */
  212.           (PFNWP) MainDlgProc,    /* 'Window' procedure for the dialog box.   */
  213.           (HMODULE) NULL,         /* Where is the dialog.  Null is EXE file.  */
  214.           IDD_MAIN_WINDOW,        /* Dialog ID.                               */
  215.           (PVOID) NULL);          /* Creation Parameters for the dialog.      */
  216.  
  217.    /**************************************************************************/
  218.    /* Retrieve the handle to the dialog box by specifying the QS_DIALOG flag.*/
  219.    /**************************************************************************/
  220.  
  221.    hwndMainDialogBox = WinQuerySecondaryHWND(hwndFrame, QS_DIALOG);
  222.  
  223.    /**************************************************************************/
  224.    /* Add Default Size menu item to system menu of the secondary window.     */
  225.    /**************************************************************************/
  226.  
  227.    WinInsertDefaultSize(hwndFrame, szDefaultSize);
  228.  
  229.    /******************************************************************/
  230.    /* Get the window title string from the Resource string table     */
  231.    /* and set it as the window text for the dialog window.           */
  232.    /******************************************************************/
  233.    WinLoadString(
  234.       hab,                                  /* HAB for this dialog box.       */
  235.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  236.       IDS_PROGRAM_TITLE,                    /* Which string to get.           */
  237.       (SHORT) sizeof( achTitle),            /* The size of the buffer.        */
  238.       achTitle);                            /* The buffer to place the string.*/
  239.  
  240.    WinSetWindowText( hwndFrame, achTitle);
  241.  
  242.   /*************************************************************************/
  243.   /* This new window is created for playing a movie in a application       */
  244.   /* defined window.  When playing a movie in this window the Sendstring   */
  245.   /* function will be passed this windows handle in order to know where    */
  246.   /* to put the movie before playing.                                      */
  247.   /*************************************************************************/
  248.  
  249.     WinRegisterClass(
  250.       hab,
  251.     "MovieWindow",
  252.     (PFNWP) NULL,
  253.     CS_SIZEREDRAW | CS_MOVENOTIFY,
  254.     0 );
  255.  
  256.   hwndAppFrame =  WinCreateWindow((HWND)hwndMainDialogBox,
  257.                                  "MovieWindow",
  258.                                   NULL,
  259.                                   0,
  260.                                   0,
  261.                                   0,
  262.                                   0,
  263.                                   0,
  264.                                   (HWND)hwndMainDialogBox,
  265.                                   HWND_TOP, ID_APPWINDOW, NULL, NULL );
  266.  
  267.    WinShowWindow( hwndFrame, TRUE );           /* Display the main window.    */
  268.  
  269.    InitializeHelp();                           /* Initialize the help.        */
  270.  
  271.    /*
  272.     * Now that we're done here, change the pointer back to the arrow.
  273.     */
  274.    WinSetPointer ( HWND_DESKTOP, hptrArrow );
  275.  
  276. } /* end initialization */
  277.  
  278. /******************************************************************************
  279.  * Name         : Finalize
  280.  *
  281.  * Description  : This routine is called after the message dispatch loop
  282.  *                has ended because of a WM_QUIT message.  The code will
  283.  *                destroy the help instance, messages queue, and window.
  284.  *
  285.  * Concepts     : None.
  286.  *
  287.  * MMPM/2 API's : WinDestroySecondaryWindow
  288.  *
  289.  * Parameters   : None.
  290.  *
  291.  * Return       : None.
  292.  *
  293.  ******************************************************************************/
  294. VOID Finalize( VOID )
  295. {
  296.    /*
  297.     * Destroy the Help Instances.
  298.     */
  299.    if ( hwndHelpInstance != (HWND) NULL)
  300.    {
  301.       WinDestroyHelpInstance( hwndHelpInstance );
  302.    }
  303.  
  304.    WinDestroySecondaryWindow( hwndFrame );
  305.    WinDestroyMsgQueue( hmq );
  306.    WinTerminate( hab );
  307.  
  308. }  /* End of Finalize */
  309.  
  310. /******************************************************************************
  311.  * Name         : MainDlgProc
  312.  *
  313.  * Description  : This function controls the main dialog box.  It will handle
  314.  *                received messages such as pushbutton notifications, timing
  315.  *                events, etc.
  316.  *
  317.  * Concepts     : Illustrates:
  318.  *                  - How to participate in MMPM/2 device sharing scheme.
  319.  *                  - How to handle notification messages.
  320.  *                  - How to implement graphic pushbutton's
  321.  *                  - How to implement secondary windows.
  322.  *
  323.  * MMPM/2 API's : WinDefSecondaryWindowProc
  324.  *                mciSendString
  325.  *                   - acquire
  326.  *
  327.  * Parameters   : hwnd - Handle for the Main dialog box.
  328.  *                msg  - Message received by the dialog box.
  329.  *                mp1  - Parameter 1 for the just received message.
  330.  *                mp2  - Parameter 2 for the just received message.
  331.  *
  332.  * Return       : 0 or the result of default processing.
  333.  *
  334.  ******************************************************************************/
  335. MRESULT EXPENTRY MainDlgProc( HWND   hwnd,
  336.                               ULONG  msg,
  337.                               MPARAM mp1,
  338.                               MPARAM mp2 )
  339. {
  340.    LONG        lmciSendStringRC;      /* return value form mciSendString      */
  341.    HPOINTER    hpProgramIcon;         /* handle to program's icon             */
  342.    USHORT      usCommandMessage;      /* command message for notify           */
  343.    USHORT      usNotifyCode;          /* notification message code            */
  344.    SHORT       sWmControlID;          /* WM_CONTROL id                        */
  345.    ULONG       ulFrame;               /* video position in frames.            */
  346.    MRESULT     mresult;               /* return result                        */
  347.  
  348.    switch( msg )
  349.    {
  350.       case WM_INITDLG :
  351.          hpProgramIcon =
  352.             WinLoadPointer(
  353.                HWND_DESKTOP,
  354.                (HMODULE) NULL,              /* Resource is kept in .Exe file. */
  355.                ID_ICON );                   /* Which icon to use.             */
  356.  
  357.          WinDefSecondaryWindowProc(
  358.             hwnd,                    /* Dialog window handle.                 */
  359.             WM_SETICON,              /* Message to the dialog.  Set it's icon.*/
  360.             (MPARAM) hpProgramIcon,
  361.             (MPARAM) 0 );            /* mp2 no value.                         */
  362.  
  363.          /*
  364.           * get all the required handles.
  365.           */
  366.                                                          /* volume slider     */
  367.          hwndVolumeSlider = WinWindowFromID( hwnd, IDC_VOLUME_SLIDER );
  368.  
  369.                                                          /* play push button  */
  370.          hwndPlayPB      = WinWindowFromID( hwnd, IDC_GPB_PLAY );
  371.  
  372.                                                          /* application RB    */
  373.          hwndApplication = WinWindowFromID( hwnd, IDC_RADIO1 );
  374.  
  375.         if (!DoesFileExist( "movie.avi" ))
  376.           {
  377.              MessageBox( IDS_CANNOT_FIND_MOVIE_FILE,              /* ID of the message          */
  378.                          MB_CANCEL | MB_ERROR  | MB_MOVEABLE);    /* style         */
  379.  
  380.              WinEnableWindow( hwndPlayPB, FALSE );
  381.           }
  382.  
  383.  
  384.          /********************************************************************/
  385.          /* The slider control cannot be completely set from the dialog      */
  386.          /* template so some aspects must be set here.  We will set the      */
  387.          /* volume range to 0-100, increment to 1-10, and the initial        */
  388.          /* volume level to 100.                                             */
  389.          /********************************************************************/
  390.          WinSendMsg( hwndVolumeSlider,
  391.                      CSM_SETRANGE,
  392.                      (MPARAM) 0L,
  393.                      (MPARAM) 100L);
  394.  
  395.          WinSendMsg( hwndVolumeSlider,
  396.                      CSM_SETINCREMENT,
  397.                      (MPARAM) 10L,
  398.                      (MPARAM) 1L);
  399.  
  400.          WinSendMsg( hwndVolumeSlider,
  401.                      CSM_SETVALUE,
  402.                      (MPARAM) sVolumeLevel,
  403.                      (MPARAM) NULL);
  404.  
  405.          /*****************/
  406.          /* Volume Slider */
  407.          /*****************/
  408.  
  409.          WinEnableWindow( hwndVolumeSlider, TRUE );
  410.  
  411.          /**********************************************/
  412.          /* Set the application window as the default  */
  413.          /**********************************************/
  414.  
  415.          WinSendMsg(hwndApplication, BM_SETCHECK, MPFROMSHORT(1), NULL);
  416.  
  417.          return( (MRESULT) 0);
  418.  
  419.       case WM_CLOSE :
  420.  
  421.          /*********************************************/
  422.          /* If the device is opened, close the device  /
  423.          /*********************************************/
  424.  
  425.          if (fDeviceOpen)
  426.             CloseTheDevice();
  427.  
  428.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  429.  
  430.       case WM_HELP :
  431.  
  432.        /*********************************************************************/
  433.        /* The dialog window has received a request for help from the user.  */
  434.        /* Send the HM_DISPLAY_HELP message to the Help Instance with the IPF*/
  435.        /* resource identifier for the correct HM panel.  This will show the */
  436.        /* help panel for this sample program.                               */
  437.        /*********************************************************************/
  438.  
  439.          WinSendMsg( hwndHelpInstance,
  440.                      HM_DISPLAY_HELP,
  441.                      MPFROMSHORT(1),
  442.                      MPFROMSHORT(HM_RESOURCEID));
  443.          return( (MRESULT) 0);
  444.  
  445.  
  446.       /*************************************************************/
  447.       /* This message is recieved when the user changes the volume */
  448.       /* or the movie position slider.                             */
  449.       /*************************************************************/
  450.  
  451.       case WM_CONTROL:
  452.         sWmControlID  = SHORT1FROMMP(mp1);
  453.         usNotifyCode  = (USHORT) SHORT2FROMMP(mp1);
  454.  
  455.         switch ( sWmControlID )
  456.         {
  457.  
  458.            case IDC_VOLUME_SLIDER:
  459.               if ( ( usNotifyCode == CSN_CHANGED ) ||
  460.                    ( usNotifyCode == CSN_TRACKING ) )
  461.               {
  462.  
  463.                /**************************************************************/
  464.                /*  Every time the volume control setting is changed, save the*/
  465.                /*  new value in sVolumeLevel.                                */
  466.                /**************************************************************/
  467.  
  468.                  sVolumeLevel = SHORT1FROMMP (mp2);
  469.  
  470.                 /*****************************/
  471.                 /*  Set the new volume level */
  472.                 /*****************************/
  473.  
  474.                  SetMovieVolume();
  475.               }
  476.               break;
  477.         }
  478.  
  479.         return( (MRESULT) 0);
  480.  
  481.       case WM_COMMAND :
  482.  
  483.         /**********************************************************************/
  484.         /* To get which pushbutton was pressed the SHORT1FROMMP macro is used.*/
  485.         /**********************************************************************/
  486.  
  487.          switch (SHORT1FROMMP(mp1))
  488.          {
  489.             case IDC_GPB_PLAY:               /* user selected "Play"          */
  490.                switch ( eState )
  491.                {
  492.                   /**********************************************************/
  493.                   /* If the Movie is currently stopped, check to see if we  */
  494.                   /* were playing, if we were resume.                       */
  495.                   /**********************************************************/
  496.                   case ST_STOPPED:
  497.  
  498.                     /****************************************************/
  499.                     /* Open the moive, resize the window if needed for  */
  500.                     /* the movie, then start playing.                   */
  501.                     /****************************************************/
  502.                      if (!fDeviceOpen)
  503.                        {
  504.                          OpenTheDevice ( hwnd );
  505.                        } /* if */
  506.                      if(sResizeWindow == 0 )
  507.                        {
  508.                          ResizeMovieWindow(hwnd);
  509.                          sResizeWindow = 1;
  510.                        }
  511.                      PlayTheMovie( hwnd );
  512.                      break;
  513.  
  514.                   /******************************************************/
  515.                   /* If the Movie is currently paused, resume the Movie */
  516.                   /******************************************************/
  517.                   case ST_PAUSED:
  518.                      ResumeTheMovie();
  519.                      break;
  520.                }
  521.                break;
  522.  
  523.             case IDC_GPB_PAUSE:
  524.                switch ( eState )
  525.                {
  526.                  /************************************************/
  527.                  /* If the Movie is currently playing, pause it. */
  528.                  /************************************************/
  529.  
  530.                  case ST_PLAYING:
  531.                     PauseTheMovie();
  532.                     break;
  533.  
  534.                  /***********************************************************/
  535.                  /* If the Movie is currently paused, resume the Movie play.*/
  536.                  /***********************************************************/
  537.  
  538.                  case ST_PAUSED:
  539.                     ResumeTheMovie();
  540.                     break;
  541.                }
  542.               break;
  543.  
  544.             case IDC_GPB_REWIND:         /* user selected "Rewind" pushbutton */
  545.                if (fDeviceOpen)          /* If the device is opened           */
  546.                  {
  547.                   StopTheDevice();
  548.                   fDevicePlaying = FALSE;
  549.                  }
  550.                break;
  551.  
  552.             case IDC_GPB_STOP:             /* user selected "Stop" pushbutton */
  553.  
  554.                /***********************************************************/
  555.                /* If the Movie is not in stopped state, stop the device.  */
  556.                /***********************************************************/
  557.  
  558.                if (eState != ST_STOPPED)
  559.                  {
  560.                     StopTheDevice();
  561.                  }
  562.                break;
  563.  
  564.             default:
  565.                break;
  566.  
  567.          }  /* End of Command Switch */
  568.  
  569.          return( (MRESULT) 0);
  570.  
  571.       /**************************************************************
  572.        * The next two messages are handled so that this application can
  573.        * participate in device sharing.  Since it opens the device as
  574.        * shareable device, other applications can gain control of the device.
  575.        * When this happens, we will receive a MM_MCIPASSDEVICE message.  We
  576.        * keep track of this device passing in the fPassedDevice Boolean
  577.        * variable.
  578.        *
  579.        * We use the WM_ACTIVATE message to participate in device
  580.        * sharing.  We first check to see if this is an activate
  581.        * or a deactivate message (indicated by mp1).  Then,
  582.        * we check to see if we've passed control of the duets'
  583.        * devices.  If these conditions are true, then
  584.        * we issue an acquire device command to regain control of
  585.        * the device, since we're now the active window on the screen.
  586.        *
  587.        * This is one possible method that can be used to implement
  588.        * device sharing. For applications that are more complex
  589.        * than this sample program, developers may wish to take
  590.        * advantage of a more robust method of device sharing.
  591.        * This can be done by using the MCI_ACQUIRE_QUEUE flag on
  592.        * the MCI_ACQUIREDEVICE command.  Please refer to the MMPM/2
  593.        * documentation for more information on this flag.
  594.        **************************************************************/
  595.  
  596.       case MM_MCIPASSDEVICE:
  597.          if (SHORT1FROMMP(mp2) == MCI_GAINING_USE)           /* GAINING USE */
  598.            {
  599.              fPassedDevice = FALSE;             /* Gaining control of device.*/
  600.            }
  601.          else                                                /* LOSING USE  */
  602.            {
  603.              fPassedDevice = TRUE;              /* Losing  control of device.*/
  604.            }
  605.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  606.  
  607.       case WM_ACTIVATE:
  608.  
  609.          /*********************************************************************/
  610.          /* We use the WM_ACTIVATE message to participate in device sharing.  */
  611.          /* We first check to see if this is an activate or a deactivate      */
  612.          /* message (indicated by mp1).  Then, we check to see if we've passed*/
  613.          /* control of the Movie device.  If these conditions are true,       */
  614.          /* then we issue an acquire device command to regain control of      */
  615.          /* the device, since we're now the active window on the screen.      */
  616.          /*********************************************************************/
  617.          if ((BOOL)mp1 && fPassedDevice == TRUE)
  618.          {
  619.            /***********************************************************/
  620.            /* To acquire the device, we will issue MCI_ACQUIREDEVICE  */
  621.            /* command to the MCI.                                     */
  622.            /***********************************************************/
  623.  
  624.             SendString( hwnd, "acquire movie notify", 0 );
  625.          }
  626.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  627.  
  628.       case MM_MCINOTIFY:
  629.  
  630.        /***********************************************************************/
  631.        /* This message is returned to an application when a device            */
  632.        /* successfully completes a command that was issued with a NOTIFY      */
  633.        /* flag, or when an error occurs with the command.                     */
  634.        /*                                                                     */
  635.        /* This message returns two values. A user parameter (mp1) and         */
  636.        /* the command message (mp2) that was issued. The low word of mp1      */
  637.        /* is the Notification Message Code which indicates the status of the  */
  638.        /* command like success or failure. The high word of mp2 is the        */
  639.        /* Command Message which indicates the source of the command.          */
  640.        /***********************************************************************/
  641.  
  642.          usNotifyCode    = (USHORT) SHORT1FROMMP( mp1);  /* low-word  */
  643.          usCommandMessage = (USHORT) SHORT2FROMMP( mp2); /* high-word */
  644.  
  645.          switch (usCommandMessage)
  646.          {
  647.             case MCI_PLAY:
  648.                switch (usNotifyCode)
  649.                {
  650.                   case MCI_NOTIFY_SUPERSEDED:
  651.                   case MCI_NOTIFY_ABORTED:
  652.                      /* we don't need to handle these messages. */
  653.                      break;
  654.  
  655.                   /********************************************************/
  656.                   /* This case is used for either successful completion   */
  657.                   /* of a command or for and error.                       */
  658.                   /********************************************************/
  659.  
  660.                   default:
  661.                    if (eState != ST_STOPPED)
  662.                      {
  663.                         eState = ST_STOPPED;
  664.                         if ( usNotifyCode != MCI_NOTIFY_SUCCESSFUL)
  665.  
  666.                            /*************************************************/
  667.                            /* Notification error message. We need to display*/
  668.                            /* the error message to the user.                */
  669.                            /*************************************************/
  670.  
  671.                            ShowMCIErrorMessage( usNotifyCode);
  672.                         CloseTheDevice();
  673.                      }
  674.  
  675.                     break;
  676.                }
  677.                break;
  678.          }
  679.          return( (MRESULT) 0);
  680.  
  681.       default:
  682.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2));
  683.  
  684.    }  /* End of msg Switch */
  685.  
  686. } /* End of MainDlgProc */
  687.  
  688. /******************************************************************************
  689.  * Name         :  PlayTheAppFile
  690.  *
  691.  * Description  :  This procedure will Load a specific movie file into the
  692.  *                 Application defined video window.
  693.  *
  694.  * Concepts     :
  695.  *                 - Loading a file into an already open device.
  696.  *
  697.  * MMPM/2 API's :  mciSendString
  698.  *                    - load
  699.  *                    - put
  700.  *                    - window handle
  701.  *
  702.  * Parameters   :  hwnd  - Handle for the Main window.
  703.  *
  704.  * Return       :  TRUE  -  if the operation was initiated without error.
  705.  *                 FALSE -  if an error occurred.
  706.  *
  707.  ******************************************************************************/
  708. BOOL PlayTheAppFile( HWND hwnd )
  709. {
  710.    LONG    lmciSendStringRC;          /* return code from SendString         */
  711.  
  712.    CHAR    szHandle[10] = "";         /* string used for window handle       */
  713.    CHAR    szx[5]       = "";         /* string used for x position of window*/
  714.    CHAR    szy[5]       = "";         /* string used for y position of window*/
  715.    CHAR    szcx[5]      = "";        /* string used for cx position of window*/
  716.    CHAR    szcy[5]      = "";        /* string used for cy position of window*/
  717.  
  718.    /*******************************************************************/
  719.    /* The szWindowString and szPutString are used as a foundation     */
  720.    /* for building a string command to send to sendstring             */
  721.    /*******************************************************************/
  722.  
  723.    CHAR    szWindowString[CCHMAXPATH] =
  724.              "window movie handle ";      /* string command to mciSendString  */
  725.  
  726.    CHAR    szPutString[CCHMAXPATH] =
  727.             "put movie destination at ";  /* string command to mciSendString */
  728.  
  729.    /**********************************************************************/
  730.    /* Change pointer to a waiting pointer first, since this might take a */
  731.    /* couple of seconds.                                                 */
  732.    /**********************************************************************/
  733.  
  734.    WinSetPointer( HWND_DESKTOP, hptrWait );
  735.  
  736.    /******************************************************/
  737.    /* Convert the Frame window handle to a string so    */
  738.    /* we can use the mciSendStringCommand.               */
  739.    /******************************************************/
  740.  
  741.    hwndAppFrame    = WinWindowFromID( hwnd, ID_APPWINDOW );
  742.  
  743.    _ultoa(hwndAppFrame,szHandle,10);
  744.  
  745.    strcat (szWindowString, szHandle);  /* concatenate the converted handle to*/
  746.    strcat (szWindowString, " ");     /* the window string so we can issue the*/
  747.    strcat (szWindowString, "wait");  /* send string command                  */
  748.  
  749.    lmciSendStringRC = SendString(hwnd, szWindowString, 0);
  750.  
  751.    /* Load the movie */
  752.  
  753.    if (!(lmciSendStringRC = SendString(hwnd, "load movie movie.avi wait", 0)))
  754.      {
  755.        ShowMCIErrorMessage(lmciSendStringRC);
  756.        return( FALSE );
  757.      }
  758.  
  759.  
  760.    /******************************************************/
  761.    /* Convert the Frame windows sizes to strings so      */
  762.    /* we can use the mciSendStringCommand to put the     */
  763.    /* video in our application Frame window.             */
  764.    /******************************************************/
  765.  
  766.      WinQueryWindowPos (hwndAppFrame, &swpAppFrame);
  767.  
  768.        swpAppFrame.x = 0;
  769.        swpAppFrame.y = 0;
  770.  
  771.      /**********************************************************/
  772.      /* convert the application windows coordinates to strings */
  773.      /* so we can issue the the sendstring command             */
  774.      /**********************************************************/
  775.      _ultoa(swpAppFrame.x,szx,10);
  776.      _ultoa(swpAppFrame.y,szy,10);
  777.      _ultoa(swpAppFrame.cx,szcx,10);
  778.      _ultoa(swpAppFrame.cy,szcy,10);
  779.  
  780.      /**********************************************************/
  781.      /* concatenate the converted strings to the the put string*/
  782.      /* so we can issue the the sendstring command             */
  783.      /*                                                        */
  784.      /* The following restrictions on PUT DESTINATION exist in */
  785.      /* OS/2 2.1: The x and y values of the destination must be*/
  786.      /* zero, although the cx and cy values may be any value   */
  787.      /* up to the width and height of the window. Also,        */
  788.      /* PUT DESTINATION will have no effect if executed before */
  789.      /* playing starts.                                        */
  790.      /**********************************************************/
  791.  
  792.      strcat (szPutString, szx);
  793.      strcat (szPutString, " ");
  794.      strcat (szPutString, szy);
  795.      strcat (szPutString, " ");
  796.      strcat (szPutString, szcx);
  797.      strcat (szPutString, " ");
  798.      strcat (szPutString, szcy);
  799.      strcat (szPutString, " ");
  800.      strcat (szPutString, "wait");
  801.  
  802.      lmciSendStringRC = SendString( hwnd, szPutString, 0 );
  803.  
  804.    /**********************************************/
  805.    /* Check to see if the digital video can play */
  806.    /* If it cannot play disable the play button  */
  807.    /* Display a message error loading video      */
  808.    /**********************************************/
  809.  
  810.    fDevicePlaying = TRUE;
  811.  
  812.    if (!SendString( hwnd,
  813.                    "capability movie can play wait",
  814.                     0 ))
  815.      {
  816.  
  817.       WinEnableWindow( hwndPlayPB, FALSE );
  818.  
  819.       return( FALSE );
  820.      }
  821.  
  822.    /******************************************************************/
  823.    /* Now that we're done here, change the pointer back to the arrow.*/
  824.    /******************************************************************/
  825.    WinSetPointer ( HWND_DESKTOP, hptrArrow );
  826.  
  827.    return( TRUE );
  828.  
  829. }  /* end of PlayTheAppFile */
  830.  
  831. /******************************************************************************
  832.  * Name         :  PlayTheDefaultFile
  833.  *
  834.  * Description  :  This procedure will load a specific movie file into
  835.  *                 the applications default video window.  Default video
  836.  *                 window will appear in the lower left origin of the screen.
  837.  *
  838.  *
  839.  * Concepts     :
  840.  *                 - Loading a file into an already open device.
  841.  *
  842.  * MMPM/2 API's :  mciSendString
  843.  *                    - load
  844.  *
  845.  * Parameters   :  hwnd  - Handle for the Main dialog box.
  846.  *
  847.  * Return       :  TRUE  -  if the operation was initiated without error.
  848.  *                 FALSE -  if an error occurred.
  849.  *
  850.  ******************************************************************************/
  851. BOOL PlayTheDefaultFile( HWND hwnd )
  852. {
  853.    LONG    lmciSendStringRC;            /* return code from SendString       */
  854.  
  855.  
  856.    /**********************************************************************/
  857.    /* Change pointer to a waiting pointer first, since this might take a */
  858.    /* couple of seconds.                                                 */
  859.    /**********************************************************************/
  860.  
  861.    WinSetPointer( HWND_DESKTOP, hptrWait );
  862.  
  863.    if (!(lmciSendStringRC = SendString(hwnd, "load movie movie.avi wait", 0)))
  864.      {
  865.        ShowMCIErrorMessage(lmciSendStringRC);
  866.        return( FALSE );
  867.      }
  868.  
  869.    fDevicePlaying = TRUE;
  870.  
  871.    /**********************************************/
  872.    /* Check to see if the digital video can play */
  873.    /* If it cannot play disable the play button  */
  874.    /* Display a message error loading video      */
  875.    /**********************************************/
  876.  
  877.    if (!SendString( hwnd,
  878.                    "capability movie can play wait",
  879.                     0 ))
  880.      {
  881.  
  882.       WinEnableWindow( hwndPlayPB, FALSE );
  883.  
  884.       return( FALSE );
  885.      }
  886.  
  887.    /******************************************************************/
  888.    /* Now that we're done here, change the pointer back to the arrow.*/
  889.    /******************************************************************/
  890.    WinSetPointer ( HWND_DESKTOP, hptrArrow );
  891.  
  892.    return( TRUE );
  893.  
  894. }  /* end of PlayTheDefaultFile */
  895.  
  896. /*************************************************************************
  897.  * Name         :  PlayTheMovie
  898.  *
  899.  * Description  :  This procedure will begin the playing of an Movie file.
  900.  *                 It is invoked when the user selects the Play pushbutton
  901.  *                 on the application's main window.  The movie will be
  902.  *                 played in either a application defined window or in a
  903.  *                 default window depending on the state of the radio buttons.
  904.  *
  905.  *
  906.  * Concepts     :  Playing a Movie file using the MCI interface.
  907.  *
  908.  * MMPM/2 API's :  mciSendString
  909.  *                    - play
  910.  *
  911.  * Parameters   :  hwnd - Handle for the Main dialog box.
  912.  *
  913.  * Return       :  TRUE  -  if the operation was initiated without error.
  914.  *                 FALSE -  if an error occurred.
  915.  *
  916.  ******************************************************************************/
  917. BOOL PlayTheMovie( HWND hwnd)
  918. {
  919.  
  920.    /*******************************************/
  921.    /* Check to see which window we want to    */
  922.    /* play the movie in.                      */
  923.    /*******************************************/
  924.  
  925.   if (fDevicePlaying == FALSE)
  926.     {
  927.        if (WinSendMsg(hwndApplication, BM_QUERYCHECK, NULL,NULL ))
  928.          {
  929.  
  930.            if (!PlayTheAppFile(hwnd))
  931.              {
  932.                return (FALSE);
  933.              }
  934.  
  935.          } /* if */
  936.        else
  937.          {
  938.            if (!PlayTheDefaultFile(hwnd))
  939.              {
  940.                return( FALSE );
  941.              } /* if */
  942.          }
  943.     } /* if */
  944.  
  945.    eState = ST_PLAYING;                      /* set state to PLAYING          */
  946.  
  947.    SetMovieVolume();                        /* set the starting volume       */
  948.  
  949.    /**************************************************************************/
  950.    /* To play the Movie, we will issue an MCI_PLAY command via mciSendString.*/
  951.    /* A MM_MCINOTIFY message will be sent to the window specified in         */
  952.    /* SendString when the operation is completed.                            */
  953.    /**************************************************************************/
  954.    SendString( hwnd,"play movie notify", 0 );
  955.  
  956.    return( TRUE );
  957.  
  958. }  /* end of PlayTheMovie */
  959.  
  960. /*************************************************************************
  961.  * Name         :  ResumeTheMovie
  962.  *
  963.  * Description  :  This procedure will resume the playing of the Movie
  964.  *                 has been paused.
  965.  *
  966.  * Concepts     :  Resuming the Movie using MCI interface.
  967.  *
  968.  * MMPM/2 API's :  mciSendString
  969.  *                    - resume
  970.  *
  971.  * Parameters   :  none.
  972.  *
  973.  * Return       :  none.
  974.  *
  975.  *************************************************************************/
  976. VOID ResumeTheMovie( VOID )
  977. {
  978.  
  979.    /*******************************************************************/
  980.    /* To resume the Movie, we will issue an MCI_RESUME command via    */
  981.    /* MciSendString.                                                  */
  982.    /*******************************************************************/
  983.    if (SendString( (HWND)NULL, "resume movie wait", 0 ) )
  984.      {
  985.        eState = ST_PLAYING;
  986.        SetMovieVolume();
  987.      }
  988.  
  989.    return;
  990. }  /* End of ResumeTheMovie */
  991.  
  992. /******************************************************************************
  993.  * Name         :  PauseTheMovie
  994.  *
  995.  * Description  :  This procedure will pause Movie that is playing.
  996.  *
  997.  * Concepts     :  Pausing the Movie using MCI interface.
  998.  *
  999.  * MMPM/2 API's :  mciSendString
  1000.  *                    - pause
  1001.  *
  1002.  * Parameters   :  none.
  1003.  *
  1004.  * Return       :  none.
  1005.  *
  1006.  ******************************************************************************/
  1007. VOID PauseTheMovie( VOID )
  1008. {
  1009.  
  1010.    /*******************************************************************/
  1011.    /* To pause the Movie, we will issue an MCI_PAUSE command via      */
  1012.    /* MciSendString.                                                  */
  1013.    /*******************************************************************/
  1014.  
  1015.    if ( SendString( (HWND)NULL, "pause movie wait", 0 ) )
  1016.     {
  1017.        eState = ST_PAUSED;
  1018.     }
  1019.  
  1020.    return;
  1021. }  /* end of PauseTheMovie */
  1022.  
  1023. /******************************************************************************
  1024.  * Name         :  StopTheDevice
  1025.  *
  1026.  * Description  :  This procedure will stop the device that is playing or
  1027.  *                 recording.
  1028.  *
  1029.  * Concepts     :  Stopping a device using the MCI interface.
  1030.  *
  1031.  * MMPM/2 API's :  mciSendString
  1032.  *                    - stop
  1033.  *
  1034.  * Parameters   :  none
  1035.  *
  1036.  * Return       :  nothing.
  1037.  *
  1038.  ******************************************************************************/
  1039. VOID StopTheDevice( VOID )
  1040. {
  1041.  
  1042.    /*
  1043.     * To stop the device , we will issue an string command using mciSendString.
  1044.     * This stop command is done for the alias.
  1045.     */
  1046.    if (SendString( (HWND)NULL, "stop movie wait", 0 ) )
  1047.    {
  1048.       if (eState == ST_PLAYING)
  1049.         {
  1050.           eState = ST_STOPPED;
  1051.         }
  1052.    }
  1053.  
  1054.    return;
  1055. }  /* end of StopTheDevice */
  1056.  
  1057.  
  1058. /*************************************************************************
  1059.  * Name         :  CloseTheDevice
  1060.  *
  1061.  * Description  :  This procedure will close the Movie device.
  1062.  *
  1063.  * Concepts     :  Closing a device using MCI interface.
  1064.  *
  1065.  * MMPM/2 API's :  mciSendString
  1066.  *                    - close
  1067.  *
  1068.  * Parameters   :  None.
  1069.  *
  1070.  * Return       :  nothing.
  1071.  *
  1072.  ******************************************************************************/
  1073. VOID CloseTheDevice( VOID)
  1074. {
  1075.  
  1076.    /*
  1077.     * To stop the device , we will issue a string command using mciSendString.
  1078.     * This stop command is done for the alias.
  1079.     */
  1080.    fDeviceOpen = FALSE;
  1081.    fDevicePlaying = FALSE;
  1082.    SendString((HWND)NULL, "close movie", 0 );
  1083.  
  1084.    return;
  1085.  
  1086. }  /* end of CloseTheDevice */
  1087.  
  1088. /*************************************************************************
  1089.  * Name         :  OpenTheDevice
  1090.  *
  1091.  * Description  :  This procedure will open the Movie device.
  1092.  *
  1093.  * Concepts     :  Opening a device using MCI interface.
  1094.  *
  1095.  * MMPM/2 API's :  mciSendString
  1096.  *                    - open
  1097.  *
  1098.  * Parameters   :  None.
  1099.  *
  1100.  * Return       :  nothing.
  1101.  *
  1102.  ******************************************************************************/
  1103. BOOL OpenTheDevice( HWND hwnd)
  1104. {
  1105.   if (!fDeviceOpen )
  1106.  
  1107.   {
  1108.      /******************************************************************/
  1109.      /* To open the device, we will issue MCI_OPEN command to the MCI  */
  1110.      /* for digital video.                                             */
  1111.      /******************************************************************/
  1112.      if ( SendString( hwnd,
  1113.                       "open digitalvideo alias movie wait shareable",
  1114.                       0 ) )
  1115.  
  1116.      {
  1117.         /* Open success, set the flag and return true */
  1118.  
  1119.         fDeviceOpen = TRUE;
  1120.  
  1121.         return(TRUE);
  1122.  
  1123.      }
  1124.      else
  1125.         return( FALSE );
  1126.   }
  1127.  
  1128. }  /* end of OpenTheDevice */
  1129.  
  1130. /*************************************************************************
  1131.  * Name         :  SendString
  1132.  *
  1133.  * Description  :  This procedure will send string to MCI.
  1134.  *
  1135.  * Concepts     :
  1136.  *
  1137.  * MMPM/2 API's :  mciSendString
  1138.  *
  1139.  * Parameters   :  hwnd        - window handle.
  1140.  *                 pcMCIString - string command.
  1141.  *                 usUserParm  - user parameter.
  1142.  *
  1143.  * Return       :  TRUE  - if the operation was initiated without error.
  1144.  *                 FALSE - if an error occurred.
  1145.  *
  1146.  ******************************************************************************/
  1147. BOOL  SendString( HWND hwnd, PCHAR pcMCIString, USHORT usUserParm )
  1148. {
  1149.    LONG           lmciSendStringRC;    /* return value fromm mciSendString     */
  1150.  
  1151.  
  1152.    lmciSendStringRC =
  1153.        mciSendString( (PSZ)pcMCIString,
  1154.                       (PSZ)szReturn,
  1155.                       (USHORT)CCHMAXPATH,
  1156.                       (HWND)hwnd,
  1157.                       (USHORT)usUserParm );
  1158.  
  1159.    if (lmciSendStringRC != 0)
  1160.    {
  1161.       ShowMCIErrorMessage(lmciSendStringRC);
  1162.       return( FALSE );
  1163.    }
  1164.  
  1165.    return( TRUE );
  1166. }
  1167.  
  1168.  
  1169. /******************************************************************************
  1170.  * Name         :  MessageBox
  1171.  *
  1172.  * Description  :  This procedure will display messages for the application
  1173.  *                 based upon string IDs passed in.  The actual text will be
  1174.  *                 loaded from the string table in the resource.
  1175.  *
  1176.  * Concepts     :  None.
  1177.  *
  1178.  * MMPM/2 API's :  None.
  1179.  *
  1180.  * Parameters   :  usMessageID - ID of the message string
  1181.  *                 ulStyle     - Style of the message box (WinMessageBox)
  1182.  *
  1183.  * Return       :  TRUE  -  if the operation was initiated without error.
  1184.  *                 FALSE -  if an error occurred.
  1185.  *
  1186.  ******************************************************************************/
  1187. USHORT MessageBox( USHORT usMessageID, ULONG  ulStyle)
  1188. {
  1189.    CHAR     achMessage[LEN_ERROR_MESSAGE];
  1190.    USHORT   usResult;
  1191.  
  1192.    /*
  1193.     * Get the string from the Resource defined string table and show it
  1194.     * in the message box.
  1195.     */
  1196.    WinLoadString(
  1197.       hab,                             /* HAB for this dialog box.            */
  1198.       (HMODULE) NULL,                  /* Get the string from the .exe file.  */
  1199.       usMessageID,                     /* Which string to get.                */
  1200.       (SHORT) sizeof( achMessage),     /* The size of the buffer.             */
  1201.       achMessage );                    /* The buffer to place the string.     */
  1202.  
  1203.    usResult =
  1204.       WinMessageBox(
  1205.          HWND_DESKTOP,                 /* Parent handle of the message box.   */
  1206.          hwndMainDialogBox,            /* Owner handle of the message box.    */
  1207.          achMessage,                   /* String to show in the message box.  */
  1208.          achMsgBoxTitle,               /* Title to shown in the message box.  */
  1209.          (USHORT) ID_MESSAGEBOX,       /* Message Box Id.                     */
  1210.          ulStyle );                    /* The style of the message box.       */
  1211.  
  1212.    return( usResult );
  1213.  
  1214. }  /* End of MessageBox */
  1215.  
  1216.  
  1217. /******************************************************************************
  1218.  * Name         :  ShowMCIErrorMessage
  1219.  *
  1220.  * Description  :  This window procedure displays an MCI error message
  1221.  *                 based upon a ulError return code.  The MCI function
  1222.  *                 mciGetErrorString is used to convert the error code into
  1223.  *                 a text string and the title is pulled from the resource
  1224.  *                 based upon a string id.
  1225.  *
  1226.  * Concepts     :  Using mciGetErrorString to convert an error code into
  1227.  *                 a textual message.
  1228.  *
  1229.  * MMPM/2 API's :  mciGetErrorString
  1230.  *
  1231.  * Parameters   :  ulError  -  MCI error code.
  1232.  *
  1233.  * Return       :  nothing
  1234.  *
  1235.  ******************************************************************************/
  1236. VOID  ShowMCIErrorMessage( ULONG ulError)
  1237. {
  1238.    CHAR  achBuffer[LEN_ERROR_MESSAGE];
  1239.  
  1240.    switch(mciGetErrorString( ulError, (PSZ)achBuffer,   sizeof( achBuffer)))
  1241.    {
  1242.       case MCIERR_SUCCESS:
  1243.          /*
  1244.           * This is what we want.  We were able to use mciGetErrorString to
  1245.           * retrieve a textual error message we can show in a message box.
  1246.           */
  1247.          WinMessageBox( HWND_DESKTOP,
  1248.                         hwndMainDialogBox,
  1249.                         achBuffer,
  1250.                         achMsgBoxTitle,
  1251.                         (USHORT) ID_MESSAGEBOX,
  1252.                         MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  1253.          break;
  1254.  
  1255.       case MCIERR_INVALID_DEVICE_ID:
  1256.       case MCIERR_OUTOFRANGE:
  1257.       case MCIERR_INVALID_BUFFER:
  1258.       default:
  1259.          MessageBox( IDS_UNKNOWN,
  1260.                      MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  1261.          break;
  1262.    }
  1263.  
  1264.    return;
  1265.  
  1266. }  /* end of ShowMCIErrorMessage */
  1267.  
  1268.  
  1269. /******************************************************************************
  1270.  * Name         :  DoesFileExist
  1271.  *
  1272.  * Description  :  This helper function determines if a file with a given
  1273.  *                 file name exists. If it does, we want to attain specific
  1274.  *                 information for future use.  This information is attained
  1275.  *                 by getting the track ID of the movie.
  1276.  *
  1277.  * Concepts     :  Using MMIO interface to access a data file and header
  1278.  *                 information.
  1279.  *
  1280.  * MMPM/2 API's :  mmioOpen
  1281.  *                 mmioClose
  1282.  *                 mmioGetHeader
  1283.  *                 mmioSet
  1284.  *
  1285.  * Parameters   :  pszFileName - The file name to be tested.
  1286.  *
  1287.  * Return       :  TRUE  -  if the a file exists matching pszFilename
  1288.  *                          and there are no errors getting the movie file
  1289.  *                          header information.
  1290.  *                 FALSE -  if the file does not exist or problem getting
  1291.  *                          the movie file header information
  1292.  *
  1293.  *
  1294.  ******************************************************************************/
  1295. BOOL DoesFileExist( PSZ pszFileName )
  1296. {
  1297.    BOOL  bReturn = 0;                    /* Function return value       */
  1298.    HMMIO hFile;                          /* Handle to file              */
  1299.    ULONG  lHeaderLengthMovie;            /* Header length of movie file */
  1300.    ULONG  lHeaderLengthVideo;            /* Header length of movie file */
  1301.    ULONG  ulTrackID;                     /* Track ID                    */
  1302.    LONG   lBytes;                        /* Number of bytes read        */
  1303.    MMMOVIEHEADER  mmMovieHeader;         /* Std Movie Header            */
  1304.    MMVIDEOHEADER  mmVideoHeader;         /* Std Video Header            */
  1305.    MMEXTENDINFO   mmExtendinfo;          /* Std Extended Information    */
  1306.    MMIOINFO       mmioinfo;              /* Structure for mmio info     */
  1307.    PMMIOPROC      pIOProc;
  1308.    PMMIOPROC      pAnswer;
  1309.    HMODULE        hmod;
  1310.    FOURCC         fcc;
  1311.    CHAR           LoadError[100];
  1312.    ULONG          rc = MMIO_SUCCESS;
  1313.  
  1314.    /*********************************************************/
  1315.    /* Reset all my my mmio information structures           */
  1316.    /*********************************************************/
  1317.  
  1318.    memset(&mmioinfo, '\0', sizeof(MMIOINFO));
  1319.    memset(&mmExtendinfo, '\0', sizeof(MMEXTENDINFO));
  1320.    memset(&mmMovieHeader, '\0', sizeof(MMMOVIEHEADER));
  1321.    memset(&mmVideoHeader, '\0', sizeof(MMVIDEOHEADER));
  1322.  
  1323.    mmioinfo.ulTranslate =  MMIO_TRANSLATEHEADER;   /* Set to std translation */
  1324.  
  1325.                                     /* Set all operations on the active track*/
  1326.    mmExtendinfo.ulFlags = MMIO_TRACK;
  1327.  
  1328.    hFile = mmioOpen( pszFileName, &mmioinfo, MMIO_READ );
  1329.  
  1330.    if (hFile != (HMMIO) NULL)
  1331.     {
  1332.  
  1333.       mmExtendinfo.ulTrackID = -1;                   /* reset the track id */
  1334.  
  1335.      /*********************************************************/
  1336.      /* After the file is open set the extend information     */
  1337.      /*********************************************************/
  1338.  
  1339.       bReturn = mmioSet(hFile, &mmExtendinfo, MMIO_SET_EXTENDEDINFO);
  1340.  
  1341.       lHeaderLengthMovie = sizeof(MMMOVIEHEADER);
  1342.  
  1343.      /*********************************************************/
  1344.      /* Read the movie header informationn and get the track  */
  1345.      /* information.                                          */
  1346.      /*********************************************************/
  1347.       if (!(bReturn = mmioGetHeader(hFile,
  1348.                                     &mmMovieHeader,
  1349.                                     lHeaderLengthMovie,
  1350.                                     &lBytes,
  1351.                                     0L,
  1352.                                     0L)));
  1353.        {
  1354.  
  1355.           /**************************************************************/
  1356.           /* Here we will use the mmioSet to set the extended info      */
  1357.           /* to the correct track after issuing the mmioGetHeader. Once */
  1358.           /* we have the correct track we can issue mmioGetHeader       */
  1359.           /* requesting the movie information we wish to have. In this  */
  1360.           /* sample we are asking for the height, width, length of the  */
  1361.           /* movie.                                                     */
  1362.           /**************************************************************/
  1363.  
  1364.           mmExtendinfo.ulTrackID = mmMovieHeader.ulNextTrackID;
  1365.  
  1366.           bReturn = mmioSet(hFile, &mmExtendinfo, MMIO_SET_EXTENDEDINFO);
  1367.  
  1368.           lHeaderLengthVideo = sizeof(MMVIDEOHEADER);
  1369.  
  1370.           /*******************************************************/
  1371.           /* Get the information we need from the video header   */
  1372.           /*******************************************************/
  1373.  
  1374.           bReturn = mmioGetHeader(hFile,
  1375.                                   &mmVideoHeader,
  1376.                                   lHeaderLengthVideo,
  1377.                                   &lBytes,
  1378.                                   0L,
  1379.                                   0L);
  1380.  
  1381.           ulMovieWidth  = mmVideoHeader.ulWidth;
  1382.  
  1383.           ulMovieHeight = mmVideoHeader.ulHeight;
  1384.  
  1385.           ulMovieLength = mmVideoHeader.ulLength;
  1386.  
  1387.           /*****************************************************/
  1388.           /* Here we are using the mmioSet to reset the tracks */
  1389.           /* We do this just in case we would need to do some- */
  1390.           /* thing different with the movie file.              */
  1391.           /*****************************************************/
  1392.           mmExtendinfo.ulTrackID = MMIO_RESETTRACKS;
  1393.           bReturn = mmioSet(hFile, &mmExtendinfo,MMIO_SET_EXTENDEDINFO);
  1394.  
  1395.           mmioClose( hFile, 0);
  1396.  
  1397.           bReturn = TRUE;
  1398.           return (bReturn);
  1399.        }
  1400.     }
  1401.    bReturn = FALSE;
  1402.    return (bReturn);
  1403.  
  1404.  
  1405. }
  1406. /******************************************************************************
  1407.  * Name         :  SetMovieVolume
  1408.  *
  1409.  * Description  :  This helper function sets the Movie file volume based upon
  1410.  *                 the position of the volume slider.  The slider will be
  1411.  *                 queried and the Movie file volume will be set.
  1412.  *
  1413.  * Concepts     :  Setting the volume of a device.
  1414.  *
  1415.  * MMPM/2 API's :  mciSendString
  1416.  *                    - set
  1417.  *
  1418.  * Parameters   :  none.
  1419.  *
  1420.  * Return       :  none.
  1421.  *
  1422.  ******************************************************************************/
  1423. VOID SetMovieVolume( VOID )
  1424. {
  1425.    LONG      lmciSendStringRC;             /* return value form mciSendString */
  1426.    CHAR      szVolume[4] = "";             /* to hold the volume level        */
  1427.    CHAR      szCommandString[CCHMAXPATH] = /* string command to MCI           */
  1428.                "set movie audio volume ";
  1429.  
  1430.  
  1431.    if ((!fPassedDevice) && (eState == ST_PLAYING ))
  1432.    {
  1433.       /*
  1434.        * To set the volume,  first, build the string command for the
  1435.        * MCI.  Then an MCI_SET command should be issued to the device
  1436.        * to perform the volume change.
  1437.        */
  1438.       _itoa(sVolumeLevel, szVolume, 10);
  1439.       strcat( szCommandString, szVolume);
  1440.       strcat( szCommandString, " ");
  1441.       strcat( szCommandString, "wait");
  1442.  
  1443.       lmciSendStringRC =
  1444.           mciSendString( (PSZ)szCommandString,
  1445.                          (PSZ)szReturn,
  1446.                          CCHMAXPATH,
  1447.                          (HWND)NULL,
  1448.                          (USHORT)NULL );
  1449.       if (lmciSendStringRC != 0)
  1450.          ShowMCIErrorMessage(lmciSendStringRC);
  1451.  
  1452.    }
  1453.    return;
  1454. }  /* end of SetMovieVolume */
  1455.  
  1456. /*************************************************************************
  1457.  * Name         : InitializeHelp
  1458.  *
  1459.  * Description  : This procedure will set up the initial values in the
  1460.  *                global help structure.  This help structure will then
  1461.  *                be passed on to the Help Manager when the Help Instance
  1462.  *                is created.  The handle to the Help Instance will be
  1463.  *                kept for later use.
  1464.  *
  1465.  * Concepts     : None.
  1466.  *
  1467.  * MMPM/2 API's : None.
  1468.  *
  1469.  * Parameters   : None.
  1470.  *
  1471.  * Return       : None.
  1472.  *
  1473.  *************************************************************************/
  1474. VOID InitializeHelp( VOID )
  1475. {
  1476.  
  1477.    HELPINIT helpInit;                 /* Help initialization structure.          */
  1478.    CHAR     achHelpLibraryName[LEN_HELP_LIBRARY_NAME];
  1479.    CHAR     achHelpWindowTitle[LEN_HELP_WINDOW_TITLE];
  1480.  
  1481.    /*
  1482.     * Load the strings for the Help window title and library name.
  1483.     * Initialize the help structure and associate the help instance.
  1484.     */
  1485.    WinLoadString( hab,
  1486.                   (HMODULE) NULL,
  1487.                   IDS_HELP_WINDOW_TITLE,
  1488.                   (SHORT) sizeof( achHelpWindowTitle),
  1489.                   achHelpWindowTitle);
  1490.  
  1491.    WinLoadString( hab,
  1492.                   (HMODULE) NULL,
  1493.                   IDS_HELP_LIBRARY_NAME,
  1494.                   (SHORT) sizeof( achHelpLibraryName),
  1495.                   achHelpLibraryName);
  1496.  
  1497.    memset ( &helpInit, 0, sizeof(helpInit) );
  1498.    /*
  1499.     * Initialize the help structure.
  1500.     */
  1501.    helpInit.cb                 = sizeof( helpInit);  /* size of the help struc*/
  1502.    helpInit.ulReturnCode       = (ULONG) 0;          /* RC from HM init       */
  1503.    helpInit.pszTutorialName    = (PSZ) NULL;         /* No tutorial program   */
  1504.    helpInit.pszHelpWindowTitle = achHelpWindowTitle; /* The Help window title.*/
  1505.    helpInit.fShowPanelId       = (ULONG) 0;          /* help panel ID.        */
  1506.    helpInit.pszHelpLibraryName = achHelpLibraryName; /* library name          */
  1507.    helpInit.phtHelpTable       = (PVOID)(0xffff0000 | ID_MOVIE_HELPTABLE);
  1508.  
  1509.    /*
  1510.     * Create the Help Instance for IPF.
  1511.     * Give IPF the Anchor Block handle and address of the IPF initialization
  1512.     * structure, and check that creation of Help was a success.
  1513.     */
  1514.    hwndHelpInstance = WinCreateHelpInstance(
  1515.                          hab,                   /* Anchor Block Handle.       */
  1516.                          &helpInit );           /* Help Structure.            */
  1517.  
  1518.    if ( hwndHelpInstance == (HWND) NULL)
  1519.    {
  1520.       MessageBox( IDS_HELP_CREATION_FAILED,     /* ID of the message          */
  1521.                   MB_OK | MB_INFORMATION  | MB_MOVEABLE);    /* style         */
  1522.    }
  1523.    else
  1524.    {
  1525.       if ( helpInit.ulReturnCode)
  1526.       {
  1527.          WinDestroyHelpInstance( hwndHelpInstance);
  1528.          MessageBox( IDS_HELP_CREATION_FAILED,     /* ID of the message       */
  1529.                      MB_OK | MB_INFORMATION | MB_MOVEABLE);     /* style      */
  1530.       }
  1531.       else  /* help creation worked */
  1532.          WinAssociateHelpInstance(
  1533.             hwndHelpInstance,        /* The handle of the Help Instance.      */
  1534.             hwndFrame);              /* Associate to this dialog window.      */
  1535.    }  /* End of IF checking the creation of the Help Instance. */
  1536.  
  1537. }  /* End of InitializeHelp */
  1538.  
  1539. /******************************************************************************
  1540.  * Name         : ResizeMovieWindow
  1541.  *
  1542.  * Description  : This function will resize the applications movie window
  1543.  *                according to the height and width of the movie file being
  1544.  *                opened.
  1545.  *
  1546.  * Parameters   : hwnd - Handle of the secondary window.
  1547.  *
  1548.  * Return       : none.
  1549.  *
  1550.  ******************************************************************************/
  1551. VOID ResizeMovieWindow (HWND hwnd)
  1552. {
  1553.  
  1554.    HWND hwndSEFrame;                 /* handle for the Secondary Window Frame */
  1555.    SWP  swpSEFrame;              /* struc containing information on Frame     */
  1556.    SWP  swpRewind;               /* struc containing information rewind button*/
  1557.    LONG cxWidthBorder = 0;
  1558.    LONG cyWidthBorder = 0;
  1559.    LONG cyTitleBar = 0;
  1560.  
  1561.   /*************************************************************/
  1562.   /* Query the position of the secondary window frame          */
  1563.   /* and the rewind button so we can postion our application   */
  1564.   /* frame for the movie.                                      */
  1565.   /*************************************************************/
  1566.  
  1567.    WinQueryWindowPos( hwndFrame, &swpSEFrame );
  1568.  
  1569.    WinQueryWindowPos( WinWindowFromID( hwnd, IDC_GPB_REWIND ),
  1570.                       &swpRewind );
  1571.  
  1572.    cxWidthBorder = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);
  1573.    cyWidthBorder = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
  1574.    cyTitleBar =    (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  1575.  
  1576.   /*************************************************************/
  1577.   /* Check to see if our movie size is larger than our frame   */
  1578.   /* if it is then resize our frame to fit the movie.          */
  1579.   /*************************************************************/
  1580.  
  1581.    if ((swpSEFrame.cx - (2 * cxWidthBorder)) <= ulMovieWidth)
  1582.     {
  1583.       swpSEFrame.cx = ulMovieWidth + (2 * cxWidthBorder);
  1584.     } /* if */
  1585.    if ((swpSEFrame.cy - swpRewind.cy - ulMovieHeight - cyTitleBar - (2 * cyWidthBorder)
  1586.                                                          < ulMovieHeight ))
  1587.     {
  1588.       swpSEFrame.cy = ulMovieHeight + cyTitleBar + (2 * cyWidthBorder);
  1589.     } /* if */
  1590.  
  1591.   /*************************************************************/
  1592.   /* Set the position and size of the application window       */
  1593.   /* to the position and size of the movie.                    */
  1594.   /*************************************************************/
  1595.  
  1596.    WinSetWindowPos( hwndAppFrame, HWND_TOP,
  1597.                     (swpSEFrame.cx - ulMovieWidth - cxWidthBorder) / 2,
  1598.                     (cyWidthBorder + swpRewind.y + swpRewind.cy) + 5,
  1599.                     ulMovieWidth,
  1600.                     ulMovieHeight,
  1601.                     SWP_SIZE | SWP_MOVE);
  1602.  
  1603. }
  1604.