home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / CAPSAMP / CAPSAMP.C < prev    next >
C/C++ Source or Header  |  1993-03-13  |  83KB  |  2,196 lines

  1. /******************************************************************************
  2.  * File Name    : CAPSAMP.C
  3.  *
  4.  * Description  : This file contains the C source code required for the
  5.  *                caption sample application program.
  6.  *
  7.  * Concepts     : This sample program is part of MMPM/2 sample closed
  8.  *                captioning system.  This sample closed captioning system
  9.  *                is composed of three parts: Caption Creation Utility,
  10.  *                Caption DLL, and Caption Sample Application (this sample).
  11.  *                The Caption Creation Utility creates a "captioned" file.
  12.  *                This is a text file with timing information relating to
  13.  *                it's associated audio file.  The Caption DLL provides 3
  14.  *                API's that drive the display and management of a "caption
  15.  *                window" in a PM application.  The caption sample (this
  16.  *                program) illustrates how an application uses the 3 API's
  17.  *                provided by the caption DLL to take advantage of it's
  18.  *                services.
  19.  *
  20.  *                This sample captioning system is provided to illustrate one
  21.  *                of the many ways that captioning may be implemented using
  22.  *                MMPM/2. As with all MMPM/2 samples, this may be used as it
  23.  *                is provided, or it may be modified in any way you prefer.
  24.  *                Please refer to the Application Programmers Reference for
  25.  *                more information on this sample captioning system.
  26.  *
  27.  * MMPM/2 API's : List of all MMPM/2 API's that are used in
  28.  *                this module
  29.  *
  30.  *                mciSendString
  31.  *                mciGetErrorString
  32.  *                mciQuerySysValue
  33.  *                mmioOpen
  34.  *                mmioClose
  35.  *
  36.  * Required
  37.  *    Files     : capsamp.c        Source Code.
  38.  *                capsamp.h        Include file.
  39.  *                captions.h       Include file.
  40.  *                capsamp.dlg      Dialog definition.
  41.  *                capsamp.rc       Resources.
  42.  *                capsamp.ipf      Help text.
  43.  *                makefile         Make file.
  44.  *                capsamp.def      Linker definition file.
  45.  *                capsamp.ico      Program icon.
  46.  *
  47.  * Copyright (C) IBM 1993
  48.  ******************************************************************************/
  49.  
  50. #define  INCL_WIN                   /* required to use Win APIs.           */
  51. #define  INCL_PM                    /* required to use PM APIs.            */
  52. #define  INCL_WINHELP               /* required to use IPF.                */
  53. #define  INCL_GPIPRIMATIVES         /* required for GPI APIs.              */
  54. #define  INCL_OS2MM                 /* required for MCI and MMIO headers   */
  55. #define  INCL_SECONDARYWINDOW       /* required for secondary window       */
  56. #define  INCL_CIRCULARSLIDER        /* required for circular slider control*/
  57. #define  INCL_GRAPHICBUTTON         /* required for graphic button control */
  58. #define  INCL_DOSERRORS             /* required for dos errors             */
  59.  
  60. #include <os2.h>
  61. #include <os2me.h>
  62. #include <stdlib.h>
  63. #include <string.h>
  64.  
  65. #include <sw.h>
  66.  
  67. #include "capsamp.h"
  68. #include "captions.h"
  69.  
  70. enum DeviceStates {ST_STOPPED, ST_PLAYING, ST_PAUSED};
  71. /*
  72.  * Procedure/Function Prototypes
  73.  */
  74. MRESULT EXPENTRY MainDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  75. MRESULT EXPENTRY ProductInfoDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2);
  76. MRESULT EXPENTRY SettingsDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  77.  
  78. BOOL    DoesFileExist( PSZ pszFileName );
  79. VOID    Finalize( VOID );
  80. VOID    Initialize( VOID );
  81. VOID    InitializeHelp( VOID );
  82. USHORT  MessageBox( USHORT usMessageID, ULONG  ulStyle );
  83. BOOL    OpenTheFile( HWND hwnd );
  84. BOOL    PlayTheAudio( HWND hwnd );
  85. VOID    SetAudioVolume( VOID);
  86. VOID    ShowMCIErrorMessage( ULONG ulError );
  87. VOID    StopTheDevice( VOID );
  88. VOID    ResumeTheAudio( VOID );
  89. VOID    PauseTheAudio( VOID );
  90. BOOL    SeekTheAudio( VOID );
  91. VOID    CloseTheDevice( VOID );
  92. VOID    StartTheCaption( HWND hwnd );
  93. VOID    InitializeSpinButton( HWND hwnd );
  94. VOID    SetAudioSliderPosition( HWND hwnd );
  95. BOOL    SendString( HWND hwnd, PCHAR pcMCIString, USHORT usUserParm );
  96.  
  97. /*************** End of Procedure/Function Prototypes *************************/
  98.  
  99. /*
  100.  * Global Variables.
  101.  */
  102. HAB    hab;
  103. HMQ    hmq;
  104. HWND   hwndFrame;                      /* Handle to the frame window.         */
  105. HWND   hwndCaption;                    /* Window which displays caption text  */
  106. HWND   hwndHelpInstance;               /* Handle to Main Help window.         */
  107. HWND   hwndMainDialogBox;              /* Handle to the dialog window.        */
  108. HWND   hwndPlayPB;                     /* Handle to the play push button      */
  109. HWND   hwndAudioSlider;                /* Handle to the audio slider          */
  110. HWND   hwndProductInfo = (HWND)0;      /* Handle to the product info. dlg box */
  111. ULONG  ulAudioLength;                  /* Audio length in MM units            */
  112. SHORT  sAudioArmRange;                 /* Slider arm range in pels            */
  113.  
  114. enum   DeviceStates   eState = ST_STOPPED;       /* state of the device       */
  115.  
  116. SHORT  sVolumeLevel   = INIT_VOLUME;   /* desired volume level                */
  117. BOOL   fPassedDevice  = FALSE;         /* for MCI_ACQUIRE to play the file    */
  118. BOOL   fDeviceOpen    = FALSE;         /* indicate we've opened for first time*/
  119. CHAR   achMsgBoxTitle[MAXNAMEL];       /* Error message box title             */
  120.  
  121. CHAR   szWhite [OPTIONSLEN];           /* for caption window background color */
  122. CHAR   szYellow[OPTIONSLEN];           /* for caption window background color */
  123. CHAR   szGray  [OPTIONSLEN];           /* for caption window background color */
  124. CHAR   szBlue  [OPTIONSLEN];           /* for caption window text color       */
  125. CHAR   szBlack [OPTIONSLEN];           /* for caption window text color       */
  126. CHAR   szRed   [OPTIONSLEN];           /* for caption window text color       */
  127. CHAR   szCenter[OPTIONSLEN];           /* for caption window position         */
  128. CHAR   szLeft  [OPTIONSLEN];           /* for caption window position         */
  129. CHAR   szRight [OPTIONSLEN];           /* for caption window position         */
  130.  
  131. PCHAR  textColumns[3]     = {"15", "35", "50"};
  132. PCHAR  textRows[3]        = {"2",  "3",  "4" };
  133. PCHAR  backgroundColor[3] = {szWhite,  szYellow, szGray };
  134. PCHAR  textColor[3]       = {szBlue,   szBlack,  szRed  };
  135. PCHAR  windowPosition[3]  = {szCenter, szLeft,   szRight};
  136.  
  137. CHAR   szReturn[CCHMAXPATH];           /* return value from mciSendString     */
  138. RECTL  rclMain;                        /* for the dimensions of the main wind.*/
  139. HPOINTER  hptrWait, hptrArrow;  /* Pointer handles for use during long waits. */
  140. FONTMETRICS fm;                 /* font matrics structure.                    */
  141.  
  142. /************************** End of Global Variables ***************************/
  143.  
  144. /******************************************************************************
  145.  * Name         : main
  146.  *
  147.  * Description  : This function calls the Initialize procedure to prepare
  148.  *                everything for the program's operation, enters the
  149.  *                message loop, then call Finalize to shut everything down
  150.  *                when the program is terminated.
  151.  *
  152.  * Concepts     : None.
  153.  *
  154.  * MMPM/2 API's : None.
  155.  *
  156.  * Parameters   : argc - Number of parameters passed into the program.
  157.  *                argv - Command line parameters.
  158.  *
  159.  * Return       : TRUE is returned to the operating system.
  160.  *
  161.  ******************************************************************************/
  162. INT main( VOID )
  163. {
  164.    QMSG    qmsg;
  165.  
  166.    Initialize();
  167.  
  168.    while ( WinGetMsg( hab, (PQMSG) &qmsg, (HWND) NULL, 0, 0) )
  169.       WinDispatchMsg( hab, (PQMSG) &qmsg );
  170.  
  171.    Finalize();
  172.  
  173.    return( TRUE);
  174.  
  175. } /* End of main */
  176.  
  177.  
  178. /******************************************************************************
  179.  * Name         : Initialize
  180.  *
  181.  * Description  : This function performs the necessary initializations and
  182.  *                setups that are required to show/run a dialog box as a
  183.  *                main window.  The message queue will be created, as will
  184.  *                the dialog box.
  185.  *
  186.  * Concepts     : Initialize captioning window using ccInitialize.
  187.  *
  188.  * MMPM/2 API's : WinLoadSecondaryWindow
  189.  *                WinQuerySecondaryHWND
  190.  *
  191.  * Parameters   : None.
  192.  *
  193.  * Return       : None.
  194.  *
  195.  ******************************************************************************/
  196. VOID Initialize( VOID)
  197. {
  198.    CHAR     szDefaultSize[CCHMAXPATH];   /* buffer for default size menu text */
  199.    CHAR     achTitle[MAXNAMEL];          /* buffer for window title text      */
  200.  
  201.  
  202.    hab       = WinInitialize( 0);
  203.    hmq       = WinCreateMsgQueue( hab, 0);
  204.  
  205.    hptrArrow = WinQuerySysPointer ( HWND_DESKTOP, SPTR_ARROW, FALSE );
  206.    hptrWait  = WinQuerySysPointer ( HWND_DESKTOP, SPTR_WAIT,  FALSE );
  207.  
  208.    /*
  209.     * Initialize the dialog window. First, change pointer to a waiting
  210.     * pointer, since this might take a couple of seconds.
  211.     */
  212.    WinSetPointer ( HWND_DESKTOP, hptrWait );
  213.  
  214.    WinLoadString(
  215.       hab,                                  /* HAB for this dialog box.       */
  216.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  217.       IDS_DEFAULTSIZE,                      /* Which string to get.           */
  218.       sizeof(szDefaultSize),                /* The size of the buffer.        */
  219.       szDefaultSize);                       /* The buffer to place the string.*/
  220.  
  221.    WinLoadString(
  222.       hab,                                  /* HAB for this dialog box.       */
  223.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  224.       IDS_CAP_SAM_ERROR,                    /* Which string to get.           */
  225.       (SHORT) sizeof( achMsgBoxTitle),      /* The size of the buffer.        */
  226.       achMsgBoxTitle);                      /* The buffer to place the string.*/
  227.  
  228.    hwndFrame =                    /* Returns the handle to the frame.         */
  229.        WinLoadSecondaryWindow(
  230.           HWND_DESKTOP,           /* Parent of the dialog box.                */
  231.           HWND_DESKTOP,           /* Owner of the dialog box.                 */
  232.           (PFNWP) MainDlgProc,    /* 'Window' procedure for the dialog box.   */
  233.           (HMODULE) NULL,         /* Where is the dialog.  Null is EXE file.  */
  234.           IDD_MAIN_WINDOW,        /* Dialog ID.                               */
  235.           (PVOID) NULL);          /* Creation Parameters for the dialog.      */
  236.  
  237.    /*
  238.     * Retrieve the handle to the dialog box by specifying the QS_DIALOG flag.
  239.     */
  240.    hwndMainDialogBox = WinQuerySecondaryHWND(hwndFrame, QS_DIALOG);
  241.  
  242.    /*
  243.     * Add Default Size menu item to system menu of the secondary window.
  244.     */
  245.    WinInsertDefaultSize(hwndFrame, szDefaultSize);
  246.  
  247.    /*
  248.     * Get the window title string from the Resource string table
  249.     * and set it as the window text for the dialog window.
  250.     */
  251.    WinLoadString(
  252.       hab,                                  /* HAB for this dialog box.       */
  253.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  254.       IDS_PROGRAM_TITLE,                    /* Which string to get.           */
  255.       (SHORT) sizeof( achTitle),            /* The size of the buffer.        */
  256.       achTitle);                            /* The buffer to place the string.*/
  257.  
  258.    WinSetWindowText( hwndFrame, achTitle);
  259.  
  260.    /*
  261.     * Create the caption window and save the handle for further use.
  262.     */
  263.    hwndCaption = ccInitialize ( (HWND) hwndMainDialogBox );
  264.  
  265.    if (( hwndCaption == (ULONG) CCERR_INVALID_WINDOW_HANDLE ) ||
  266.        ( hwndCaption == (HWND)0))
  267.        MessageBox( IDS_INVALID_WINDOW_HANDLE,
  268.                    MB_CANCEL | MB_ERROR  | MB_MOVEABLE);
  269.  
  270.    WinShowWindow( hwndFrame, TRUE );           /* Display the main window.    */
  271.  
  272.    InitializeHelp();                           /* Initialize the help.        */
  273.  
  274.    /*
  275.     * Now that we're done here, change the pointer back to the arrow.
  276.     */
  277.    WinSetPointer ( HWND_DESKTOP, hptrArrow );
  278.  
  279. } /* End of Initialize */
  280.  
  281. /******************************************************************************
  282.  * Name         : Finalize
  283.  *
  284.  * Description  : This routine is called after the message dispatch loop
  285.  *                has ended because of a WM_QUIT message.  The code will
  286.  *                destroy the help instance, messages queue, and window.
  287.  *
  288.  * Concepts     : None.
  289.  *
  290.  * MMPM/2 API's : WinDestroySecondaryWindow
  291.  *
  292.  * Parameters   : None.
  293.  *
  294.  * Return       : None.
  295.  *
  296.  ******************************************************************************/
  297. VOID Finalize( VOID )
  298. {
  299.    /*
  300.     * Destroy the Help Instances.
  301.     */
  302.    if ( hwndHelpInstance != (HWND) NULL)
  303.    {
  304.       WinDestroyHelpInstance( hwndHelpInstance );
  305.    }
  306.  
  307.    WinDestroySecondaryWindow( hwndFrame );
  308.    WinDestroyMsgQueue( hmq );
  309.    WinTerminate( hab );
  310.  
  311. }  /* End of Finalize */
  312.  
  313. /******************************************************************************
  314.  * Name         : MainDlgProc
  315.  *
  316.  * Description  : This function controls the main dialog box.  It will handle
  317.  *                received messages such as pushbutton notifications, timing
  318.  *                events, etc.
  319.  *
  320.  * Concepts     : Illustrates:
  321.  *                  - How to participate in MMPM/2 device sharing scheme.
  322.  *                  - How to handle notification messages.
  323.  *                  - How to implement graphic pushbutton's
  324.  *                  - How to implement secondary windows.
  325.  *
  326.  * MMPM/2 API's : WinDefSecondaryWindowProc
  327.  *                mciSendString
  328.  *                   - acquire
  329.  *
  330.  * Parameters   : hwnd - Handle for the Main dialog box.
  331.  *                msg  - Message received by the dialog box.
  332.  *                mp1  - Parameter 1 for the just received message.
  333.  *                mp2  - Parameter 2 for the just received message.
  334.  *
  335.  * Return       : 0 or the result of default processing.
  336.  *
  337.  ******************************************************************************/
  338. MRESULT EXPENTRY MainDlgProc( HWND   hwnd,
  339.                               ULONG  msg,
  340.                               MPARAM mp1,
  341.                               MPARAM mp2 )
  342. {
  343.    LONG        lmciSendStringRC;      /* return value form mciSendString      */
  344.    HPOINTER    hpProgramIcon;         /* handle to program's icon             */
  345.    USHORT      usCommandMessage;      /* command message for notify           */
  346.    USHORT      usNotifyCode;          /* notification message code            */
  347.    SHORT       sArmPosition;          /* Updated slider arm position          */
  348.    SHORT       sWmControlID;          /* WM_CONTROL id                        */
  349.    ULONG       ulTime;                /* Media position in mm units           */
  350.  
  351.  
  352.    switch( msg )
  353.    {
  354.       case WM_INITDLG :
  355.          hpProgramIcon =
  356.             WinLoadPointer(
  357.                HWND_DESKTOP,
  358.                (HMODULE) NULL,              /* Resource is kept in .Exe file. */
  359.                ID_ICON );                   /* Which icon to use.             */
  360.  
  361.          WinDefSecondaryWindowProc(
  362.             hwnd,                    /* Dialog window handle.                 */
  363.             WM_SETICON,              /* Message to the dialog.  Set it's icon.*/
  364.             (MPARAM) hpProgramIcon,
  365.             (MPARAM) 0 );            /* mp2 no value.                         */
  366.  
  367.          /*
  368.           * get all the required handles.
  369.           */
  370.          hwndAudioSlider = WinWindowFromID( hwnd, IDC_AUDIO_SLIDER );
  371.          hwndPlayPB      = WinWindowFromID( hwnd, IDC_GPB_PLAY );   /* play PB*/
  372.  
  373.          /*
  374.           * Enable the audio slider.
  375.           */
  376.          WinEnableWindow( hwndAudioSlider, TRUE );
  377.  
  378.          /*
  379.           * The slider control cannot be completely set from the dialog
  380.           * template so some aspects must be set here.  We will set the
  381.           * volume range to 0-100, increment to 1-10, and the initial
  382.           * volume level to 75.
  383.           */
  384.          WinSendMsg( WinWindowFromID(hwnd, IDC_SL_VOLUME),
  385.                      CSM_SETRANGE,
  386.                      (MPARAM) 0L,
  387.                      (MPARAM) 100L);
  388.  
  389.          WinSendMsg( WinWindowFromID(hwnd, IDC_SL_VOLUME),
  390.                      CSM_SETINCREMENT,
  391.                      (MPARAM) 10L,
  392.                      (MPARAM) 1L);
  393.  
  394.          WinSendMsg( WinWindowFromID(hwnd, IDC_SL_VOLUME),
  395.                      CSM_SETVALUE,
  396.                      (MPARAM) sVolumeLevel,
  397.                      (MPARAM) NULL);
  398.          /*
  399.           * Set up the PLAY graphic pushbutton.
  400.           */
  401.          WinSendMsg (
  402.             hwndPlayPB,                   /* Play push button handle          */
  403.             GBM_SETANIMATIONRATE,         /* Animation rate control           */
  404.             MPFROMLONG(100L),             /* Update play bitmap every .1 sec  */
  405.             NULL);                        /* Ignore return data               */
  406.  
  407.          return( (MRESULT) 0);
  408.  
  409.       case WM_CLOSE :
  410.          /*
  411.           * If the device is opened, close the device.
  412.           */
  413.          if (fDeviceOpen)
  414.             CloseTheDevice();
  415.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  416.  
  417.       case WM_HELP :
  418.          /*
  419.           * The dialog window has received a request for help from the user,
  420.           * i.e., the Help pushbutton was pressed.  Send the HM_DISPLAY_HELP
  421.           * message to the Help Instance with the IPF resource identifier
  422.           * for the correct HM panel.  This will show the help panel for this
  423.           * sample program.
  424.           */
  425.          WinSendMsg( hwndHelpInstance,
  426.                      HM_DISPLAY_HELP,
  427.                      MPFROMSHORT(1),
  428.                      MPFROMSHORT(HM_RESOURCEID));
  429.          return( (MRESULT) 0);
  430.  
  431.       case WM_COMMAND :
  432.          /*
  433.           * To get which pushbutton was pressed the SHORT1FROMMP macro is used.
  434.           */
  435.          switch (SHORT1FROMMP(mp1))
  436.          {
  437.             case IDC_GPB_PLAY:               /* user selected "Play"          */
  438.                switch ( eState )
  439.                {
  440.                   /*
  441.                    * If the audio is currently stopped, open/load the audio
  442.                    * file.
  443.                    */
  444.                   case ST_STOPPED:
  445.                      if (OpenTheFile(hwnd))
  446.                      {
  447.                         /*
  448.                          * Set the audio slider position and start playing.
  449.                          */
  450.                         if ( PlayTheAudio( hwnd ) )
  451.                            /*
  452.                             * If play was success, start captioning.
  453.                             */
  454.                            StartTheCaption(hwnd);
  455.                      }
  456.                      break;
  457.                   /*
  458.                    * If the audio is currently paused, resume the audio play.
  459.                    */
  460.                   case ST_PAUSED:
  461.                      ResumeTheAudio();
  462.                      break;
  463.                }
  464.                break;
  465.  
  466.             case IDC_GPB_PAUSE:
  467.                switch ( eState )
  468.                {
  469.                  /*
  470.                   * If the audio is currently playing, pause it.
  471.                   */
  472.                  case ST_PLAYING:
  473.                     PauseTheAudio();
  474.                     break;
  475.                  /*
  476.                   * If the audio is currently paused, resume the audio play.
  477.                   */
  478.                  case ST_PAUSED:
  479.                     ResumeTheAudio();
  480.                     break;
  481.               }
  482.               break;
  483.  
  484.             case IDC_GPB_REWIND:         /* user selected "Rewind" pushbutton */
  485.                if (fDeviceOpen)          /* If the device is opened           */
  486.                {
  487.                   /*
  488.                    * Stop the audio, hide the caption window and set the audio
  489.                    * slider position to zero.
  490.                    */
  491.                   StopTheDevice();
  492.                   ccSendCommand( CC_STOP, MPFROMHWND(hwndCaption), 0 );
  493.                   WinSendMsg(
  494.                          hwndAudioSlider,
  495.                          SLM_SETSLIDERINFO,
  496.                          MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE),
  497.                          MPFROMSHORT( 0 ) );
  498.                }
  499.                break;
  500.  
  501.             case IDC_GPB_STOP:             /* user selected "Stop" pushbutton */
  502.                /*
  503.                 * If the audio is not in stopped state, stop the device and
  504.                 * hide the text window.
  505.                 */
  506.                if (eState != ST_STOPPED)
  507.                {
  508.                   StopTheDevice();
  509.                   ccSendCommand( CC_STOP, MPFROMHWND(hwndCaption), 0 );
  510.                }
  511.                break;
  512.  
  513.             case IDM_SETTINGS:            /* user selected "Settings" menu */
  514.                /*
  515.                 * Call the settings dialog window.
  516.                 */
  517.                WinDlgBox(
  518.                   HWND_DESKTOP,                /* Parent of the dialog box.   */
  519.                   hwndMainDialogBox,           /* Owner of the dialog box.    */
  520.                   (PFNWP) SettingsDlgProc,     /* Dialog box procedure.       */
  521.                   (HMODULE) NULL,              /* Dialog is where, EXE file.  */
  522.                   IDD_SETTINGS_DLG,            /* Dialog ID.                  */
  523.                   (PVOID) NULL);               /* Dialog Creation Parameters. */
  524.  
  525.                return( 0 );
  526.  
  527.             case IDM_HELP_PRODUCTINFO :
  528.                /*
  529.                 * See if the product information dialog box is already
  530.                 * displayed.
  531.                 */
  532.                if (!hwndProductInfo)
  533.                {
  534.                   /*
  535.                    * Product Window was not created, create and display the
  536.                    * window.
  537.                    */
  538.                   hwndProductInfo =
  539.                       WinLoadSecondaryWindow(
  540.                          HWND_DESKTOP,             /* Parent of the dialog box*/
  541.                          hwndFrame,                /* Owner of the dialog box.*/
  542.                          (PFNWP)ProductInfoDlgProc,/* Dialog box procedure.   */
  543.                          (HMODULE) NULL,           /* Dialog is where,EXE file*/
  544.                          IDD_PRODUCTINFO_DLG,      /* Dialog ID.              */
  545.                          (PVOID) NULL);            /* Dialog Creation Params  */
  546.                }
  547.                else
  548.                {
  549.                   /*
  550.                    * Product window was created earlier, reposition the window
  551.                    * and give the focus.
  552.                    */
  553.                   WinSetWindowPos(
  554.                      hwndProductInfo,
  555.                      HWND_TOP,
  556.                      (SHORT) NULL,
  557.                      (SHORT) NULL,
  558.                      (SHORT) NULL,
  559.                      (SHORT) NULL,
  560.                      SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE );
  561.  
  562.                   WinSetFocus( HWND_DESKTOP, hwndProductInfo );
  563.                }
  564.                return( 0 );
  565.  
  566.             case IDM_HELP_INDEX :            /* user selected "Help Index"    */
  567.                /*
  568.                 * Call system default help index panel.
  569.                 */
  570.                WinSendMsg( hwndHelpInstance,
  571.                            HM_HELP_INDEX,
  572.                            NULL,
  573.                            NULL);
  574.                break;
  575.  
  576.             case IDM_HELP_GENERAL :          /* user selected "General Help"  */
  577.                /*
  578.                 * Call general help panel.
  579.                 */
  580.                WinSendMsg( hwndHelpInstance,
  581.                            HM_DISPLAY_HELP,
  582.                            MPFROMSHORT(1),
  583.                            MPFROMSHORT(HM_RESOURCEID));
  584.                break;
  585.  
  586.             case IDM_HELP_USING :            /* user selected "Using Help"    */
  587.                /*
  588.                 * Call system default using help panel.
  589.                 */
  590.                WinSendMsg( hwndHelpInstance,
  591.                            HM_DISPLAY_HELP,
  592.                            NULL,
  593.                            NULL);
  594.                break;
  595.  
  596.             case IDM_HELP_KEYS :             /* user selected "Keys Help"     */
  597.                /*
  598.                 * Call keys help panel.
  599.                 */
  600.                WinSendMsg( hwndHelpInstance,
  601.                            HM_DISPLAY_HELP,
  602.                            MPFROMSHORT(3),
  603.                            MPFROMSHORT(HM_RESOURCEID));
  604.                break;
  605.  
  606.             default:
  607.                break;
  608.  
  609.          }  /* End of Command Switch */
  610.          return( (MRESULT) 0);
  611.  
  612.       case WM_CONTROL:
  613.         sWmControlID  = SHORT1FROMMP(mp1);
  614.         usNotifyCode  = (USHORT) SHORT2FROMMP(mp1);
  615.  
  616.         switch ( sWmControlID )
  617.         {
  618.            case IDC_SL_VOLUME:
  619.               if ((usNotifyCode == CSN_CHANGED) ||        /* change volume?   */
  620.                   (usNotifyCode == CSN_TRACKING))         /* tracking volume? */
  621.               {
  622.                 /*
  623.                  *  Every time the volume control setting is changed, save the
  624.                  *  new value in sVolumeLevel.
  625.                  */
  626.                  sVolumeLevel = SHORT1FROMMP (mp2);
  627.  
  628.                 /*
  629.                  *  Set the new volume level
  630.                  */
  631.                  SetAudioVolume();
  632.               }
  633.               break;
  634.  
  635.            case IDC_AUDIO_SLIDER:
  636.               /*
  637.                * We need to determine if the SLN_CHANGE message caming from
  638.                * the user or from the program.  If the slider has the focus,
  639.                * that implies that the user updated the slider control.
  640.                */
  641.               if ( ( usNotifyCode != SLN_CHANGE ) ||
  642.                    ( WinQueryFocus ( HWND_DESKTOP ) != hwndAudioSlider ) )
  643.                  /*
  644.                   * SLN_CHANGE messages are not originated by the user, ignore.
  645.                   */
  646.                  break;
  647.  
  648.               /*
  649.                * User updated the audio slider. Change the focus to the play
  650.                * pushbutton. This is needed to continue the above test.
  651.                */
  652.               WinSetFocus( HWND_DESKTOP, hwndPlayPB );
  653.  
  654.               /*
  655.                * Get the new slider position.
  656.                */
  657.               sArmPosition = SHORT1FROMMP(mp2);
  658.  
  659.               if ((eState == ST_PLAYING) || (eState == ST_PAUSED))
  660.               {
  661.                  /*
  662.                   * Audio is playing or paused. Stop the audio and restart
  663.                   * from the new position.
  664.                   */
  665.                  StopTheDevice();
  666.                  PlayTheAudio( hwnd );
  667.               }
  668.               break;
  669.         }
  670.          return( (MRESULT) 0);
  671.  
  672.  
  673.       /*
  674.        * The next two messages are handled so that this application can
  675.        * participate in device sharing.  Since it opens the device as
  676.        * spareable device, other applications can gain control of the device.
  677.        * When this happens, we will receive a MM_MCIPASSDEVICE message.  We
  678.        * keep track of this device passing in the fPassedDevice Boolean
  679.        * variable.
  680.        *
  681.        * If we do not have access to the device when we receive an WM_ACTIVATE
  682.        * message, then we will issue an acquire device command to gain
  683.        * access to the device.
  684.        */
  685.  
  686.       case MM_MCIPASSDEVICE:
  687.          if (SHORT1FROMMP(mp2) == MCI_GAINING_USE)           /* GAINING USE */
  688.          {
  689.             fPassedDevice = FALSE;               /* Gaining control of device.*/
  690.             if (eState == ST_PLAYING)            /* If the file was playing   */
  691.             {
  692.                /*
  693.                 * Start play button animation.
  694.                 */
  695.                WinSendMsg( hwndPlayPB,           /* Play button handle        */
  696.                            GBM_ANIMATE,          /* Animation control         */
  697.                            MPFROMSHORT(TRUE),    /* Animation flag            */
  698.                            NULL );               /* Ignore return data        */
  699.             }
  700.          }
  701.          else                                                /* LOSING USE  */
  702.          {
  703.             fPassedDevice = TRUE;                /* Losing  control of device.*/
  704.             if (eState == ST_PLAYING)            /* If the file was playing   */
  705.             {
  706.                /*
  707.                 * Stop play button animation.
  708.                 */
  709.                WinSendMsg( hwndPlayPB,           /* Play button handle        */
  710.                            GBM_ANIMATE,          /* Animation control         */
  711.                            MPFROMSHORT(FALSE),   /* Animation flag            */
  712.                            NULL );               /* Ignore return data        */
  713.             }
  714.          }
  715.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  716.  
  717.       case WM_ACTIVATE:
  718.  
  719.          /* We use the WM_ACTIVATE message to participate in device sharing.
  720.           * We first check to see if this is an activate or a deactivate
  721.           * message (indicated by mp1).  Then, we check to see if we've passed
  722.           * control of the audio device.  If these conditions are true,
  723.           * then we issue an acquire device command to regain control of
  724.           * the device, since we're now the active window on the screen.
  725.           */
  726.          if ((BOOL)mp1 && fPassedDevice == TRUE)
  727.          {
  728.            /*
  729.             * To acquire the device, we will issue MCI_ACQUIREDEVICE
  730.             * command to the MCI.
  731.             */
  732.             SendString( hwnd, "acquire capsamp notify", 0 );
  733.          }
  734.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  735.  
  736.      case MM_MCIPOSITIONCHANGE:
  737.         /*
  738.          * This message will be returned (in mm time) to the application
  739.          * whenever the audio position changed. This time will be used to
  740.          * increment the audio position slider. This message is only
  741.          * generated during playback.
  742.          */
  743.         if ( eState == ST_PLAYING )
  744.         {
  745.            ulTime = (ULONG) LONGFROMMP(mp2);
  746.  
  747.            /*
  748.             * Get the new slider arm position and set it.
  749.             */
  750.            sArmPosition =
  751.                (SHORT) ( ( ulTime * ( sAudioArmRange - 1) ) / ulAudioLength );
  752.            WinSendMsg(
  753.               hwndAudioSlider,
  754.               SLM_SETSLIDERINFO,
  755.               MPFROM2SHORT( SMA_SLIDERARMPOSITION, SMA_RANGEVALUE ),
  756.               MPFROMSHORT( sArmPosition ));
  757.         }
  758.         return 0;
  759.  
  760.       case MM_MCINOTIFY:
  761.          /*
  762.           * This message is returned to an application when a device
  763.           * successfully completes a command that was issued with a NOTIFY
  764.           * flag, or when an error occurs with the command.
  765.           *
  766.           * This message returns two values. A user parameter (mp1) and
  767.           * the command message (mp2) that was issued. The low word of mp1
  768.           * is the Notification Message Code which indicates the status of the
  769.           * command like success or failure. The high word of mp2 is the
  770.           * Command Message which indicates the source of the command.
  771.           */
  772.          usNotifyCode    = (USHORT) SHORT1FROMMP( mp1);  /* low-word  */
  773.          usCommandMessage = (USHORT) SHORT2FROMMP( mp2); /* high-word */
  774.  
  775.          switch (usCommandMessage)
  776.          {
  777.             case MCI_PLAY:
  778.                switch (usNotifyCode)
  779.                {
  780.                   case MCI_NOTIFY_SUPERSEDED:
  781.                   case MCI_NOTIFY_ABORTED:
  782.                      /* we don't need to handle these messages. */
  783.                      break;
  784.  
  785.                   default:
  786.                      if (eState != ST_STOPPED)
  787.                      {
  788.                         /*
  789.                          * Set the audio slider to the end.
  790.                          */
  791.                         WinSendMsg(
  792.                            hwndAudioSlider,
  793.                            SLM_SETSLIDERINFO,
  794.                            MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE),
  795.                            MPFROMSHORT( sAudioArmRange - 1 ) );
  796.  
  797.                         /*
  798.                          * Hide the caption window and update the internal
  799.                          * state of the dialog box.
  800.                          */
  801.                         ccSendCommand( CC_STOP, MPFROMHWND(hwndCaption), 0);
  802.                         eState = ST_STOPPED;
  803.  
  804.                         /*
  805.                          * Stop the play button animation
  806.                          */
  807.                         WinSendMsg( hwndPlayPB,        /* Play button handle  */
  808.                                     GBM_ANIMATE,       /* Animation control   */
  809.                                     MPFROMSHORT(FALSE),/* Animation flag      */
  810.                                     NULL );            /* Ignore return data  */
  811.  
  812.                         if ( usNotifyCode != MCI_NOTIFY_SUCCESSFUL)
  813.                            /*
  814.                             * Notification error message. We need to display
  815.                             * the error message to the user.
  816.                             */
  817.                            ShowMCIErrorMessage( usNotifyCode);
  818.                      }
  819.                      break;
  820.                }
  821.                break;
  822.          }
  823.          return( (MRESULT) 0);
  824.  
  825.       default:
  826.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2));
  827.  
  828.    }  /* End of msg Switch */
  829.  
  830.    return( (MRESULT) FALSE);
  831.  
  832. } /* End of MainDlgProc */
  833.  
  834.  
  835. /*******************************************************************************
  836.  * Name        : SettingsDlgProc
  837.  *
  838.  * Description : This function allows you to change the properties of
  839.  *               caption window.
  840.  *
  841.  * Concepts    : Illustrates how to change the properties of the captioning
  842.  *               window.  The following properties of the caption window may
  843.  *               be changed using the CC_SET message via the ccSendCommand
  844.  *               API:
  845.  *                  - Text columns.
  846.  *                  - Text rows.
  847.  *                  - caption window background color.
  848.  *                  - Text color.
  849.  *                  - Caption window position in the main dialog box.
  850.  *
  851.  * MMPM/2 API's: None.
  852.  *
  853.  * Parameters  : hwnd - Handle for the Device dialog box.
  854.  *               msg  - Message received by the dialog box.
  855.  *               mp1  - Parameter 1 for the just received message.
  856.  *               mp2  - Parameter 2 for the just received message.
  857.  *
  858.  * Return      : 0 or the result of default processing.
  859.  *
  860.  ******************************************************************************/
  861. MRESULT EXPENTRY SettingsDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  862. {
  863.    PCHAR              buffer;              /* to store the spin button text   */
  864.    CC_SET_PARMS       ccSetParms;          /* set parms for CC_SET            */
  865.    ULONG              ulArrayIndexValue=0; /* for spin button return value    */
  866.    CC_STATUS_PARMS    ccStatusParms;       /* status parms for CC_STATUS      */
  867.    HPS                hps;                 /* handle to caption window PS     */
  868.  
  869.    switch( msg )
  870.    {
  871.       case WM_INITDLG :
  872.          /*
  873.           * Load all the required option strings from the resource file.
  874.           */
  875.          WinLoadString( hab, (HMODULE)NULL, IDS_WHITE,  OPTIONSLEN, szWhite  );
  876.          WinLoadString( hab, (HMODULE)NULL, IDS_YELLOW, OPTIONSLEN, szYellow );
  877.          WinLoadString( hab, (HMODULE)NULL, IDS_GRAY,   OPTIONSLEN, szGray   );
  878.          WinLoadString( hab, (HMODULE)NULL, IDS_BLUE,   OPTIONSLEN, szBlue   );
  879.          WinLoadString( hab, (HMODULE)NULL, IDS_BLACK,  OPTIONSLEN, szBlack  );
  880.          WinLoadString( hab, (HMODULE)NULL, IDS_RED,    OPTIONSLEN, szRed    );
  881.          WinLoadString( hab, (HMODULE)NULL, IDS_CENTER, OPTIONSLEN, szCenter );
  882.          WinLoadString( hab, (HMODULE)NULL, IDS_LEFT,   OPTIONSLEN, szLeft   );
  883.          WinLoadString( hab, (HMODULE)NULL, IDS_RIGHT,  OPTIONSLEN, szRight  );
  884.  
  885.          /*
  886.           * Query the size of the main window for further use.  This is
  887.           * needed to calculate the correct position of the caption window
  888.           * inside the main window.
  889.           */
  890.          WinQueryWindowRect ( hwndMainDialogBox, &rclMain );
  891.  
  892.          /*
  893.           * Get caption window presentation space.  Get the font metrics
  894.           * for the default font for this presentation space.  This data
  895.           * is needed to calculate the caption window positioning inside
  896.           * the main window.
  897.           */
  898.          hps = WinGetPS( hwndCaption );
  899.          GpiQueryFontMetrics( hps, (LONG) sizeof (fm), &fm );
  900.  
  901.          /*
  902.           * Initialize the Spinbuttons.
  903.           */
  904.          InitializeSpinButton(hwnd);
  905.          return( (MRESULT) 0 );
  906.  
  907.       case WM_CLOSE :
  908.           WinDismissDlg( hwnd, TRUE );      /* Close the Dialog box.          */
  909.           return( 0 );
  910.  
  911.       case WM_HELP :
  912.          /*
  913.           * The dialog window has received a request for help from the user,
  914.           * i.e., the Help pushbutton was pressed.  Send the HM_DISPLAY_HELP
  915.           * message to the Help Instance with the IPF resource identifier
  916.           * for the correct HM panel.  This will show the help panel for this
  917.           * dialog box.
  918.           */
  919.          WinSendMsg( hwndHelpInstance,
  920.                      HM_DISPLAY_HELP,
  921.                      MPFROMSHORT(2),
  922.                      MPFROMSHORT(HM_RESOURCEID));
  923.          return( 0 );
  924.  
  925.       case WM_COMMAND :
  926.          switch( SHORT1FROMMP( mp1 ) )
  927.          {
  928.             case IDC_OK_PB :           /* user selected "OK" pushbutton */
  929.               /*
  930.                * Initialize the CC_SET_PARMS with zeros.
  931.                */
  932.               memset( &ccSetParms, 0, sizeof(ccSetParms));
  933.  
  934.               /*
  935.                * Query the background color spin button. The array index
  936.                * value will be returned in ulArrayIndexValue variable.
  937.                */
  938.               WinSendDlgItemMsg(
  939.                  hwnd,
  940.                  IDC_BACKGROUND_COLOR_SB,
  941.                  SPBM_QUERYVALUE,
  942.                  (MPARAM) &ulArrayIndexValue,
  943.                  MPFROMLONG(0));
  944.  
  945.               /*
  946.                * Get the actual value.
  947.                */
  948.               buffer = backgroundColor[ulArrayIndexValue];
  949.  
  950.               /*
  951.                * Initialize the CC_SET_PARMS data structure with the
  952.                * appropriate information.
  953.                */
  954.               if (stricmp(buffer, szYellow) == 0)
  955.                  ccSetParms.ulBackgroundColor = CLR_YELLOW;
  956.               else
  957.               if (stricmp(buffer, szWhite) == 0)
  958.                  ccSetParms.ulBackgroundColor = CLR_WHITE;
  959.               else
  960.                  ccSetParms.ulBackgroundColor = CLR_DARKGRAY;
  961.  
  962.               /*
  963.                * Query the text columns spin button. The array index
  964.                * value will be returned in ulArrayIndexValue variable.
  965.                */
  966.               WinSendDlgItemMsg(
  967.                   hwnd,
  968.                   IDC_TEXT_COLUMNS_SB,
  969.                   SPBM_QUERYVALUE,
  970.                   (MPARAM) &ulArrayIndexValue,
  971.                   MPFROMLONG(0));
  972.  
  973.               /*
  974.                * Get the actual value.
  975.                */
  976.               ccSetParms.ulColumns=(ULONG)atoi(textColumns[ulArrayIndexValue]);
  977.  
  978.               /*
  979.                * Query the text color spin buttons.
  980.                */
  981.               WinSendDlgItemMsg(
  982.                  hwnd,
  983.                  IDC_TEXT_COLOR_SB,
  984.                  SPBM_QUERYVALUE,
  985.                  (MPARAM) &ulArrayIndexValue,
  986.                  MPFROMLONG(0));
  987.  
  988.               /*
  989.                * Get the actual value.
  990.                */
  991.               buffer = textColor[ulArrayIndexValue];
  992.  
  993.               /*
  994.                * Initialize the CC_SET_PARMS data structure with the
  995.                * appropriate information.
  996.                */
  997.               if (stricmp(buffer, szBlue) == 0)
  998.                  ccSetParms.ulTextColor = CLR_DARKBLUE;
  999.               else
  1000.               if (stricmp(buffer, szRed) == 0)
  1001.                  ccSetParms.ulTextColor = CLR_RED;
  1002.               else
  1003.                  ccSetParms.ulTextColor = CLR_BLACK;
  1004.  
  1005.               /*
  1006.                * Query the window position spin buttons. The array index
  1007.                * value will be returned in ulArrayIndexValue variable.
  1008.                */
  1009.               WinSendDlgItemMsg(
  1010.                  hwnd,
  1011.                  IDC_WINDOW_POSITION_SB,
  1012.                  SPBM_QUERYVALUE,
  1013.                  (MPARAM) &ulArrayIndexValue,
  1014.                  MPFROMLONG(0));
  1015.  
  1016.               /*
  1017.                * Get the actual value.
  1018.                */
  1019.               buffer = windowPosition[ulArrayIndexValue];
  1020.  
  1021.               /*
  1022.                * Calculate the correct caption window position inside the
  1023.                * main window using fm.lAveCharaWidth and initialize the
  1024.                * CC_SET_PARMS data structure with the appropriate information.
  1025.                */
  1026.               if (stricmp(buffer, szLeft) == 0)
  1027.               {
  1028.                  ccSetParms.ulXposition = (ULONG) 5;
  1029.                  ccSetParms.ulYposition = (ULONG) 5;
  1030.               }
  1031.               else
  1032.               if (stricmp(buffer, szCenter) == 0)
  1033.               {
  1034.                  if (ccSetParms.ulColumns == 15)
  1035.                  {
  1036.                     ccSetParms.ulXposition = (ULONG)
  1037.                           (rclMain.xRight - fm.lAveCharWidth * 15 ) / 2;
  1038.                     ccSetParms.ulYposition = (ULONG) 5;
  1039.                  }
  1040.                  else
  1041.                  if (ccSetParms.ulColumns == 35)
  1042.                  {
  1043.                     ccSetParms.ulXposition = (ULONG)
  1044.                           (rclMain.xRight - fm.lAveCharWidth * 35 ) / 2;
  1045.                     ccSetParms.ulYposition = (ULONG) 5;
  1046.                  }
  1047.                  else
  1048.                  {
  1049.                     ccSetParms.ulXposition = (ULONG)
  1050.                           (rclMain.xRight - fm.lAveCharWidth * 50 ) / 2;
  1051.                     ccSetParms.ulYposition = (ULONG) 5;
  1052.                  }
  1053.               }
  1054.               else
  1055.               {
  1056.                  if (ccSetParms.ulColumns == 15)
  1057.                  {
  1058.                     ccSetParms.ulXposition = (ULONG)
  1059.                          (rclMain.xRight - fm.lAveCharWidth * 15 ) - 5;
  1060.                     ccSetParms.ulYposition = (ULONG) 5;
  1061.                  }
  1062.                  else
  1063.                  if (ccSetParms.ulColumns == 35)
  1064.                  {
  1065.                     ccSetParms.ulXposition = (ULONG)
  1066.                          (rclMain.xRight - fm.lAveCharWidth * 35 ) - 5;
  1067.                     ccSetParms.ulYposition = (ULONG) 5;
  1068.                  }
  1069.                  else
  1070.                  {
  1071.                     ccSetParms.ulXposition = (ULONG)
  1072.                          (rclMain.xRight - fm.lAveCharWidth * 50 ) - 5;
  1073.                     ccSetParms.ulYposition = (ULONG) 5;
  1074.                  }
  1075.               }
  1076.  
  1077.               /*
  1078.                * Query the text rows spin button. The array index
  1079.                * value will be returned in ulArrayIndexValue variable.
  1080.                */
  1081.               WinSendDlgItemMsg(
  1082.                  hwnd,
  1083.                  IDC_TEXT_ROWS_SB,
  1084.                  SPBM_QUERYVALUE,
  1085.                  (MPARAM) &ulArrayIndexValue,
  1086.                  MPFROMLONG(0));
  1087.  
  1088.               /*
  1089.                * Get the actual value and initialize the CC_SET_PARMS
  1090.                * data structure with the appropriate information.
  1091.                */
  1092.               ccSetParms.ulRows = (ULONG) atoi( textRows[ulArrayIndexValue] );
  1093.  
  1094.               /*
  1095.                * Issue the CC_SET command with the ccSendCommand and close
  1096.                * the dialog box.
  1097.                */
  1098.               ccSendCommand(CC_SET, MPFROMHWND(hwndCaption), &ccSetParms);
  1099.               WinDismissDlg( hwnd, TRUE );
  1100.  
  1101.               return( 0 );
  1102.  
  1103.             case DID_CANCEL:
  1104.             case IDC_CANCEL_PB:
  1105.  
  1106.                WinDismissDlg( hwnd, TRUE ); /* Close the Dialog box.          */
  1107.  
  1108.                return( 0 );
  1109.  
  1110.          }  /* End of Command Switch */
  1111.  
  1112.          return( 0 );
  1113.  
  1114.       default:
  1115.          return( WinDefDlgProc( hwnd, msg, mp1, mp2 ) );
  1116.  
  1117.    }  /* End of Switch */
  1118.  
  1119.    return( (MRESULT) FALSE );
  1120.  
  1121. } /* End of SettingsDlgProc */
  1122.  
  1123.  
  1124. /******************************************************************************
  1125.  * Name         :  OpenTheFile
  1126.  *
  1127.  * Description  :  This procedure will Open the audio device with a specific
  1128.  *                 file loaded, if the audio device is not already opened.
  1129.  *                 If the audio device is open, an audio file will be loaded
  1130.  *                 onto it.
  1131.  *
  1132.  * Concepts     :  - Open a device using the MCI interface.
  1133.  *                 - Loading a file into an already open device.
  1134.  *
  1135.  * MMPM/2 API's :  mciSendString
  1136.  *                    - open
  1137.  *                    - load
  1138.  *
  1139.  * Parameters   :  hwnd  - Handle for the Main dialog box.
  1140.  *
  1141.  * Return       :  TRUE  -  if the operation was initiated without error.
  1142.  *                 FALSE -  if an error occurred.
  1143.  *
  1144.  ******************************************************************************/
  1145. BOOL OpenTheFile( HWND hwnd )
  1146. {
  1147.  
  1148.    /*
  1149.     * Change pointer to a waiting pointer first, since this might take a
  1150.     * couple of seconds.
  1151.     */
  1152.    WinSetPointer( HWND_DESKTOP, hptrWait );
  1153.  
  1154.    if (! DoesFileExist( "CAPSAMP.WAV" ))
  1155.    {
  1156.       MessageBox( IDS_CANNOT_FIND_AUDIO_FILE,              /* ID of the message          */
  1157.                   MB_CANCEL | MB_ERROR  | MB_MOVEABLE);    /* style         */
  1158.       return( FALSE );
  1159.    }
  1160.  
  1161.    if (! fDeviceOpen )
  1162.    /* If this is the first time thru this routine, then we need to open
  1163.     * the device.
  1164.     */
  1165.    {
  1166.       /*
  1167.        * To open the device, we will issue MCI_OPEN command to the MCI.
  1168.        */
  1169.       if ( SendString(
  1170.                hwnd,
  1171.                "open capsamp.wav alias capsamp wait shareable readonly",
  1172.                0 ) )
  1173.       {
  1174.          /*
  1175.           * Open success, set the flag to indicate that next time thru this
  1176.           * routine we do not need to open the device.
  1177.           * Also, since the file's now open, we can set up the audio slider.
  1178.           */
  1179.          fDeviceOpen = TRUE;
  1180.          SetAudioSliderPosition(hwnd);
  1181.       }
  1182.       else
  1183.          return( FALSE );
  1184.    }
  1185.    else
  1186.    {
  1187.       /*
  1188.        * The device is already open,
  1189.        * so we only need to load the appropriate file onto the device.
  1190.        *
  1191.        * To load the audio file into the device, we will issue MCI_LOAD
  1192.        * command to the MCI.
  1193.        */
  1194.       if (!SendString(hwnd, "load capsamp capsamp.wav wait readonly", 0))
  1195.          return( FALSE );
  1196.    }
  1197.    /*
  1198.     * Now that we're done here, change the pointer back to the arrow.
  1199.     */
  1200.    WinSetPointer ( HWND_DESKTOP, hptrArrow );
  1201.  
  1202.    return( TRUE );
  1203.  
  1204. }  /* end of OpenTheFile */
  1205.  
  1206. /******************************************************************************
  1207.  * Name         :  SetAudioSliderPosition
  1208.  *
  1209.  * Description  :  This routine queries the length of the audio file, sets
  1210.  *                 up the audio slider information and resets the slider
  1211.  *                 position to 0.  Its called each time the user plays the
  1212.  *                 audio file.
  1213.  *
  1214.  * Concepts     :  Query the length of the audio file using MCI interface.
  1215.  *
  1216.  * MMPM/2 API's :  mciSendString
  1217.  *                    - status
  1218.  *
  1219.  * Parameters   :  hwnd - Handle for the Main dialog box.
  1220.  *
  1221.  * Return       :  none
  1222.  *
  1223.  ******************************************************************************/
  1224. VOID  SetAudioSliderPosition( HWND hwnd )
  1225. {
  1226.     MRESULT mresult;
  1227.  
  1228.     /*
  1229.      * To get the length of the audio file, we will issue MCI_STATUS
  1230.      * command to the MCI. The length of the audio file will be returned
  1231.      * in the szReturn parameter of the mciSendString API, which is in the
  1232.      * SendString routine.
  1233.      */
  1234.     SendString( hwnd, "status capsamp length wait", 0 );
  1235.  
  1236.     /*
  1237.      * Get the audio file length.
  1238.      */
  1239.     ulAudioLength  = atol(szReturn);
  1240.  
  1241.     /*
  1242.      * Set the Audio position slider at the zero position.
  1243.      */
  1244.     WinSendMsg( hwndAudioSlider,
  1245.                 SLM_SETSLIDERINFO,
  1246.                 MPFROM2SHORT( SMA_SLIDERARMPOSITION, SMA_RANGEVALUE ),
  1247.                 MPFROMSHORT( 0 ) );
  1248.  
  1249.     mresult = WinSendMsg( hwndAudioSlider,
  1250.                           SLM_QUERYSLIDERINFO,
  1251.                           MPFROM2SHORT( SMA_SLIDERARMPOSITION, SMA_RANGEVALUE ),
  1252.                           0 );
  1253.     sAudioArmRange = SHORT2FROMMP( (MPARAM) mresult );
  1254.  
  1255.     return;
  1256. }
  1257.  
  1258. /*************************************************************************
  1259.  * Name         :  PlayTheAudio
  1260.  *
  1261.  * Description  :  This procedure will begin the playing of an audio file.
  1262.  *                 It is invoked when the user selects the Play pushbutton
  1263.  *                 on the application's main window.
  1264.  *
  1265.  * Concepts     :  Playing a audio file using the MCI interface.
  1266.  *
  1267.  * MMPM/2 API's :  mciSendString
  1268.  *                    - play
  1269.  *
  1270.  * Parameters   :  hwnd - Handle for the Main dialog box.
  1271.  *
  1272.  * Return       :  TRUE  -  if the operation was initiated without error.
  1273.  *                 FALSE -  if an error occurred.
  1274.  *
  1275.  ******************************************************************************/
  1276. BOOL PlayTheAudio( HWND hwnd)
  1277. {
  1278.  
  1279.  
  1280.    /*
  1281.     * Seek the audio to the beginning. In this sample program we are always
  1282.     * going to play the audio from the beginning of the file.
  1283.     */
  1284.    if (!SeekTheAudio())
  1285.       return( FALSE );
  1286.  
  1287.    eState = ST_PLAYING;                      /* set state to PLAYING          */
  1288.    SetAudioVolume();                         /* set the starting volume       */
  1289.  
  1290.    /*
  1291.     * To play the audio, we will issue an MCI_PLAY command via mciSendString.
  1292.     * A MM_MCINOTIFY message will be sent to the window specified in
  1293.     * SendString when the operation is completed.
  1294.     */
  1295.    if ( SendString( hwnd, "play capsamp notify", UP_PLAY ) )
  1296.    {
  1297.       /*
  1298.        * Start the play button animation
  1299.        */
  1300.       WinSendMsg( hwndPlayPB,                 /* Play push button handle      */
  1301.                   GBM_ANIMATE,                /* Animation control            */
  1302.                   MPFROMSHORT(TRUE),          /* Animation flag               */
  1303.                   NULL );                     /* Ignore return data           */
  1304.    }
  1305.  
  1306.    return( TRUE );
  1307.  
  1308. }  /* end of PlayTheAudio */
  1309.  
  1310. /*************************************************************************
  1311.  * Name         :  ResumeTheAudio
  1312.  *
  1313.  * Description  :  This procedure will resume the playing of the audio
  1314.  *                 has been paused.
  1315.  *
  1316.  * Concepts     :  Resuming the audio using MCI interface.
  1317.  *
  1318.  * MMPM/2 API's :  mciSendString
  1319.  *                    - resume
  1320.  *
  1321.  * Parameters   :  none.
  1322.  *
  1323.  * Return       :  none.
  1324.  *
  1325.  *************************************************************************/
  1326. VOID ResumeTheAudio( VOID )
  1327. {
  1328.    /*
  1329.     * To resume the audio, we will issue an MCI_RESUME command via
  1330.     * MciSendString.
  1331.     */
  1332.  
  1333.    if ( SendString( (HWND)NULL, "resume capsamp wait", 0 ) )
  1334.    {
  1335.       /*
  1336.        * Start the play button animation and update the internal state of
  1337.        * the dialog box.
  1338.        */
  1339.       WinSendMsg( hwndPlayPB,                    /* Play push button handle   */
  1340.                   GBM_ANIMATE,                   /* Animation control         */
  1341.                   MPFROMSHORT(TRUE),             /* Animation flag            */
  1342.                   NULL );                        /* Ignore return data        */
  1343.       eState = ST_PLAYING;
  1344.       SetAudioVolume();
  1345.    }
  1346.  
  1347.    return;
  1348. }  /* End of ResumeTheAudio */
  1349.  
  1350. /******************************************************************************
  1351.  * Name         :  PauseTheAudio
  1352.  *
  1353.  * Description  :  This procedure will pause audio that is playing.
  1354.  *
  1355.  * Concepts     :  Pausing the audio using MCI interface.
  1356.  *
  1357.  * MMPM/2 API's :  mciSendString
  1358.  *                    - pause
  1359.  *
  1360.  * Parameters   :  none.
  1361.  *
  1362.  * Return       :  none.
  1363.  *
  1364.  ******************************************************************************/
  1365. VOID PauseTheAudio( VOID )
  1366. {
  1367.  
  1368.    /*
  1369.     * To pause the Audio, we will issue MCI_PAUSE command via mciSendString.
  1370.     */
  1371.    if ( SendString( (HWND)NULL, "pause capsamp wait", 0 ) )
  1372.    {
  1373.       /*
  1374.        * If pause was successful, stop the play button animation and
  1375.        * update the internal state of the dialog box.
  1376.        */
  1377.       WinSendMsg( hwndPlayPB,          /* Dialog window handle */
  1378.                   GBM_ANIMATE,         /* Animation control    */
  1379.                   MPFROMSHORT(FALSE),  /* Animation flag       */
  1380.                   NULL );              /* Ignore return data   */
  1381.       eState = ST_PAUSED;
  1382.    }
  1383.  
  1384.    return;
  1385. }  /* end of PauseTheAudio */
  1386.  
  1387. /******************************************************************************
  1388.  * Name         :  SeekTheAudio
  1389.  *
  1390.  * Description  :  This procedure will Seek to the position in an audio file.
  1391.  *                 Specified by the audio position slider on the main window.
  1392.  *
  1393.  * Concepts     :  Changing the current position in an audio file using the
  1394.  *                 MCI interface.
  1395.  *
  1396.  * MMPM/2 API's :  mciSendString
  1397.  *                    - seek
  1398.  *
  1399.  * Parameters   :  none
  1400.  *
  1401.  * Return       :  TRUE  -  if the operation was initiated without error.
  1402.  *                 FALSE -  if an error occurred.
  1403.  *
  1404.  ******************************************************************************/
  1405. BOOL SeekTheAudio( VOID )
  1406. {
  1407.    MRESULT mresultSlider;              /* return audio slider current position*/
  1408.    SHORT   sArmPosition;               /* Read the slider position            */
  1409.    ULONG   ulStartPos;                 /* audio stating position              */
  1410.    CHAR    szPosition[5] = "";         /* to store the starting position      */
  1411.    CHAR    szCommandString[CCHMAXPATH] =
  1412.              "seek capsamp to ";       /* string command to mciSendString     */
  1413.  
  1414.  
  1415.    /*
  1416.     * Query the slider position to determine the start of the audio play.
  1417.     */
  1418.    mresultSlider =
  1419.           WinSendMsg( hwndAudioSlider,
  1420.                       SLM_QUERYSLIDERINFO,
  1421.                       MPFROM2SHORT( SMA_SLIDERARMPOSITION, SMA_RANGEVALUE ),
  1422.                       0 );
  1423.    sArmPosition = SHORT1FROMMP ( (MPARAM) mresultSlider );
  1424.  
  1425.  
  1426.    if ( sArmPosition >=  ( sAudioArmRange - 1 ) )
  1427.    {
  1428.       /*
  1429.        * Slider is at the extreme right of its range, start playing from
  1430.        * the beginning.
  1431.        */
  1432.       ulStartPos = 0;
  1433.       WinSendMsg( hwndAudioSlider,
  1434.                   SLM_SETSLIDERINFO,
  1435.                   MPFROM2SHORT ( SMA_SLIDERARMPOSITION, SMA_RANGEVALUE ),
  1436.                   MPFROMSHORT  ( 0 ) );
  1437.    }
  1438.    else
  1439.       /*
  1440.        * Slider is NOT at the extreme right of its range, calculate the
  1441.        * starting position.
  1442.        */
  1443.       ulStartPos = (ULONG) ( ( sArmPosition * ulAudioLength ) / ( sAudioArmRange - 1 ) );
  1444.  
  1445.    _itoa(ulStartPos, szPosition, 10);
  1446.    strcat( szCommandString, szPosition);
  1447.    strcat( szCommandString, " ");
  1448.    strcat( szCommandString, "wait");
  1449.  
  1450.    /*
  1451.     * To seek the audio file, we will issue MCI_SEEK command to the MCI.
  1452.     */
  1453.    if (! SendString( (HWND)NULL, szCommandString, 0 ) )
  1454.       return( FALSE );
  1455.  
  1456.    return( TRUE );
  1457.  
  1458. }  /* end of SeekTheAudio */
  1459. /******************************************************************************
  1460.  * Name         :  StartTheCaption
  1461.  *
  1462.  * Description  :  This procedure will check the status of MMPM/2's captioning
  1463.  *                 flag.  If the caption flag is turned off, indicating that
  1464.  *                 user does not wish to see captioning, then application will
  1465.  *                 not invoke the Caption DLL.  If the caption flag is turned
  1466.  *                 on, then this routine will issue an API to the Caption DLL
  1467.  *                 to begin captioning.
  1468.  *
  1469.  * Concepts     :  Start captioning the file using the API's provided by the
  1470.  *                 Caption DLL.
  1471.  *
  1472.  * MMPM/2 API's :  mciQuerySysValue
  1473.  *                 mciSendString
  1474.  *                    - setpositionadvise
  1475.  *
  1476.  * Parameters   :  hwnd - Handle for the Main dialog box.
  1477.  *
  1478.  * Return       :  nothing.
  1479.  *
  1480.  ******************************************************************************/
  1481. VOID StartTheCaption( HWND hwnd )
  1482. {
  1483.     CC_START_PARMS   csp;             /* Closed-captioning start parameters   */
  1484.     ULONG            ulReturn;        /* Return value from ccSendCommand      */
  1485.     BOOL             bCCflag;         /* Value used in MMPM/2 caption switch. */
  1486.  
  1487.     /*
  1488.      * Test the MMPM/2 Closed Captioning Flag.  If it's ON then the user
  1489.      * wants to see captioning.  If it's OFF the user does not want to see
  1490.      * captioning.
  1491.      */
  1492.     mciQuerySysValue ( MSV_CLOSEDCAPTION, &bCCflag );
  1493.  
  1494.     if ( ! bCCflag )
  1495.     {
  1496.        /*
  1497.         * Close caption flag is OFF. The text window will not be displayed.
  1498.         * Issue a set position advise command. This will cause position
  1499.         * change messages to be sent to our window procedure.  This will
  1500.         * enable us to maintain the audio slider.
  1501.         */
  1502.        SendString(
  1503.            hwnd,
  1504.            "setpositionadvise capsamp on every 1500 notify",
  1505.            0 );
  1506.        return;
  1507.     }
  1508.  
  1509.     /*
  1510.      * Close caption flag is ON.
  1511.      * Fill in the CC_START_PARMS structure and the call ccSendCommand
  1512.      * to make the captioning window visible.  The hwndOwner field holds
  1513.      * the window handle that we want the Caption DLL to send the position
  1514.      * change messages to, when it is done processing them.
  1515.      */
  1516.  
  1517.     csp.pszDeviceName    = (PSZ)   "capsamp";        /* alias name            */
  1518.     csp.pszCaptionFile   = (PSZ)   "CAPSAMP._CC";    /* File name to use      */
  1519.     csp.hwndOwner        =  hwnd;                    /* for position change   */
  1520.  
  1521.     ulReturn = ccSendCommand ( CC_START, MPFROMHWND(hwndCaption), &csp );  /* Start captioning      */
  1522.  
  1523.     /*
  1524.      * If an error from ccSendCommand, stop the device and display an
  1525.      * error message.
  1526.      */
  1527.     if (ulReturn)
  1528.     {
  1529.        StopTheDevice();
  1530.        switch(ulReturn)
  1531.        {
  1532.           case CCERR_UNEXPECTED_EOF:
  1533.              MessageBox( IDS_UNEXPECTED_EOF,        /* ID of the message      */
  1534.                          MB_CANCEL | MB_ERROR  | MB_MOVEABLE);    /* style         */
  1535.              break;
  1536.           case CCERR_FILE_FORMAT:
  1537.              MessageBox( IDS_INVALID_FILE_FORMAT,   /* ID of the message      */
  1538.                          MB_CANCEL | MB_ERROR  | MB_MOVEABLE);    /* style         */
  1539.              break;
  1540.           case CCERR_TOO_MANY_LINES:
  1541.              MessageBox( IDS_TOO_MANY_LINES,        /* ID of the message      */
  1542.                          MB_CANCEL | MB_ERROR  | MB_MOVEABLE);    /* style         */
  1543.              break;
  1544.           case ERROR_FILE_NOT_FOUND:
  1545.           case ERROR_OPEN_FAILED:
  1546.              MessageBox( IDS_INVALID_FILE_NAME,     /* ID of the message      */
  1547.                          MB_CANCEL | MB_ERROR  | MB_MOVEABLE);    /* style         */
  1548.              break;
  1549.  
  1550.           default:
  1551.              StopTheDevice();
  1552.              ShowMCIErrorMessage(ulReturn);
  1553.              break;
  1554.        }
  1555.     }
  1556.  
  1557.     return;
  1558. }
  1559. /******************************************************************************
  1560.  * Name         :  StopTheDevice
  1561.  *
  1562.  * Description  :  This procedure will stop the device that is playing or
  1563.  *                 recording.
  1564.  *
  1565.  * Concepts     :  Stopping a device using the MCI interface.
  1566.  *
  1567.  * MMPM/2 API's :  mciSendString
  1568.  *                    - stop
  1569.  *
  1570.  * Parameters   :  none
  1571.  *
  1572.  * Return       :  nothing.
  1573.  *
  1574.  ******************************************************************************/
  1575. VOID StopTheDevice( VOID )
  1576. {
  1577.  
  1578.    /*
  1579.     * To stop the device , we will issue an string command using mciSendString.
  1580.     * This stop command is done for the alias.
  1581.     */
  1582.    if (SendString( (HWND)NULL, "stop capsamp wait", 0 ) )
  1583.    {
  1584.       if (eState == ST_PLAYING)
  1585.          /*
  1586.           * Stop the play button animation
  1587.           */
  1588.          WinSendMsg( hwndPlayPB,                 /* Play push button handle   */
  1589.                      GBM_ANIMATE,                /* Animation control         */
  1590.                      MPFROMSHORT(FALSE),         /* Animation flag            */
  1591.                      NULL );                     /* Ignore return data        */
  1592.          eState = ST_STOPPED;
  1593.    }
  1594.  
  1595.    return;
  1596. }  /* end of StopTheDevice */
  1597.  
  1598.  
  1599. /*************************************************************************
  1600.  * Name         :  CloseTheDevice
  1601.  *
  1602.  * Description  :  This procedure will close the audio device and close the
  1603.  *                 captioning system.
  1604.  *
  1605.  * Concepts     :  Closing a device using MCI interface.
  1606.  *
  1607.  * MMPM/2 API's :  mciSendString
  1608.  *                    - close
  1609.  *
  1610.  * Parameters   :  None.
  1611.  *
  1612.  * Return       :  nothing.
  1613.  *
  1614.  ******************************************************************************/
  1615. VOID CloseTheDevice( VOID)
  1616. {
  1617.  
  1618.    /*
  1619.     * To stop the device , we will issue an string command using mciSendString.
  1620.     * This stop command is done for the alias.
  1621.     */
  1622.    if ( SendString( (HWND)NULL, "close capsamp wait", 0 ) )
  1623.       /*
  1624.        * Close the captioning system. This will release all the resources that
  1625.        * were allocated.
  1626.        */
  1627.       ccTerminate(hwndCaption);
  1628.  
  1629.    return;
  1630.  
  1631. }  /* end of CloseTheDevice */
  1632.  
  1633.  
  1634. /*************************************************************************
  1635.  * Name         :  SendString
  1636.  *
  1637.  * Description  :  This procedure will send string to MCI.
  1638.  *
  1639.  * Concepts     :
  1640.  *
  1641.  * MMPM/2 API's :  mciSendString
  1642.  *
  1643.  * Parameters   :  hwnd        - window handle.
  1644.  *                 pcMCIString - string command.
  1645.  *                 usUserParm  - user parameter.
  1646.  *
  1647.  * Return       :  TRUE  - if the operation was initiated without error.
  1648.  *                 FALSE - if an error occurred.
  1649.  *
  1650.  ******************************************************************************/
  1651. BOOL  SendString( HWND hwnd, PCHAR pcMCIString, USHORT usUserParm )
  1652. {
  1653.    LONG          lmciSendStringRC;    /* return value form mciSendString     */
  1654.  
  1655.  
  1656.    lmciSendStringRC =
  1657.        mciSendString( (PSZ)pcMCIString,
  1658.                       (PSZ)szReturn,
  1659.                       CCHMAXPATH,
  1660.                       (HWND)hwnd,
  1661.                       (USHORT)usUserParm );
  1662.  
  1663.    if (lmciSendStringRC != 0)
  1664.    {
  1665.       ShowMCIErrorMessage(lmciSendStringRC);
  1666.       return( FALSE );
  1667.    }
  1668.  
  1669.    return( TRUE );
  1670. }
  1671.  
  1672.  
  1673. /******************************************************************************
  1674.  * Name         :  MessageBox
  1675.  *
  1676.  * Description  :  This procedure will display messages for the application
  1677.  *                 based upon string IDs passed in.  The actual text will be
  1678.  *                 loaded from the string table in the resource.
  1679.  *
  1680.  * Concepts     :  None.
  1681.  *
  1682.  * MMPM/2 API's :  None.
  1683.  *
  1684.  * Parameters   :  usMessageID - ID of the message string
  1685.  *                 ulStyle     - Style of the message box (WinMessageBox)
  1686.  *
  1687.  * Return       :  TRUE  -  if the operation was initiated without error.
  1688.  *                 FALSE -  if an error occurred.
  1689.  *
  1690.  ******************************************************************************/
  1691. USHORT MessageBox( USHORT usMessageID, ULONG  ulStyle)
  1692. {
  1693.    CHAR     achMessage[LEN_ERROR_MESSAGE];
  1694.    USHORT   usResult;
  1695.  
  1696.    /*
  1697.     * Get the string from the Resource defined string table and show it
  1698.     * in the message box.
  1699.     */
  1700.    WinLoadString(
  1701.       hab,                             /* HAB for this dialog box.            */
  1702.       (HMODULE) NULL,                  /* Get the string from the .exe file.  */
  1703.       usMessageID,                     /* Which string to get.                */
  1704.       (SHORT) sizeof( achMessage),     /* The size of the buffer.             */
  1705.       achMessage );                    /* The buffer to place the string.     */
  1706.  
  1707.    usResult =
  1708.       WinMessageBox(
  1709.          HWND_DESKTOP,                 /* Parent handle of the message box.   */
  1710.          hwndMainDialogBox,            /* Owner handle of the message box.    */
  1711.          achMessage,                   /* String to show in the message box.  */
  1712.          achMsgBoxTitle,               /* Title to shown in the message box.  */
  1713.          (USHORT) ID_MESSAGEBOX,       /* Message Box Id.                     */
  1714.          ulStyle );                    /* The style of the message box.       */
  1715.  
  1716.    return( usResult );
  1717.  
  1718. }  /* End of MessageBox */
  1719.  
  1720.  
  1721. /******************************************************************************
  1722.  * Name         :  ShowMCIErrorMessage
  1723.  *
  1724.  * Description  :  This window procedure displays an MCI error message
  1725.  *                 based upon a ulError return code.  The MCI function
  1726.  *                 mciGetErrorString is used to convert the error code into
  1727.  *                 a text string and the title is pulled from the resource
  1728.  *                 based upon a string id.
  1729.  *
  1730.  * Concepts     :  Using mciGetErrorString to convert an error code into
  1731.  *                 a textual message.
  1732.  *
  1733.  * MMPM/2 API's :  mciGetErrorString
  1734.  *
  1735.  * Parameters   :  ulError  -  MCI error code.
  1736.  *
  1737.  * Return       :  nothing
  1738.  *
  1739.  ******************************************************************************/
  1740. VOID  ShowMCIErrorMessage( ULONG ulError)
  1741. {
  1742.    CHAR  achBuffer[LEN_ERROR_MESSAGE];
  1743.  
  1744.    switch(mciGetErrorString( ulError, (PSZ)achBuffer,   sizeof( achBuffer)))
  1745.    {
  1746.       case MCIERR_SUCCESS:
  1747.          /*
  1748.           * This is what we want.  We were able to use mciGetErrorString to
  1749.           * retrieve a textual error message we can show in a message box.
  1750.           */
  1751.          WinMessageBox( HWND_DESKTOP,
  1752.                         hwndMainDialogBox,
  1753.                         achBuffer,
  1754.                         achMsgBoxTitle,
  1755.                         (USHORT) ID_MESSAGEBOX,
  1756.                         MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  1757.          break;
  1758.  
  1759.       case MCIERR_INVALID_DEVICE_ID:
  1760.       case MCIERR_OUTOFRANGE:
  1761.       case MCIERR_INVALID_BUFFER:
  1762.       default:
  1763.          MessageBox( IDS_UNKNOWN,
  1764.                      MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  1765.          break;
  1766.    }
  1767.  
  1768.    return;
  1769.  
  1770. }  /* end of ShowMCIErrorMessage */
  1771.  
  1772.  
  1773. /******************************************************************************
  1774.  * Name         :  DoesFileExist
  1775.  *
  1776.  * Description  :  This helper function determines if a file with a given
  1777.  *                 file name exists.
  1778.  *
  1779.  * Concepts     :  Using MMIO interface to access a data file.
  1780.  *
  1781.  * MMPM/2 API's :  mmioOpen
  1782.  *                 mmioClose
  1783.  *
  1784.  * Parameters   :  pszFileName - The file name to be tested.
  1785.  *
  1786.  * Return       :  TRUE  -  if the a file exists matching szFilename
  1787.  *                 FALSE -  if the file does not exist
  1788.  *
  1789.  ******************************************************************************/
  1790. BOOL DoesFileExist( PSZ pszFileName )
  1791. {
  1792.    BOOL  bReturn;    /* function return value   */
  1793.    HMMIO hFile;      /* handle to file          */
  1794.  
  1795.  /*
  1796.   * Notice that these MMIO functions are analogous to the standard
  1797.   * C functions, fopen and fclose.
  1798.   */
  1799.  
  1800.    hFile = mmioOpen( pszFileName, (PMMIOINFO) NULL, MMIO_READ);
  1801.  
  1802.    if (hFile != (HMMIO) NULL)
  1803.    {
  1804.       mmioClose( hFile, 0);
  1805.       bReturn = TRUE;
  1806.    }
  1807.    else
  1808.       bReturn = FALSE;
  1809.  
  1810.    return( bReturn);
  1811. }
  1812.  
  1813. /******************************************************************************
  1814.  * Name         :  SetAudioVolume
  1815.  *
  1816.  * Description  :  This helper function sets the audio file volume based upon
  1817.  *                 the position of the volume slider.  The slider will be
  1818.  *                 queried and the audio file volume will be set.
  1819.  *
  1820.  * Concepts     :  Setting the volume of a device.
  1821.  *
  1822.  * MMPM/2 API's :  mciSendString
  1823.  *                    - set
  1824.  *
  1825.  * Parameters   :  none.
  1826.  *
  1827.  * Return       :  none.
  1828.  *
  1829.  ******************************************************************************/
  1830. VOID SetAudioVolume( VOID )
  1831. {
  1832.    LONG      lmciSendStringRC;             /* return value form mciSendString */
  1833.    CHAR      szVolume[4] = "";             /* to hold the volume level        */
  1834.    CHAR      szCommandString[CCHMAXPATH] = /* string command to MCI           */
  1835.                "set capsamp audio volume ";
  1836.  
  1837.  
  1838.    if ((!fPassedDevice) && eState==ST_PLAYING)
  1839.    {
  1840.       /*
  1841.        * To set the volume,  first, build the string command to the
  1842.        * MCI.  Then an MCI_SET command should be issued to the device
  1843.        * to perform the volume change.
  1844.        */
  1845.       _itoa(sVolumeLevel, szVolume, 10);
  1846.       strcat( szCommandString, szVolume);
  1847.       strcat( szCommandString, " ");
  1848.       strcat( szCommandString, "wait");
  1849.  
  1850.       lmciSendStringRC =
  1851.           mciSendString( (PSZ)szCommandString   ,
  1852.                          (PSZ)szReturn,
  1853.                          CCHMAXPATH,
  1854.                          (HWND)NULL,
  1855.                          (USHORT)NULL );
  1856.       if (lmciSendStringRC != 0)
  1857.          ShowMCIErrorMessage(lmciSendStringRC);
  1858.  
  1859.    }
  1860.    return;
  1861. }  /* end of SetAudioVolume */
  1862.  
  1863. /******************************************************************************
  1864.  *  Name         : InitializeSpinButton
  1865.  *
  1866.  *  Description  : Set the initial values for the spin button controls.
  1867.  *
  1868.  *  Concepts     :
  1869.  *
  1870.  *  MMPM/2 API's :
  1871.  *
  1872.  *  Parameters   : hwnd - Handle of the Settings dialog box.
  1873.  *
  1874.  *  Returns      : none
  1875.  *
  1876.  ******************************************************************************/
  1877. VOID InitializeSpinButton( HWND hwnd )
  1878. {
  1879.    CC_STATUS_PARMS ccStatusParms;         /* status parms for CC_STATUS_PARMS */
  1880.    USHORT          ulArrayIndexValue = 0; /* return value from the spin button*/
  1881.  
  1882.    /*
  1883.     * Insert the values into the spin buttons.
  1884.     */
  1885.    WinSendDlgItemMsg( hwnd,                    /* Handle to the dialog box    */
  1886.                       IDC_TEXT_COLUMNS_SB,     /* ID of the spin button       */
  1887.                       SPBM_SETARRAY,           /* Set the array of data       */
  1888.                       textColumns,             /* Array of values             */
  1889.                       MPFROMLONG(3) );         /* Number of items in the array*/
  1890.  
  1891.    WinSendDlgItemMsg( hwnd,
  1892.                       IDC_TEXT_ROWS_SB,
  1893.                       SPBM_SETARRAY,
  1894.                       textRows,
  1895.                       MPFROMLONG(3) );
  1896.  
  1897.    WinSendDlgItemMsg( hwnd,
  1898.                       IDC_BACKGROUND_COLOR_SB,
  1899.                       SPBM_SETARRAY,
  1900.                       backgroundColor,
  1901.                       MPFROMLONG(3) );
  1902.  
  1903.    WinSendDlgItemMsg( hwnd,
  1904.                       IDC_TEXT_COLOR_SB,
  1905.                       SPBM_SETARRAY,
  1906.                       textColor,
  1907.                       MPFROMLONG(3) );
  1908.  
  1909.    WinSendDlgItemMsg( hwnd,
  1910.                       IDC_WINDOW_POSITION_SB,
  1911.                       SPBM_SETARRAY,
  1912.                       windowPosition,
  1913.                       MPFROMLONG(3) );
  1914.    /*
  1915.     * Query the current status of the text columns.
  1916.     * The CC_STATUS returns the actual value in the ulReturn field.
  1917.     */
  1918.    ccStatusParms.ulItem = CC_STATUS_TEXT_COLUMNS;
  1919.    ccSendCommand( CC_STATUS, MPFROMHWND(hwndCaption), &ccStatusParms );
  1920.  
  1921.    /*
  1922.     * Get the index value for the ulReturn field.
  1923.     */
  1924.    if (ccStatusParms.ulReturn == 15)
  1925.       ulArrayIndexValue = 0;
  1926.    else
  1927.    if (ccStatusParms.ulReturn == 35)
  1928.       ulArrayIndexValue = 1;
  1929.    else
  1930.    if (ccStatusParms.ulReturn == 50)
  1931.       ulArrayIndexValue = 2;
  1932.  
  1933.    /*
  1934.     * Set the current index value in the spin button.
  1935.     */
  1936.    WinSendDlgItemMsg( hwnd,                         /* Handle to the dlg box  */
  1937.                       IDC_TEXT_COLUMNS_SB,          /* ID of the spin button  */
  1938.                       SPBM_SETCURRENTVALUE,         /* Set current index value*/
  1939.                       MPFROMLONG(ulArrayIndexValue),/* Current index value    */
  1940.                       NULL );                       /* Ignore                 */
  1941.    /*
  1942.     * Query the current status of the text rows.
  1943.     * The CC_STATUS returns the actual value in the ulReturn field.
  1944.     */
  1945.    ccStatusParms.ulItem = CC_STATUS_TEXT_ROWS;
  1946.    ccSendCommand( CC_STATUS, MPFROMHWND(hwndCaption), &ccStatusParms );
  1947.  
  1948.    /*
  1949.     * Get the index value for the ulReturn field.
  1950.     */
  1951.    if (ccStatusParms.ulReturn == 2)
  1952.       ulArrayIndexValue = 0;
  1953.    else
  1954.    if (ccStatusParms.ulReturn == 3)
  1955.       ulArrayIndexValue = 1;
  1956.    else
  1957.    if (ccStatusParms.ulReturn == 4)
  1958.       ulArrayIndexValue = 2;
  1959.  
  1960.    /*
  1961.     * Set the current index value in the spin button.
  1962.     */
  1963.    WinSendDlgItemMsg( hwnd,                         /* Handle to the dlg box  */
  1964.                       IDC_TEXT_ROWS_SB,             /* ID of the spin button  */
  1965.                       SPBM_SETCURRENTVALUE,         /* Set current index value*/
  1966.                       MPFROMLONG(ulArrayIndexValue),/* Current index value    */
  1967.                       NULL );                       /* Ignore                 */
  1968.    /*
  1969.     * Query the current status of the background color.
  1970.     * The CC_STATUS returns the actual value in the ulReturn field.
  1971.     */
  1972.    ccStatusParms.ulItem = CC_STATUS_BACKGROUND_COLOR;
  1973.    ccSendCommand( CC_STATUS, MPFROMHWND(hwndCaption), &ccStatusParms );
  1974.  
  1975.    /*
  1976.     * Get the index value for the ulReturn field.
  1977.     */
  1978.    if (ccStatusParms.ulReturn == CLR_WHITE)
  1979.       ulArrayIndexValue = 0;
  1980.    else
  1981.    if (ccStatusParms.ulReturn == CLR_YELLOW)
  1982.       ulArrayIndexValue = 1;
  1983.    else
  1984.    if (ccStatusParms.ulReturn == CLR_DARKGRAY)
  1985.       ulArrayIndexValue = 2;
  1986.  
  1987.    /*
  1988.     * Set the current index value in the spin button.
  1989.     */
  1990.    WinSendDlgItemMsg( hwnd,                         /* Handle to the dlg box  */
  1991.                       IDC_BACKGROUND_COLOR_SB,      /* ID of the spin button  */
  1992.                       SPBM_SETCURRENTVALUE,         /* Set current index value*/
  1993.                       MPFROMLONG(ulArrayIndexValue),/* Current index value    */
  1994.                       NULL );                       /* Ignore                 */
  1995.    /*
  1996.     * Query the current status of the text color.
  1997.     * The CC_STATUS returns the actual value in the ulReturn field.
  1998.     */
  1999.    ccStatusParms.ulItem = CC_STATUS_TEXT_COLOR;
  2000.    ccSendCommand( CC_STATUS, MPFROMHWND(hwndCaption), &ccStatusParms );
  2001.  
  2002.    /*
  2003.     * Get the index value for the ulReturn field.
  2004.     */
  2005.    if (ccStatusParms.ulReturn == CLR_DARKBLUE)
  2006.       ulArrayIndexValue = 0;
  2007.    else
  2008.    if (ccStatusParms.ulReturn == CLR_BLACK)
  2009.       ulArrayIndexValue = 1;
  2010.    else
  2011.    if (ccStatusParms.ulReturn == CLR_RED)
  2012.       ulArrayIndexValue = 2;
  2013.  
  2014.    /*
  2015.     * Set the current index value in the spin button.
  2016.     */
  2017.    WinSendDlgItemMsg( hwnd,                         /* Handle to the dlg box  */
  2018.                       IDC_TEXT_COLOR_SB,            /* ID of the spin button  */
  2019.                       SPBM_SETCURRENTVALUE,         /* Set current index value*/
  2020.                       MPFROMLONG(ulArrayIndexValue),/* Current index value    */
  2021.                       NULL );                       /* Ignore                 */
  2022.    /*
  2023.     * Query the current window position.
  2024.     * The CC_STATUS returns the actual value in the ulReturn field.
  2025.     */
  2026.    ccStatusParms.ulItem = CC_STATUS_X_POSITION;
  2027.    ccSendCommand( CC_STATUS, MPFROMHWND(hwndCaption), &ccStatusParms );
  2028.  
  2029.    /*
  2030.     * Get the index value for the ulReturn field.
  2031.     */
  2032.    if ((ccStatusParms.ulReturn==(rclMain.xRight - fm.lAveCharWidth * 15)/2) ||
  2033.        (ccStatusParms.ulReturn==(rclMain.xRight - fm.lAveCharWidth * 35)/2) ||
  2034.        (ccStatusParms.ulReturn==(rclMain.xRight - fm.lAveCharWidth * 50)/2) ||
  2035.        (ccStatusParms.ulReturn == (ULONG) 0 ))
  2036.       ulArrayIndexValue = 0;                            /* Lower Left         */
  2037.    else
  2038.    if (ccStatusParms.ulReturn == 5)
  2039.       ulArrayIndexValue = 1;                            /* Lower Center       */
  2040.    else
  2041.       ulArrayIndexValue = 2;                            /* Lower Right        */
  2042.  
  2043.    /*
  2044.     * Set the current index value in the spin button.
  2045.     */
  2046.    WinSendDlgItemMsg( hwnd,                         /* Handle to the dlg box  */
  2047.                       IDC_WINDOW_POSITION_SB,       /* ID of the spin button  */
  2048.                       SPBM_SETCURRENTVALUE,         /* Set current index value*/
  2049.                       MPFROMLONG(ulArrayIndexValue),/* Current index value    */
  2050.                       NULL );                       /* Ignore                 */
  2051.    return;
  2052. }
  2053.  
  2054. /*************************************************************************
  2055.  * Name         : InitializeHelp
  2056.  *
  2057.  * Description  : This procedure will set up the initial values in the
  2058.  *                global help structure.  This help structure will then
  2059.  *                be passed on to the Help Manager when the Help Instance
  2060.  *                is created.  The handle to the Help Instance will be
  2061.  *                kept for later use.
  2062.  *
  2063.  * Concepts     : None.
  2064.  *
  2065.  * MMPM/2 API's : None.
  2066.  *
  2067.  * Parameters   : None.
  2068.  *
  2069.  * Return       : None.
  2070.  *
  2071.  *************************************************************************/
  2072. VOID InitializeHelp( VOID )
  2073. {
  2074.  
  2075.    HELPINIT helpInit;                 /* Help initialization structure.          */
  2076.    CHAR     achHelpLibraryName[LEN_HELP_LIBRARY_NAME];
  2077.    CHAR     achHelpWindowTitle[LEN_HELP_WINDOW_TITLE];
  2078.  
  2079.    /*
  2080.     * Load the strings for the Help window title and library name.
  2081.     * Initialize the help structure and associate the help instance.
  2082.     */
  2083.    WinLoadString( hab,
  2084.                   (HMODULE) NULL,
  2085.                   IDS_HELP_WINDOW_TITLE,
  2086.                   (SHORT) sizeof( achHelpWindowTitle),
  2087.                   achHelpWindowTitle);
  2088.  
  2089.    WinLoadString( hab,
  2090.                   (HMODULE) NULL,
  2091.                   IDS_HELP_LIBRARY_NAME,
  2092.                   (SHORT) sizeof( achHelpLibraryName),
  2093.                   achHelpLibraryName);
  2094.  
  2095.    memset ( &helpInit, 0, sizeof(helpInit) );
  2096.    /*
  2097.     * Initialize the help structure.
  2098.     */
  2099.    helpInit.cb                 = sizeof( helpInit);  /* size of the help struc*/
  2100.    helpInit.ulReturnCode       = (ULONG) 0;          /* RC from HM init       */
  2101.    helpInit.pszTutorialName    = (PSZ) NULL;         /* No tutorial program   */
  2102.    helpInit.pszHelpWindowTitle = achHelpWindowTitle; /* The Help window title.*/
  2103.    helpInit.fShowPanelId       = (ULONG) 0;          /* help panel ID.        */
  2104.    helpInit.pszHelpLibraryName = achHelpLibraryName; /* library name          */
  2105.    helpInit.phtHelpTable       = (PVOID)(0xffff0000 | ID_AUDIO_HELPTABLE);
  2106.  
  2107.    /*
  2108.     * Create the Help Instance for IPF.
  2109.     * Give IPF the Anchor Block handle and address of the IPF initialization
  2110.     * structure, and check that creation of Help was a success.
  2111.     */
  2112.    hwndHelpInstance = WinCreateHelpInstance(
  2113.                          hab,                   /* Anchor Block Handle.       */
  2114.                          &helpInit );           /* Help Structure.            */
  2115.  
  2116.    if ( hwndHelpInstance == (HWND) NULL)
  2117.    {
  2118.       MessageBox( IDS_HELP_CREATION_FAILED,     /* ID of the message          */
  2119.                   MB_OK | MB_INFORMATION  | MB_MOVEABLE);    /* style         */
  2120.    }
  2121.    else
  2122.    {
  2123.       if ( helpInit.ulReturnCode)
  2124.       {
  2125.          WinDestroyHelpInstance( hwndHelpInstance);
  2126.          MessageBox( IDS_HELP_CREATION_FAILED,     /* ID of the message       */
  2127.                      MB_OK | MB_INFORMATION | MB_MOVEABLE);     /* style      */
  2128.       }
  2129.       else  /* help creation worked */
  2130.          WinAssociateHelpInstance(
  2131.             hwndHelpInstance,        /* The handle of the Help Instance.      */
  2132.             hwndFrame);              /* Associate to this dialog window.      */
  2133.    }  /* End of IF checking the creation of the Help Instance. */
  2134.  
  2135. }  /* End of InitializeHelp */
  2136.  
  2137. /*******************************************************************************
  2138.  * Name        : ProcuctInfoDlgProc
  2139.  *
  2140.  * Description : This function controls the product information dialog box.
  2141.  *
  2142.  * Concepts    : None.
  2143.  *
  2144.  * MMPM/2 API's: WinDestroySecondaryWindow
  2145.  *               WinDefSecondaryWindowProc
  2146.  *               WinInsertDefaultSize
  2147.  *
  2148.  * Parameters  : hwnd - Handle for the Include dialog box.
  2149.  *               msg  - Message received by the dialog box.
  2150.  *               mp1  - Parameter 1 for the just received message.
  2151.  *               mp2  - Parameter 2 for the just received message.
  2152.  *
  2153.  * Return      : 0 or the result of default processing.
  2154.  *
  2155.  ******************************************************************************/
  2156. MRESULT EXPENTRY ProductInfoDlgProc( HWND   hwnd,
  2157.                                      ULONG  msg,
  2158.                                      MPARAM mp1,
  2159.                                      MPARAM mp2 )
  2160. {
  2161.    switch( msg )
  2162.    {
  2163.      case WM_INITDLG :
  2164.          /*
  2165.           * Add Default Size menu item to system menu of the secondary window.
  2166.           */
  2167.          WinInsertDefaultSize(hwnd, "~DefaultSize");
  2168.  
  2169.          break;
  2170.  
  2171.      case WM_CLOSE :
  2172.          WinDestroySecondaryWindow( hwnd ); /* Close the Dialog box.          */
  2173.          return( 0 );
  2174.          break;
  2175.  
  2176.      case WM_DESTROY:
  2177.          hwndProductInfo = (HWND) 0;
  2178.          break;
  2179.  
  2180.      case WM_COMMAND :
  2181.          switch( SHORT1FROMMP( mp1 ) )
  2182.          {
  2183.             case DID_OK :
  2184.  
  2185.             case DID_CANCEL:
  2186.                WinDestroySecondaryWindow( hwnd ); /* Close the Dialog box.          */
  2187.                return( (MRESULT)TRUE);
  2188.             break;
  2189.          }  /* End of Command Switch */
  2190.  
  2191.    }  /* End of Switch */
  2192.  
  2193.    return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  2194.  
  2195. } /* End of ProductInfoDlgProc */
  2196.