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

  1. /******************************************************************************
  2.  * File Name    :  RECORDER.C
  3.  *
  4.  * Description  :  This file contains the C source code required for the
  5.  *                 Recorder sample program.
  6.  *
  7.  * Concepts     :  This sample program illustrates the concepts of recording
  8.  *                 audio data through the media control interface. It also
  9.  *                 illustrates how to change the characteristics of the audio
  10.  *                 recording and the audio device (such as bits per sample,
  11.  *                 samples per second, input level, input source, etc.)
  12.  *
  13.  * MMPM/2 API's :  List of all MMPM/2 API's that are used in
  14.  *                 this module
  15.  *
  16.  *                 mciSendCommand    MCI_OPEN
  17.  *                                   MCI_PLAY
  18.  *                                   MCI_RECORD
  19.  *                                   MCI_CLOSE
  20.  *                                   MCI_SET
  21.  *                                   MCI_STOP
  22.  *                                   MCI_CONNECTOR
  23.  *                                   MCI_CONNECTION
  24.  *                                   MCI_STATUS
  25.  *                                   MCI_SYSINFO
  26.  *                                   MCI_GETDEVCAPS
  27.  *                 mciGetErrorString
  28.  *                 mmioOpen
  29.  *                 mmioClose
  30.  *
  31.  * Required
  32.  *    Files     :  recorder.c        Source Code.
  33.  *                 options.c         Source Code.
  34.  *                 recorder.h        Include file.
  35.  *                 recorder.dlg      Dialog definition.
  36.  *                 recorder.rc       Resources.
  37.  *                 recorder.ipf      Help text.
  38.  *                 makefile          Make file.
  39.  *                 recorder.def      Linker definition file.
  40.  *                 recorder.ico      Program icon.
  41.  *
  42.  * Copyright (C) IBM 1993
  43.  ******************************************************************************/
  44. #define  INCL_OS2MM                 /* required for MCI and MMIO headers   */
  45. #define  INCL_WIN                   /* required to use Win APIs.           */
  46. #define  INCL_PM                    /* required to use PM APIs.            */
  47. #define  INCL_WINHELP               /* required to use IPF.                */
  48. #define  INCL_SECONDARYWINDOW       /* required for secondary window       */
  49. #define  INCL_CIRCULARSLIDER        /* required for circular slider control*/
  50. #define  INCL_GRAPHICBUTTON         /* required for graphic button control */
  51. #define  INCL_WINSTDSLIDER          /* required for using slider control   */
  52. #define  INCL_WINSTDFILE            /* required for open file dlg          */
  53. #define  INCL_WINSTDDLGS            /* required for open file dlg          */
  54.  
  55. #include <os2.h>
  56. #include <os2me.h>
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <string.h>
  60.  
  61. #include <sw.h>
  62.  
  63. #include "recorder.h"
  64.  
  65. enum DeviceStates {ST_STOPPED, ST_PLAYING, ST_RECORDING};
  66.  
  67. /*
  68.  * Procedure/Function Prototypes
  69.  */
  70. MRESULT EXPENTRY MainDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  71. MRESULT EXPENTRY OpenFileDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  72. MRESULT EXPENTRY ProductInfoDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  73.  
  74. VOID    AdjustTheDlg( HWND hwnd, BOOL fShow );
  75. VOID    CloseTheDevice( VOID );
  76. VOID    DeselectTheOption( USHORT idOption );
  77. BOOL    DoesFileExist(VOID);
  78. BOOL    FileSaveAs(HWND hwnd);
  79. VOID    Finalize( VOID);
  80. VOID    FindTheDeviceCapability( VOID );
  81. VOID    EvaluateReturnCode (ULONG ulBitsPerSample, ULONG ulSampPerSec, ULONG ulChannels, ULONG ulRC);
  82. BOOL    GetFileName( PSZ szFileName, ULONG ulStringLength);
  83. VOID    Initialize( VOID);
  84. VOID    InitializeHelp( VOID );
  85. USHORT  MessageBox( USHORT usMessageID, ULONG  ulStyle );
  86. BOOL    OpenTheFile( HWND hwnd, PSZ pszFileName );
  87. BOOL    PlayTheAudio( HWND hwnd );
  88. VOID    QueryTheDefaultConnection( VOID );
  89. BOOL    RecordTheAudio( HWND hwnd );
  90. VOID    SaveTheAudio( HWND hwnd );
  91. USHORT  SaveTheChanges( HWND hwnd );
  92. BOOL    SeekTheAudio( HWND hwnd, ULONG ulPosition );
  93. VOID    SetAudioVolume( HWND hwnd );
  94. BOOL    SetTheOptions( BOOL fSelectedFileType );
  95. VOID    SelectTheOption( USHORT idOption );
  96. VOID    ShowMCIErrorMessage( ULONG ulError );
  97. BOOL    ShowStandardFileDlg( USHORT usSelection );
  98. VOID    StopTheDevice( HWND hwnd );
  99. VOID    UpdateTitleText( HWND hwnd, PSZ pszFileName );
  100. VOID    UpdateTheStatusLine( HWND hwnd, USHORT usStatus );
  101.  
  102. /*************** End of Procedure/Function Prototypes *************************/
  103.  
  104. /*
  105.  * Global Variables.
  106.  */
  107. HAB     hab;
  108. HMQ     hmq;
  109. HWND    hwndFrame;                 /* Handle to the frame window.             */
  110. HWND    hwndHelpInstance;          /* Handle to Main Help window.             */
  111. HWND    hwndMainDialogBox;         /* Handle to the dialog window.            */
  112. HWND    hwndMenu;                  /* Handle to the menu                      */
  113. HWND    hwndPlayPB;                /* Handle to the play push button          */
  114. HWND    hwndRecordPB;              /* Handle to the record push button        */
  115. HWND    hwndProductInfo = 0;       /* Handle to the product info. dialog box  */
  116.  
  117. enum    DeviceStates   eState = ST_STOPPED;      /* state of the device       */
  118.  
  119. SHORT   sVolumeLevel  = INIT_VOLUME;             /* desired volume level      */
  120. USHORT  usDeviceType  = MCI_MICROPHONE_CONNECTOR,/* for microphone or line in */
  121.         usStereoMono  = STEREO,                  /* for stereo or mono        */
  122.         usQualityType = MUSIC,                   /* for quality selection     */
  123.         usInputLevel  = MEDIUM_INPUT_LEVEL,      /* for input level selection */
  124.         usBitType     = BIT_8,                   /* for 8 bit or 16 bit       */
  125.         usDeviceTypeOpened;                      /* for device type opened    */
  126.  
  127. BOOL    fMonoSupported        = TRUE;  /* Device supports mono files          */
  128. BOOL    fStereoSupported      = TRUE;  /* Device supports stereo files        */
  129. BOOL    fVoiceSupported       = TRUE;  /* Device supports 11 kHz files        */
  130. BOOL    fMusicSupported       = TRUE;  /* Device supports 22 kHz files        */
  131. BOOL    fHiFiSupported        = TRUE;  /* Device supports 44 kHz files        */
  132. BOOL    fHighQualitySupported = TRUE;  /* Device supports 16 bps files        */
  133. BOOL    fLoQualitySupported   = TRUE;  /* Device supports 8 bps files         */
  134. BOOL    fMonitor              = TRUE;  /* for Monotor - on/off                */
  135. BOOL    fPassedDevice         = FALSE; /* for MCI_ACQUIRE to play the file    */
  136. BOOL    fFileOpen             = FALSE; /* for file open or not                */
  137. BOOL    fTempFileInUse        = FALSE; /* for temporary file open or not      */
  138. BOOL    fModified             = FALSE; /* for opened file modified or not     */
  139. BOOL    fFirstOpen            = TRUE;  /* indicate we've opened for first time*/
  140. CHAR    szFileName[FILE_NAME_SIZE];    /* buffer for fully qualified file name*/
  141. CHAR    acTempFileName[MESSAGELEN];    /* buffer for temporary file name      */
  142. CHAR    achTitle[MAXNAMEL];            /* buffer for window title text        */
  143. CHAR    achMsgBoxTitle[MAXNAMEL];      /* Error message box title             */
  144. MCI_OPEN_PARMS   mciOpenParms;         /* open parms for MCI_OPEN             */
  145. HPOINTER  hptrWait, hptrArrow;  /* Pointer handles for use during long waits. */
  146.  
  147. /************************** End of Global Variables ***************************/
  148.  
  149. /******************************************************************************
  150.  * Name         : main
  151.  *
  152.  * Description  : This function calls the Initialize procedure to prepare
  153.  *                everything for the program's operation, enters the
  154.  *                message loop, then call Finalize to shut everything down
  155.  *                when the program is terminated.
  156.  *
  157.  * Concepts     : None.
  158.  *
  159.  * MMPM/2 API's : None.
  160.  *
  161.  * Parameters   : argc - Number of parameters passed into the program.
  162.  *                argv - Command line parameters.
  163.  *
  164.  * Return       : TRUE is returned to the operating system.
  165.  *
  166.  ******************************************************************************/
  167. INT main( VOID )
  168. {
  169.    QMSG    qmsg;
  170.  
  171.    Initialize();
  172.  
  173.    while ( WinGetMsg( hab, (PQMSG) &qmsg, (HWND) NULL, 0, 0) )
  174.       WinDispatchMsg( hab, (PQMSG) &qmsg );
  175.  
  176.    Finalize();
  177.  
  178.    return( TRUE);
  179.  
  180. } /* End of main */
  181.  
  182.  
  183. /******************************************************************************
  184.  * Name         : Initialize
  185.  *
  186.  * Description  : This function performs the necessary initializations and
  187.  *                setups that are required to show/run a dialog box as a
  188.  *                main window.  The message queue will be created, as will
  189.  *                the dialog box.
  190.  *
  191.  * Concepts     : None.
  192.  *
  193.  * MMPM/2 API's : none
  194.  *
  195.  * Parameters   : None.
  196.  *
  197.  * Return       : None.
  198.  *
  199.  ******************************************************************************/
  200. VOID Initialize( VOID)
  201. {
  202.    CHAR     szDefaultSize[MESSAGELEN];   /* buffer for default size menu text */
  203.    CHAR     szCommandString[STRING_COMMAND_SIZE];
  204.    CHAR     szReturn[STRING_COMMAND_SIZE] = "";
  205.  
  206.  
  207.    hab       = WinInitialize( 0);
  208.    hmq       = WinCreateMsgQueue( hab, 0);
  209.  
  210.    hptrArrow = WinQuerySysPointer ( HWND_DESKTOP, SPTR_ARROW, FALSE );
  211.    hptrWait  = WinQuerySysPointer ( HWND_DESKTOP, SPTR_WAIT,  FALSE );
  212.  
  213.    /*
  214.     * Initialize the dialog window. First, change pointer to a waiting
  215.     * pointer, since this might take a couple of seconds.
  216.     */
  217.    WinSetPointer ( HWND_DESKTOP, hptrWait );
  218.  
  219.    WinLoadString(
  220.       hab,                                  /* HAB for this dialog box.       */
  221.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  222.       IDS_DEFAULTSIZE,                      /* Which string to get.           */
  223.       sizeof(szDefaultSize),                /* The size of the buffer.        */
  224.       szDefaultSize);                       /* The buffer to place the string.*/
  225.  
  226.    WinLoadString(
  227.       hab,                                  /* HAB for this dialog box.       */
  228.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  229.       IDS_UNTITLED,                         /* Which string to get.           */
  230.       (SHORT) sizeof( acTempFileName),      /* The size of the buffer.        */
  231.       acTempFileName);                      /* The buffer to place the string.*/
  232.  
  233.    WinLoadString(
  234.       hab,                                  /* HAB for this dialog box.       */
  235.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  236.       IDS_AUDIO_RECORDER_ERROR,             /* Which string to get.           */
  237.       (SHORT) sizeof( achMsgBoxTitle),      /* The size of the buffer.        */
  238.       achMsgBoxTitle);                      /* The buffer to place the string.*/
  239.  
  240.    hwndFrame =                    /* Returns the handle to the frame.         */
  241.        WinLoadSecondaryWindow(
  242.           HWND_DESKTOP,           /* Parent of the dialog box.                */
  243.           HWND_DESKTOP,           /* Owner of the dialog box.                 */
  244.           (PFNWP) MainDlgProc,    /* 'Window' procedure for the dialog box.   */
  245.           (HMODULE) NULL,         /* Where is the dialog.  Null is EXE file.  */
  246.           ID_DLG_MAIN,            /* Dialog ID.                               */
  247.           (PVOID) NULL);          /* Creation Parameters for the dialog.      */
  248.  
  249.    /*
  250.     * Retrieve the handle to the dialog box by specifying the QS_DIALOG flag.
  251.     */
  252.    hwndMainDialogBox = WinQuerySecondaryHWND(hwndFrame, QS_DIALOG);
  253.  
  254.    /*
  255.     * Add Default Size menu item to system menu of the secondary window.
  256.     */
  257.    WinInsertDefaultSize(hwndFrame, szDefaultSize);
  258.  
  259.    /*
  260.     * Get the window title string from the Resource string table
  261.     * and set it as the window text for the dialog window.
  262.     */
  263.    WinLoadString(
  264.       hab,                                  /* HAB for this dialog box.       */
  265.       (HMODULE) NULL,                       /* Get the string from the .exe.  */
  266.       IDS_PROGRAM_TITLE,                    /* Which string to get.           */
  267.       (SHORT) sizeof( achTitle),            /* The size of the buffer.        */
  268.       achTitle);                            /* The buffer to place the string.*/
  269.    WinSetWindowText( hwndFrame, achTitle);
  270.  
  271.    /*
  272.     * Query the device for the default connections.
  273.     */
  274.    QueryTheDefaultConnection();
  275.  
  276.    /*
  277.     * Open the audio device with a untitled file loaded.
  278.     */
  279.    if (OpenTheFile( hwndMainDialogBox, acTempFileName ))
  280.       fTempFileInUse =  TRUE;
  281.    /*
  282.     * Find the opened device capabilities like can able to play and record
  283.     * the wave audio files. Also find the device has the ability to play
  284.     * and record 16 bit audio files.
  285.     */
  286.    FindTheDeviceCapability();
  287.  
  288.    WinShowWindow( hwndFrame, TRUE );
  289.    InitializeHelp();
  290.  
  291.    /*
  292.     * Now that we're done here, change the pointer back to the arrow.
  293.     */
  294.    WinSetPointer ( HWND_DESKTOP, hptrArrow );
  295.  
  296. } /* End of Initialize */
  297.  
  298. /******************************************************************************
  299.  * Name         : Finalize
  300.  *
  301.  * Description  : This routine is called after the message dispatch loop
  302.  *                has ended because of a WM_QUIT message.  The code will
  303.  *                destroy the help instance, messages queue, and window.
  304.  *
  305.  * Concepts     : None.
  306.  *
  307.  * MMPM/2 API's : None.
  308.  *
  309.  * Parameters   : None.
  310.  *
  311.  * Return       : None.
  312.  *
  313.  ******************************************************************************/
  314. VOID Finalize( VOID )
  315. {
  316.    /*
  317.     * Destroy the Help Instances.
  318.     */
  319.    if ( hwndHelpInstance != (HWND) NULL)
  320.    {
  321.       WinDestroyHelpInstance( hwndHelpInstance );
  322.    }
  323.  
  324.    WinDestroySecondaryWindow( hwndFrame );
  325.    WinDestroyMsgQueue( hmq );
  326.    WinTerminate( hab );
  327.  
  328. }  /* End of Finalize */
  329.  
  330. /******************************************************************************
  331.  * Name         : MainDlgProc
  332.  *
  333.  * Description  : This function controls the main dialog box.  It will handle
  334.  *                received messages such as pushbutton notifications, timing
  335.  *                events, etc.
  336.  *
  337.  * Concepts     : - How to participate in MMPM/2 device sharing scheme.
  338.  *                - How to handle notification messages.
  339.  *
  340.  * MMPM/2 API's : mciSendMessage   MCI_ACQUIREDEVICE
  341.  *
  342.  * Parameters   : hwnd - Handle for the Main dialog box.
  343.  *                msg  - Message received by the dialog box.
  344.  *                mp1  - Parameter 1 for the just received message.
  345.  *                mp2  - Parameter 2 for the just received message.
  346.  *
  347.  * Return       :
  348.  *
  349.  ******************************************************************************/
  350. MRESULT EXPENTRY MainDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  351. {
  352.    ULONG             ulError;                 /* rc for MCI_ACQUIRE send cmd  */
  353.    HPOINTER          hpProgramIcon;           /* handle to program's icon     */
  354.    MCI_GENERIC_PARMS mciGenericParms;         /* generic parms for MCI_ACQUIRE*/
  355.    USHORT            usCommandMessage;        /* command message for notify   */
  356.    USHORT            usNotifyCode;            /* notification message code    */
  357.    static BOOL       fShowStatus;             /* for status line              */
  358.    BOOL              fError;                  /* Error return code            */
  359.  
  360.  
  361.    switch( msg )
  362.    {
  363.       case WM_INITDLG :
  364.          hpProgramIcon =
  365.             WinLoadPointer(
  366.                HWND_DESKTOP,
  367.                (HMODULE) NULL,              /* Resource is kept in .Exe file. */
  368.                ID_ICON );                   /* Which icon to use.             */
  369.  
  370.          WinDefSecondaryWindowProc(
  371.             hwnd,                    /* Dialog window handle.                 */
  372.             WM_SETICON,              /* Message to the dialog.  Set it's icon.*/
  373.             (MPARAM) hpProgramIcon,
  374.             (MPARAM) 0 );            /* mp2 no value.                         */
  375.  
  376.          /*
  377.           * get all the required handles.
  378.           */
  379.          hwndPlayPB     = WinWindowFromID( hwnd, ID_GPB_PLAY );   /* play PB  */
  380.          hwndRecordPB   = WinWindowFromID( hwnd, ID_GPB_RECORD ); /* record PB*/
  381.          hwndMenu       = WinWindowFromID(                        /* menu     */
  382.                              WinQuerySecondaryFrame( hwnd ),
  383.                              FID_MENU );
  384.          /*
  385.           * The slider control cannot be completely set from the dialog
  386.           * template so some aspects must be set here.  We will set the
  387.           * volume range to 0-100, increment to 1-10, and the initial
  388.           * volume level to 75.
  389.           */
  390.          WinSendMsg( WinWindowFromID(hwnd, ID_SL_VOLUME),
  391.                      CSM_SETRANGE,
  392.                      (MPARAM) 0L,
  393.                      (MPARAM) 100L);
  394.  
  395.          WinSendMsg( WinWindowFromID(hwnd, ID_SL_VOLUME),
  396.                      CSM_SETINCREMENT,
  397.                      (MPARAM) 10L,
  398.                      (MPARAM) 1L);
  399.  
  400.          WinSendMsg( WinWindowFromID(hwnd, ID_SL_VOLUME),
  401.                      CSM_SETVALUE,
  402.                      (MPARAM) sVolumeLevel,
  403.                      (MPARAM) NULL);
  404.  
  405.          /*
  406.           * Set up the PLAY graphic pushbutton.
  407.           */
  408.          WinSendMsg (
  409.             hwndPlayPB,                   /* Play push button handle          */
  410.             GBM_SETANIMATIONRATE,         /* Animation rate control           */
  411.             MPFROMLONG(100L),             /* Update play bitmap every .1 sec  */
  412.             NULL);                        /* Ignore return data               */
  413.  
  414.          /*
  415.           * Initialize all the default selections in the menu pulldowns.
  416.           */
  417.          WinSendMsg( hwndMenu,          /* select the "Microphone" as default */
  418.                      MM_SETITEMATTR,
  419.                      MPFROM2SHORT(IDM_MICROPHONE, TRUE),
  420.                      MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  421.  
  422.          WinSendMsg( hwndMenu,   /* select the "Medium input level" as default*/
  423.                      MM_SETITEMATTR,
  424.                      MPFROM2SHORT(IDM_MEDIUM_INPUT, TRUE),
  425.                      MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  426.  
  427.          WinSendMsg( hwndMenu,      /* select the "Monitor input" as default  */
  428.                      MM_SETITEMATTR,
  429.                      MPFROM2SHORT(IDM_MONITOR_INPUT, TRUE),
  430.                      MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  431.  
  432.          WinSendMsg( hwndMenu,     /* select the "Stereo" as default          */
  433.                      MM_SETITEMATTR,
  434.                      MPFROM2SHORT(IDM_STEREO, TRUE),
  435.                      MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  436.  
  437.          WinSendMsg( hwndMenu,     /* select "Music (22 khz)" as default      */
  438.                      MM_SETITEMATTR,
  439.                      MPFROM2SHORT(IDM_MUSIC, TRUE),
  440.                      MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  441.  
  442.          WinSendMsg( hwndMenu,     /* select the "Low quality" as default     */
  443.                      MM_SETITEMATTR,
  444.                      MPFROM2SHORT(IDM_LOW_QUALITY, TRUE),
  445.                      MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  446.  
  447.          WinSendMsg( hwndMenu,     /* select "Show status line" as default    */
  448.                      MM_SETITEMATTR,
  449.                      MPFROM2SHORT(IDM_OPTIONS_STATUSLINE, TRUE),
  450.                      MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  451.  
  452.          fShowStatus = TRUE;    /* set the "fShowStatus" flag to true         */
  453.  
  454.          return( (MRESULT) 0);
  455.  
  456.       case WM_CLOSE :
  457.          /*
  458.           * Before closing the device, inform the user if there is a
  459.           * modified file open.
  460.           */
  461.          if (!fFirstOpen)
  462.          {
  463.             if (fModified )
  464.             {
  465.                if ( SaveTheChanges( hwnd ) == MBID_CANCEL )
  466.                   return( (MRESULT) 0);
  467.                else
  468.                   CloseTheDevice();
  469.             }
  470.             else
  471.                CloseTheDevice();
  472.          }
  473.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  474.  
  475.       case WM_HELP :
  476.          /*
  477.           * The dialog window has received a request for help from the user,
  478.           * i.e., the Help pushbutton was pressed.  Send the HM_DISPLAY_HELP
  479.           * message to the Help Instance with the IPF resource identifier
  480.           * for the correct HM panel.  This will show the help panel for this
  481.           * sample program.
  482.           */
  483.          WinSendMsg( hwndHelpInstance,
  484.                      HM_DISPLAY_HELP,
  485.                      MPFROMSHORT(1),
  486.                      MPFROMSHORT(HM_RESOURCEID));
  487.          return( (MRESULT) 0);
  488.  
  489.       case WM_CONTROL:
  490.          if (SHORT1FROMMP(mp1)==ID_SL_VOLUME)
  491.          {
  492.             if ((SHORT2FROMMP(mp1)==CSN_CHANGED) ||    /* change volume?   */
  493.                 (SHORT2FROMMP(mp1)==CSN_TRACKING))     /* tracking volume? */
  494.             {
  495.                sVolumeLevel = SHORT1FROMMP (mp2);
  496.                SetAudioVolume(hwnd);
  497.             }
  498.          }
  499.          return( (MRESULT) 0);
  500.  
  501.       case WM_COMMAND :
  502.          /*
  503.           * To get which pushbutton was pressed the SHORT1FROMMP macro is used.
  504.           */
  505.          switch (SHORT1FROMMP(mp1))
  506.          {
  507.             case ID_GPB_PLAY:               /* user selected "Play"           */
  508.                /*
  509.                 * If the audio is stopped and an existing file or a tempfile is
  510.                 * open,  PLAY.
  511.                 */
  512.                if (eState == ST_STOPPED)
  513.                {
  514.                   if (PlayTheAudio( hwnd))
  515.                   {
  516.                      /*
  517.                       * Update the status line with appropriate message.
  518.                       */
  519.                      UpdateTheStatusLine(hwnd, IDS_PLAYING);
  520.  
  521.                      /*
  522.                       * If playing was successful, start the play button
  523.                       * animation.
  524.                       */
  525.                      WinSendMsg( hwndPlayPB,          /* Dialog window handle */
  526.                                  GBM_ANIMATE,         /* Animation control    */
  527.                                  MPFROMSHORT(TRUE),   /* Animation flag       */
  528.                                  NULL );              /* Ignore return data   */
  529.                   }
  530.                   else      /* If playing failed, set the state to stopped    */
  531.                       eState = ST_STOPPED;
  532.                }
  533.                break;
  534.  
  535.             case ID_GPB_RECORD:                    /* user selected "Record"  */
  536.                /*
  537.                 * If the audio is in stopped state, record
  538.                 */
  539.                if (eState == ST_STOPPED)
  540.                {
  541.                   RecordTheAudio( hwnd );
  542.                }
  543.                break;
  544.  
  545.             case ID_GPB_STOP:              /* user selected "Stop"            */
  546.                /*
  547.                 * If the audio is not in stopped state, stop the device
  548.                 */
  549.                if (eState != ST_STOPPED)
  550.                   StopTheDevice(hwnd);
  551.                break;
  552.  
  553.             case ID_GPB_REWIND:            /* user selected "Rewind"          */
  554.                /*
  555.                 * If an existing file open, or a temp file is modified
  556.                 * seek the file.
  557.                 */
  558.                if ((fFileOpen) || (fModified))
  559.                {
  560.                   /*
  561.                    * Update the status line with the appropriate message and
  562.                    * seek the audio to the begining.
  563.                    */
  564.                   UpdateTheStatusLine(hwnd, IDS_REWINDING);
  565.                   SeekTheAudio( hwnd, MCI_TO_START );
  566.                }
  567.                break;
  568.  
  569.             case ID_GPB_FF:                /* user selected "Fast Forward"    */
  570.                /*
  571.                 * If an existing file open, or a temp file is modified
  572.                 * seek the file.
  573.                 */
  574.                if ((fFileOpen) || (fModified))
  575.                {
  576.                   /*
  577.                    * Update the status line with the appropriate message and
  578.                    * seek the audio to the end.
  579.                    */
  580.                   UpdateTheStatusLine(hwnd, IDS_FASTFORWARDING);
  581.                   SeekTheAudio( hwnd, MCI_TO_END );
  582.                }
  583.                break;
  584.  
  585.             case IDM_FILE_NEW:             /* user selected "Filenew"         */
  586.                if (eState != ST_STOPPED)
  587.                   StopTheDevice(hwnd);
  588.                /*
  589.                 * First, if any modified file is open, ask the user if he wants
  590.                 * to save the changes or not.
  591.                 */
  592.                if (fModified)
  593.                {
  594.                   if ( SaveTheChanges( hwnd ) == MBID_CANCEL )
  595.                      return( (MRESULT) FALSE);
  596.                }
  597.  
  598.                /*
  599.                 * If opening is success, set the file varables.
  600.                 */
  601.                if ( OpenTheFile( hwnd, acTempFileName ))
  602.                {
  603.                   /*
  604.                    * Get the selected file header information and check the
  605.                    * correct options and disable all the other options in the
  606.                    * Type menu pulldown.
  607.                    */
  608.                   SetTheOptions(NEW_FILE);
  609.  
  610.                   fTempFileInUse =  TRUE;
  611.                   fFileOpen      =  FALSE;
  612.                   UpdateTheStatusLine(hwnd, IDS_STOPPED);
  613.                }
  614.                return( (MRESULT) TRUE);
  615.                break;
  616.  
  617.             case IDM_FILE_OPEN:                   /* user selected "Fileopen" */
  618.                /*
  619.                 * First, if any modified file is open, ask the user if he wants
  620.                 * to save the changes or not.
  621.                 */
  622.                if (fModified)
  623.                {
  624.                   if ( SaveTheChanges( hwnd ) == MBID_CANCEL )
  625.                      return( (MRESULT) FALSE);
  626.                }
  627.  
  628.                /*
  629.                 * Allow the user to select a file using Open dialog.
  630.                 *
  631.                 */
  632.                if (ShowStandardFileDlg(IDM_FILE_OPEN))
  633.                {
  634.                   /*
  635.                    * If the audio is not in stop state, stop it.
  636.                    */
  637.                   if (eState != ST_STOPPED)
  638.                      StopTheDevice(hwnd);
  639.  
  640.                   if (!fFirstOpen)       /* If we've opened the device        */
  641.                   {
  642.                      /*
  643.                       * Get the selected file header information and check the
  644.                       * correct options and disable all the other options in
  645.                       * the Type menu pulldown.
  646.                       */
  647.                      fError = SetTheOptions(EXISTING_FILE);
  648.                      /* If we get an error from SetTheOptions, we want to
  649.                       * exit now, before opening the file.
  650.                       */
  651.                      if (!fError) {
  652.                         return( (MRESULT) FALSE);
  653.                      }
  654.                   }
  655.                   /*
  656.                    * Now that the user has selected a file, open it.
  657.                    */
  658.                   if (OpenTheFile( hwnd, szFileName ))
  659.                   {
  660.                      fFileOpen      =  TRUE;
  661.                      fTempFileInUse =  FALSE;
  662.                      UpdateTheStatusLine(hwnd, IDS_STOPPED);
  663.                   }
  664.                }
  665.                return( (MRESULT) TRUE);
  666.                break;
  667.  
  668.             case IDM_FILE_SAVE:                   /* user selected "Save"     */
  669.  
  670.                if ((!fTempFileInUse) && (!fFileOpen) || (fTempFileInUse))
  671.                {
  672.                   if ( FileSaveAs( hwnd ) )
  673.                   {
  674.                      /*
  675.                       * If the audio is not in stop state, stop it.
  676.                       */
  677.                      if (eState != ST_STOPPED)
  678.                         StopTheDevice(hwnd);
  679.  
  680.                      fFileOpen = TRUE;
  681.                      UpdateTitleText( hwndFrame, szFileName );
  682.                   }
  683.                }
  684.                else
  685.                   SaveTheAudio(hwnd);
  686.  
  687.                return( (MRESULT) TRUE);
  688.                break;
  689.  
  690.             case IDM_FILE_SAVE_AS:                /* user selected "Saveas"   */
  691.  
  692.                if ( FileSaveAs( hwnd ) )
  693.                {
  694.                   /*
  695.                    * If the audio is not in stop state, stop it.
  696.                    */
  697.                   if (eState != ST_STOPPED)
  698.                      StopTheDevice(hwnd);
  699.  
  700.                   fFileOpen = TRUE;
  701.                   UpdateTitleText( hwndFrame, szFileName );
  702.                }
  703.                return( (MRESULT) TRUE);
  704.                break;
  705.  
  706.             case IDM_MICROPHONE:             /* user selected "Microphone"    */
  707.                /*
  708.                 * First, select the "Microphone" then, deselect the "Line in"
  709.                 * and set the usDeviceType.
  710.                 */
  711.                SelectTheOption(IDM_MICROPHONE);
  712.                DeselectTheOption(IDM_LINEIN);
  713.                usDeviceType =  MCI_MICROPHONE_CONNECTOR;
  714.                return( 0 );
  715.  
  716.             case IDM_LINEIN:                /* user selected "Line in"        */
  717.                /*
  718.                 * First, select the "Line in" then, deselect the "Microphone"
  719.                 * and set the usDeviceType.
  720.                 */
  721.                SelectTheOption(IDM_LINEIN);
  722.                DeselectTheOption(IDM_MICROPHONE);
  723.                usDeviceType =  MCI_LINE_IN_CONNECTOR;
  724.                return( 0 );
  725.  
  726.             case IDM_LOW_INPUT:             /* user selected "Low input level"*/
  727.                /*
  728.                 * First, select the "Low input level" then, deselect the
  729.                 * "Medium input level" and "High input level" and set the
  730.                 * usInputLevel.
  731.                 */
  732.                SelectTheOption(IDM_LOW_INPUT);
  733.                DeselectTheOption( IDM_MEDIUM_INPUT );
  734.                DeselectTheOption( IDM_HIGH_INPUT );
  735.                usInputLevel = LOW_INPUT_LEVEL;
  736.                return( 0 );
  737.  
  738.             case IDM_MEDIUM_INPUT:       /* user selected "Medium input level"*/
  739.                /*
  740.                 * First, select the "Medium input level" then, deselect the
  741.                 * "Low input level" and "High input level" and set the
  742.                 * usInputLevel.
  743.                 */
  744.                SelectTheOption(IDM_MEDIUM_INPUT);
  745.                DeselectTheOption( IDM_LOW_INPUT );
  746.                DeselectTheOption( IDM_HIGH_INPUT );
  747.                usInputLevel = MEDIUM_INPUT_LEVEL;
  748.                return( 0 );
  749.  
  750.             case IDM_HIGH_INPUT:          /* user selected "High input level" */
  751.                /*
  752.                 * First, select the "High input level" then, deselect the
  753.                 * "Low input level" and "Medium input level" and set the
  754.                 * usInputLevel.
  755.                 */
  756.                SelectTheOption(IDM_HIGH_INPUT);
  757.                DeselectTheOption( IDM_LOW_INPUT );
  758.                DeselectTheOption( IDM_MEDIUM_INPUT );
  759.                usInputLevel = HIGH_INPUT_LEVEL;
  760.                return( 0 );
  761.  
  762.             case IDM_MONITOR_INPUT:        /* user selected "Monitor input"   */
  763.                /*
  764.                 * Check to see the status of the "Monitor input" option.
  765.                 */
  766.                if (fMonitor)
  767.                {
  768.                   /*
  769.                    * Previously this item was checked, so now uncheck the
  770.                    * "Monitor input" item and set fMonitor to false.
  771.                    */
  772.                   WinSendMsg( hwndMenu,
  773.                               MM_SETITEMATTR,
  774.                               MPFROM2SHORT(IDM_MONITOR_INPUT, TRUE),
  775.                               MPFROM2SHORT(MIA_CHECKED, FALSE));
  776.                   fMonitor = FALSE;
  777.                }
  778.                else
  779.                {
  780.                   /*
  781.                    * Previously this item was unchecked, so now check the
  782.                    * "Monitor input" item and set fMonitor to true.
  783.                    */
  784.                   WinSendMsg( hwndMenu,
  785.                               MM_SETITEMATTR,
  786.                               MPFROM2SHORT(IDM_MONITOR_INPUT, TRUE),
  787.                               MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  788.                   fMonitor = TRUE;
  789.                }
  790.                return( 0 );
  791.  
  792.             case IDM_STEREO:                 /* user selected "Stereo"        */
  793.                /*
  794.                 * First, select the "Stereo" then, deselect the "Mono" and
  795.                 * set the usStereoMono.
  796.                 */
  797.                SelectTheOption(IDM_STEREO);
  798.                DeselectTheOption( IDM_MONO );
  799.                usStereoMono =  STEREO;
  800.                return( 0 );
  801.  
  802.             case IDM_MONO:                   /* user selected "Mono"          */
  803.                /*
  804.                 * First, select the "Mono" then, deselect the "Stereo" and
  805.                 * and set the usStereoMono
  806.                 */
  807.                SelectTheOption(IDM_MONO);
  808.                DeselectTheOption( IDM_STEREO );
  809.                usStereoMono =  MONO;
  810.                return( 0 );
  811.  
  812.             case IDM_VOICE:                 /* user selected "Voice (11 khz)" */
  813.                /*
  814.                 * First, select the "Voice (11 khz)" then, deselect the
  815.                 * "Music (22 khz)" and "High fidelity (44 khz)" and set the
  816.                 * usQualityType
  817.                 */
  818.                SelectTheOption(IDM_VOICE);
  819.                DeselectTheOption( IDM_MUSIC );
  820.                DeselectTheOption( IDM_HIGH_FIDELITY );
  821.                usQualityType =  VOICE;
  822.                return( 0 );
  823.  
  824.             case IDM_MUSIC:                 /* user selected "Music (22 khz)" */
  825.                /*
  826.                 * First, select the "Music (22 khz)" then, deselect the
  827.                 * "Voice (11 khz)" and "High fidelity (44 khz)" and set the
  828.                 * usQualityType
  829.                 */
  830.                SelectTheOption(IDM_MUSIC);
  831.                DeselectTheOption( IDM_VOICE );
  832.                DeselectTheOption( IDM_HIGH_FIDELITY );
  833.                usQualityType = MUSIC;
  834.                return( 0 );
  835.  
  836.             case IDM_HIGH_FIDELITY:  /* user selected "High fidelity (44 khz)"*/
  837.                /*
  838.                 * First, select the "High fidelity (44 khz)" then, deselect
  839.                 * the "Voice (11 khz)" and "Music (22 khz)" and set the
  840.                 * usQualityType
  841.                 */
  842.                SelectTheOption(IDM_HIGH_FIDELITY);
  843.                DeselectTheOption( IDM_VOICE );
  844.                DeselectTheOption( IDM_MUSIC );
  845.                usQualityType =  HIGH_FIDELITY;
  846.                return( 0 );
  847.  
  848.             case IDM_LOW_QUALITY:              /* user selected "Low quality" */
  849.                /*
  850.                 * First, select the "Low quality" then, deselect the
  851.                 * "High quality" and set the usBitType.
  852.                 */
  853.                SelectTheOption(IDM_LOW_QUALITY);
  854.                DeselectTheOption( IDM_HIGH_QUALITY );
  855.                usBitType =  BIT_8;
  856.                return( 0 );
  857.  
  858.             case IDM_HIGH_QUALITY:             /* user selected "High quality"*/
  859.                /*
  860.                 * First, select the "High quality" then, deselect the
  861.                 * "Low quality" and set the usBitType.
  862.                 */
  863.                SelectTheOption(IDM_HIGH_QUALITY);
  864.                DeselectTheOption( IDM_LOW_QUALITY );
  865.                usBitType =  BIT_16;
  866.                return( 0 );
  867.  
  868.             case IDM_OPTIONS_STATUSLINE :
  869.                /*
  870.                 * Check to see the status of the "Show status line" option.
  871.                 */
  872.                if (fShowStatus)
  873.                {
  874.                   /*
  875.                    * Previously this item was checked, so now uncheck the
  876.                    * "Show status line" item and set fShowStatus to false.
  877.                    */
  878.                   WinSendMsg( hwndMenu,
  879.                               MM_SETITEMATTR,
  880.                               MPFROM2SHORT(IDM_OPTIONS_STATUSLINE, TRUE),
  881.                               MPFROM2SHORT(MIA_CHECKED, FALSE));
  882.                   fShowStatus = FALSE;
  883.  
  884.                   /*
  885.                    * Adjust the Dialog window.
  886.                    */
  887.                   AdjustTheDlg(hwnd, fShowStatus);
  888.                }
  889.                else
  890.                {
  891.                   /*
  892.                    * Previously this item was unchecked, so now check the
  893.                    * "Show status line" item and set fShowStatus to true.
  894.                    */
  895.                   WinSendMsg( hwndMenu,
  896.                               MM_SETITEMATTR,
  897.                               MPFROM2SHORT(IDM_OPTIONS_STATUSLINE, TRUE),
  898.                               MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
  899.                   fShowStatus = TRUE;
  900.  
  901.                   /*
  902.                    * Adjust the Dialog window.
  903.                    */
  904.                   AdjustTheDlg(hwnd, fShowStatus);
  905.                }
  906.                return( 0 );
  907.  
  908.             case IDM_HELP_PRODUCTINFO :
  909.                /*
  910.                 * See if the product information dialog box was created.
  911.                 */
  912.                if (!hwndProductInfo)
  913.                {
  914.                   /*
  915.                    * Product Window was not created, create and display the
  916.                    * window.
  917.                    */
  918.                   hwndProductInfo =
  919.                       WinLoadSecondaryWindow(
  920.                          HWND_DESKTOP,             /* Parent of the dialog box*/
  921.                          hwndFrame,                /* Owner of the dialog box.*/
  922.                          (PFNWP)ProductInfoDlgProc,/* Dialog box procedure.   */
  923.                          (HMODULE) NULL,           /* Dialog is where,EXE file*/
  924.                          ID_DLG_PRODUCTINFO,       /* Dialog ID.              */
  925.                          (PVOID) NULL);            /* Dialog Creation Params  */
  926.               }
  927.               else
  928.               {
  929.                  /*
  930.                   * Product window was created earlier, reposition the window
  931.                   * and give the focus.
  932.                   */
  933.                  WinSetWindowPos(
  934.                     hwndProductInfo,
  935.                     HWND_TOP,
  936.                     (SHORT) NULL,
  937.                     (SHORT) NULL,
  938.                     (SHORT) NULL,
  939.                     (SHORT) NULL,
  940.                     SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE );
  941.  
  942.                  WinSetFocus( HWND_DESKTOP, hwndProductInfo );
  943.               }
  944.                return( 0 );
  945.  
  946.             case IDM_HELP_INDEX :            /* user selected "Help Index"    */
  947.                /*
  948.                 * Call system default help index panel.
  949.                 */
  950.                WinSendMsg( hwndHelpInstance,
  951.                            HM_HELP_INDEX,
  952.                            NULL,
  953.                            NULL);
  954.                break;
  955.  
  956.             case IDM_HELP_GENERAL :          /* user selected "General Help"  */
  957.                /*
  958.                 * Call general help panel.
  959.                 */
  960.                WinSendMsg( hwndHelpInstance,
  961.                            HM_DISPLAY_HELP,
  962.                            MPFROMSHORT(1),
  963.                            MPFROMSHORT(HM_RESOURCEID));
  964.                break;
  965.  
  966.             case IDM_HELP_USING :            /* user selected "Using Help"    */
  967.                /*
  968.                 * Call system default using help panel.
  969.                 */
  970.                WinSendMsg( hwndHelpInstance,
  971.                            HM_DISPLAY_HELP,
  972.                            NULL,
  973.                            NULL);
  974.                break;
  975.  
  976.             case IDM_HELP_KEYS :             /* user selected "Keys Help"     */
  977.                /*
  978.                 * Call keys help panel.
  979.                 */
  980.                WinSendMsg( hwndHelpInstance,
  981.                            HM_DISPLAY_HELP,
  982.                            MPFROMSHORT(2),
  983.                            MPFROMSHORT(HM_RESOURCEID));
  984.                break;
  985.  
  986.             default:
  987.                break;
  988.  
  989.          }  /* End of Command Switch */
  990.          return( (MRESULT) 0);
  991.  
  992.       /*
  993.        * The next two messages are handled so that the audio recorder
  994.        * application can participate in device sharing.  Since it opens
  995.        * the device as shareable device, other applications can gain
  996.        * control of the device.  When this happens, we will receive a
  997.        * MM_MCIPASSDEVICE message.  We keep track of this device passing in
  998.        * the fPassedDevice boolean variable.
  999.        *
  1000.        * If we do not have access to the device when we receive an WM_ACTIVATE
  1001.        * message, then we will issue an acquire device command to gain
  1002.        * access to the device.
  1003.        *
  1004.        *
  1005.        * This is one possible method that can be used to implement
  1006.        * device sharing. For applications that are more complex
  1007.        * than this sample program, developers may wish to take
  1008.        * advantage of a more robust method of device sharing.
  1009.        * This can be done by using the MCI_ACQUIRE_QUEUE flag on
  1010.        * the MCI_ACQUIREDEVICE command.  Please refer to the MMPM/2
  1011.        * documentation for more information on this flag.
  1012.        */
  1013.  
  1014.       case MM_MCIPASSDEVICE:
  1015.          if (SHORT1FROMMP(mp2) == MCI_GAINING_USE)           /* GAINING USE */
  1016.          {
  1017.             fPassedDevice = FALSE;               /* Gaining control of device.*/
  1018.             if (eState == ST_PLAYING)            /* If the file was playing   */
  1019.             {
  1020.                /*
  1021.                 * Start play button animation and update the status line
  1022.                 * with appropriate text.
  1023.                 */
  1024.                WinSendMsg( hwndPlayPB,           /* Play button handle        */
  1025.                            GBM_ANIMATE,          /* Animation control         */
  1026.                            MPFROMSHORT(TRUE),    /* Animation flag            */
  1027.                            NULL );               /* Ignore return data        */
  1028.                UpdateTheStatusLine(hwnd, IDS_PLAYING);
  1029.             }
  1030.             else if (eState == ST_RECORDING)
  1031.             {
  1032.                /*
  1033.                 * Start record button animation and update the status line
  1034.                 * with appropriate text.
  1035.                 */
  1036.                WinSendMsg( hwndRecordPB,         /* Record button handle      */
  1037.                            GBM_ANIMATE,          /* Animation control         */
  1038.                            MPFROMSHORT(TRUE),    /* Animation flag            */
  1039.                            NULL );               /* Ignore return data        */
  1040.                UpdateTheStatusLine(hwnd, IDS_RECORDING);
  1041.             }
  1042.             else
  1043.                /*
  1044.                 * Update the status line with appropriate text.
  1045.                 */
  1046.                UpdateTheStatusLine(hwnd, IDS_STOPPED);
  1047.          }
  1048.          else                     /* LOSING USE  */
  1049.          {
  1050.             fPassedDevice = TRUE;                /* Losing  control of device.*/
  1051.             if (eState == ST_PLAYING)            /* If the file was playing   */
  1052.             {
  1053.                /*
  1054.                 * Stop play button animation and update the status line
  1055.                 * with appropriate text.
  1056.                 */
  1057.                WinSendMsg( hwndPlayPB,           /* Play button handle        */
  1058.                            GBM_ANIMATE,          /* Animation control         */
  1059.                            MPFROMSHORT(FALSE),   /* Animation flag            */
  1060.                            NULL );               /* Ignore return data        */
  1061.                UpdateTheStatusLine(hwnd, IDS_PLAYING);
  1062.             }
  1063.             else if (eState == ST_RECORDING)
  1064.             {
  1065.                /*
  1066.                 * Stop record button animation and update the status line
  1067.                 * with appropriate text.
  1068.                 */
  1069.                WinSendMsg( hwndRecordPB,         /* Record button handle      */
  1070.                            GBM_ANIMATE,          /* Animation control         */
  1071.                            MPFROMSHORT(FALSE),   /* Animation flag            */
  1072.                            NULL );               /* Ignore return data        */
  1073.                UpdateTheStatusLine(hwnd, IDS_RECORDING);
  1074.             }
  1075.             else
  1076.                /*
  1077.                 * Update the status line with appropriate text.
  1078.                 */
  1079.                UpdateTheStatusLine(hwnd, IDS_STOPPED);
  1080.          }
  1081.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  1082.  
  1083.       case WM_ACTIVATE:
  1084.  
  1085.          /* We use the WM_ACTIVATE message to participate in device
  1086.           * sharing.  We first check to see if this is an activate
  1087.           * or a deactivate message (indicated by mp1).  Then,
  1088.           * we check to see if we've passed control of the audio'
  1089.           * devices.  If these conditions are true, then
  1090.           * we issue an acquire device command to regain control of
  1091.           * the device, since we're now the active window on the screen.
  1092.           */
  1093.  
  1094.          if ((BOOL)mp1 && fPassedDevice == TRUE)
  1095.          {
  1096.             mciGenericParms.hwndCallback = hwnd;
  1097.  
  1098.             ulError = mciSendCommand( mciOpenParms.usDeviceID,
  1099.                                       MCI_ACQUIREDEVICE,
  1100.                                       (ULONG)MCI_NOTIFY,
  1101.                                       (PVOID) &mciGenericParms,
  1102.                                       (USHORT)NULL);
  1103.             if (ulError)
  1104.                ShowMCIErrorMessage( ulError);
  1105.          }
  1106.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  1107.  
  1108.       case MM_MCINOTIFY:
  1109.          /*
  1110.           * This message is returned to an application when a device
  1111.           * successfully completes a command that was issued with a NOTIFY
  1112.           * flag, or when an error occurs with the command.
  1113.           *
  1114.           * This message returns two values. A user parameter (mp1) and
  1115.           * the command message (mp2) that was issued. The low word of mp1
  1116.           * is the Notification Message Code which indicates the status of the
  1117.           * command like success or failure. The high word of mp2 is the
  1118.           * Command Message which indicates the source of the command.
  1119.           */
  1120.  
  1121.          usNotifyCode = (USHORT) SHORT1FROMMP( mp1);  /* low-word    */
  1122.          usCommandMessage = (USHORT) SHORT2FROMMP( mp2); /* high-word */
  1123.  
  1124.          switch (usCommandMessage)
  1125.          {
  1126.             case MCI_PLAY:
  1127.                switch (usNotifyCode)
  1128.                {
  1129.                   case MCI_NOTIFY_SUCCESSFUL:
  1130.                      if (eState != ST_STOPPED)
  1131.                      {
  1132.                         /*
  1133.                          * Update the status line with appropriate message.
  1134.                          */
  1135.                         UpdateTheStatusLine(hwnd, IDS_STOPPED);
  1136.                         eState = ST_STOPPED;
  1137.  
  1138.                         /*
  1139.                          * Stop the play button animation
  1140.                          */
  1141.                         WinSendMsg( hwndPlayPB,        /* Play button handle  */
  1142.                                     GBM_ANIMATE,       /* Animation control   */
  1143.                                     MPFROMSHORT(FALSE),/* Animation flag      */
  1144.                                     NULL );            /* Ignore return data  */
  1145.                      }
  1146.                      break;
  1147.  
  1148.                   case MCI_NOTIFY_SUPERSEDED:
  1149.                   case MCI_NOTIFY_ABORTED:
  1150.                      /* we don't need to handle these messages. */
  1151.                      break;
  1152.  
  1153.                   default:
  1154.                      /*
  1155.                       * If the message is none of the above, then it must be
  1156.                       * a notification error message.
  1157.                       */
  1158.                      ShowMCIErrorMessage( usNotifyCode);
  1159.                      eState = ST_STOPPED;
  1160.  
  1161.                      /*
  1162.                       * Stop the play button animation and update the status
  1163.                       * line with appropriate text.
  1164.                       */
  1165.                      WinSendMsg( hwndPlayPB,           /* Play button handle  */
  1166.                                  GBM_ANIMATE,          /* Animation control   */
  1167.                                  MPFROMSHORT(FALSE),   /* Animation flag      */
  1168.                                  NULL );               /* Ignore return data  */
  1169.                      UpdateTheStatusLine(hwnd, IDS_STOPPED);
  1170.                      break;
  1171.                }
  1172.                break;
  1173.          }
  1174.          return( (MRESULT) 0);
  1175.  
  1176.       default:
  1177.          return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2));
  1178.  
  1179.    }  /* End of msg Switch */
  1180.  
  1181.    return( (MRESULT) FALSE);
  1182.  
  1183. } /* End of MainDlgProc */
  1184.  
  1185. /******************************************************************************
  1186.  * Name         : InitializeHelp
  1187.  *
  1188.  * Description  : This procedure will set up the initial values in the
  1189.  *                global help structure.  This help structure will then
  1190.  *                be passed on to the Help Manager when the Help Instance
  1191.  *                is created.  The handle to the Help Instance will be
  1192.  *                kept for later use.
  1193.  *
  1194.  * Concepts     : None.
  1195.  *
  1196.  * MMPM/2 API's : None.
  1197.  *
  1198.  * Parameters   : None.
  1199.  *
  1200.  * Return       : None.
  1201.  *
  1202.  ******************************************************************************/
  1203. VOID InitializeHelp( VOID )
  1204. {
  1205.  
  1206.    HELPINIT helpInit;                 /* Help initialization structure.          */
  1207.    CHAR     achHelpLibraryName[LEN_HELP_LIBRARY_NAME];
  1208.    CHAR     achHelpWindowTitle[LEN_HELP_WINDOW_TITLE];
  1209.  
  1210.    /*
  1211.     * Load the strings for the Help window title and library name.
  1212.     * Initialize the help structure and associate the help instance.
  1213.     */
  1214.    WinLoadString( hab,
  1215.                   (HMODULE) NULL,
  1216.                   IDS_HELP_WINDOW_TITLE,
  1217.                   (SHORT) sizeof( achHelpWindowTitle),
  1218.                   achHelpWindowTitle);
  1219.  
  1220.    WinLoadString( hab,
  1221.                   (HMODULE) NULL,
  1222.                   IDS_HELP_LIBRARY_NAME,
  1223.                   (SHORT) sizeof( achHelpLibraryName),
  1224.                   achHelpLibraryName);
  1225.  
  1226.    memset ( &helpInit, 0, sizeof(helpInit) );
  1227.    /*
  1228.     * Initialize the help structure.
  1229.     */
  1230.    helpInit.cb                 = sizeof( helpInit);  /* size of the help struc*/
  1231.    helpInit.ulReturnCode       = (ULONG) 0;          /* RC from HM init       */
  1232.    helpInit.pszTutorialName    = (PSZ) NULL;         /* No tutorial program   */
  1233.    helpInit.pszHelpWindowTitle = achHelpWindowTitle; /* The Help window title.*/
  1234.    helpInit.fShowPanelId       = (ULONG) 0;          /* help panel ID.        */
  1235.    helpInit.pszHelpLibraryName = achHelpLibraryName; /* library name          */
  1236.    helpInit.phtHelpTable       = (PVOID)(0xffff0000 | ID_AUDIO_HELPTABLE);
  1237.  
  1238.    /*
  1239.     * Create the Help Instance for IPF.
  1240.     * Give IPF the Anchor Block handle and address of the IPF initialization
  1241.     * structure, and check that creation of Help was a success.
  1242.     */
  1243.    hwndHelpInstance = WinCreateHelpInstance(
  1244.                          hab,                   /* Anchor Block Handle.       */
  1245.                          &helpInit );           /* Help Structure.            */
  1246.  
  1247.    if ( hwndHelpInstance == (HWND) NULL)
  1248.    {
  1249.       MessageBox( IDS_HELP_CREATION_FAILED,     /* ID of the message          */
  1250.                   MB_OK | MB_INFORMATION  | MB_MOVEABLE);    /* style         */
  1251.    }
  1252.    else
  1253.    {
  1254.       if ( helpInit.ulReturnCode)
  1255.       {
  1256.          WinDestroyHelpInstance( hwndHelpInstance);
  1257.          MessageBox( IDS_HELP_CREATION_FAILED,     /* ID of the message       */
  1258.                      MB_OK | MB_INFORMATION | MB_MOVEABLE);     /* style      */
  1259.       }
  1260.       else  /* help creation worked */
  1261.          WinAssociateHelpInstance(
  1262.             hwndHelpInstance,        /* The handle of the Help Instance.      */
  1263.             hwndFrame);              /* Associate to this dialog window.      */
  1264.    }  /* End of IF checking the creation of the Help Instance. */
  1265.  
  1266. }  /* End of InitializeHelp */
  1267.  
  1268. /******************************************************************************
  1269.  * Name        : ProcuctInfoDlgProc
  1270.  *
  1271.  * Description : This function controls the product information dialog box.
  1272.  *
  1273.  * Concepts    : None.
  1274.  *
  1275.  * MMPM/2 API's: None.
  1276.  *
  1277.  * Parameters  : hwnd - Handle for the Include dialog box.
  1278.  *               msg  - Message received by the dialog box.
  1279.  *               mp1  - Parameter 1 for the just received message.
  1280.  *               mp2  - Parameter 2 for the just received message.
  1281.  *
  1282.  * Return      : 0 or the result of default processing.
  1283.  *
  1284.  ******************************************************************************/
  1285. MRESULT EXPENTRY ProductInfoDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
  1286. {
  1287.    switch( msg )
  1288.    {
  1289.      case WM_INITDLG :
  1290.          /*
  1291.           * Add Default Size menu item to system menu of the secondary window.
  1292.           */
  1293.          WinInsertDefaultSize(hwnd, "~DefaultSize");
  1294.          break;
  1295.  
  1296.      case WM_CLOSE :
  1297.          WinDestroySecondaryWindow( hwnd ); /* Close the Dialog box.          */
  1298.          return( 0 );
  1299.          break;
  1300.  
  1301.     case WM_DESTROY:
  1302.          hwndProductInfo = 0;
  1303.          break;
  1304.  
  1305.       case WM_COMMAND :
  1306.          switch( SHORT1FROMMP( mp1 ) )
  1307.          {
  1308.             case DID_OK :
  1309.  
  1310.             case DID_CANCEL:
  1311.                WinDestroySecondaryWindow( hwnd ); /* Close the Dialog box.          */
  1312.                return( (MRESULT)TRUE);
  1313.             break;
  1314.          }  /* End of Command Switch */
  1315.  
  1316.    }  /* End of Switch */
  1317.  
  1318.    return( WinDefSecondaryWindowProc( hwnd, msg, mp1, mp2 ) );
  1319.  
  1320. } /* End of FileDlgProc */
  1321.  
  1322. /******************************************************************************
  1323.  * Name         :  OpenTheFile
  1324.  *
  1325.  * Description  :  This procedure will Open the audio device with a specific
  1326.  *                 file loaded, if the audio device is not already opened.
  1327.  *                 If the audio device is open, an audio file will be loaded
  1328.  *                 onto it.
  1329.  *
  1330.  * Concepts     :  - Open a device using the MCI interface.
  1331.  *                 - Loading a file into an already open device.
  1332.  *
  1333.  * MMPM/2 API's :  mciSendCommand    MCI_OPEN
  1334.  *                                   MCI_LOAD
  1335.  *
  1336.  * Parameters   :  hwnd        - Handle for the Main dialog box.
  1337.  *                 pszFileName - selected file name to open
  1338.  *
  1339.  * Return       :  TRUE  -  if the operation was initiated without error.
  1340.  *                 FALSE -  if an error occurred.
  1341.  *
  1342.  ******************************************************************************/
  1343. BOOL OpenTheFile( HWND hwnd, PSZ pszFileName )
  1344. {
  1345.    ULONG          ulError;             /* return value for mci command        */
  1346.    MCI_LOAD_PARMS mciLoadParms;        /* load parms for MCI_LOAD             */
  1347.    BOOL           bReturn = TRUE;      /* function return value               */
  1348.  
  1349.  
  1350.    if (fFirstOpen)
  1351.    /* If this is the first time thru this routine, then we need to open
  1352.     * the device.
  1353.     *
  1354.     * On subsequent calls to this routine, the devices are already open,
  1355.     * so we only need to load the appropriate file onto the device.
  1356.     *
  1357.     */
  1358.    {
  1359.       /*
  1360.        * Update the status line with appropriate message.
  1361.        */
  1362.       UpdateTheStatusLine(hwnd, IDS_OPENINGDEVICE);
  1363.       /*
  1364.        * To Open the device, we will issue an MCI_OPEN command via
  1365.        * mciSendCommand using an MCI_OPEN_PARMS structure.  The device ID
  1366.        * will be returned in the device ID field of the open data structure.
  1367.        */
  1368.  
  1369.       memset( &mciOpenParms,            /* Object to fill with zeros.       */
  1370.               0,                        /* Value to place into the object.  */
  1371.               sizeof( mciOpenParms ) ); /* How many zero's to use.          */
  1372.  
  1373.       mciOpenParms.hwndCallback = hwnd; /* For MM_MCIPASSDEVICE */
  1374.       mciOpenParms.usDeviceID   = (USHORT)  NULL; /* this is returned   */
  1375.  
  1376.       /*
  1377.        * Specify the device type. The pszDeviceType is to be interpreted as
  1378.        * the low-order word is a standard device type, and the high-order
  1379.        * word is the ordinal index for the device. In other words we are
  1380.        * explecitely trying to open the default device on the system. This
  1381.        * gives the ability to load a non existing (untitled) audio file.
  1382.        */
  1383.       mciOpenParms.pszDeviceType    = (PSZ) MAKEULONG(
  1384.                                               MCI_DEVTYPE_WAVEFORM_AUDIO,
  1385.                                               usDeviceTypeOpened);
  1386.  
  1387.       /*
  1388.        * Specify the name of the file to be opened.
  1389.        */
  1390.       mciOpenParms.pszElementName   = (PSZ)NULL;
  1391.  
  1392.       ulError = mciSendCommand( (USHORT) 0,
  1393.                                 MCI_OPEN,
  1394.                                 MCI_WAIT | MCI_OPEN_TYPE_ID |
  1395.                                 MCI_OPEN_SHAREABLE | MCI_OPEN_ELEMENT,
  1396.                                 (PVOID) &mciOpenParms,
  1397.                                 UP_OPEN);
  1398.       if (ulError)
  1399.       {
  1400.          ShowMCIErrorMessage( ulError);
  1401.          UpdateTheStatusLine(hwnd, IDS_STOPPED);
  1402.          bReturn = FALSE;
  1403.       }
  1404.       else
  1405.          /*
  1406.           * Open success, set the flag to indicate that next time thru this
  1407.           * routine we do not need to open the device.
  1408.           */
  1409.          fFirstOpen = FALSE;
  1410.    }
  1411.    else
  1412.    {
  1413.        /*
  1414.         * Change pointer to a waiting pointer first, since this might take a
  1415.         * couple of seconds.
  1416.         */
  1417.        WinSetPointer( HWND_DESKTOP, hptrWait );
  1418.  
  1419.        /*
  1420.         * The device is already open. We just need to load the appropriate
  1421.         * audio file.
  1422.         *
  1423.         * Update the status line with appropriate message.
  1424.         */
  1425.        UpdateTheStatusLine(hwnd, IDS_LOADINGFILE);
  1426.  
  1427.        mciLoadParms.hwndCallback     = (HWND) NULL;    /* We're waiting */
  1428.  
  1429.        /*
  1430.         * If we're not using a temporary file, load the filename.
  1431.         * Otherwise, just pass NULL as the filename and let the audio
  1432.         * device handle the temporary file for us.
  1433.         */
  1434.        if ( strcmp ( pszFileName, acTempFileName) )
  1435.           mciLoadParms.pszElementName   = (PSZ)pszFileName;
  1436.        else
  1437.           mciLoadParms.pszElementName   = (PSZ)NULL;
  1438.  
  1439.        ulError = mciSendCommand( mciOpenParms.usDeviceID,
  1440.                                  MCI_LOAD,
  1441.                                  MCI_WAIT,
  1442.                                  (PVOID) &mciLoadParms,
  1443.                                  (ULONG) NULL);
  1444.        if (ulError)
  1445.        {
  1446.           ShowMCIErrorMessage( ulError );  /* Display the error message      */
  1447.           UpdateTheStatusLine(hwnd, IDS_STOPPED);
  1448.           bReturn = FALSE;
  1449.        }
  1450.  
  1451.        /*
  1452.         * Now that we're done here, change the pointer back to the arrow.
  1453.         */
  1454.        WinSetPointer ( HWND_DESKTOP, hptrArrow );
  1455.    }
  1456.  
  1457.    if (bReturn)
  1458.       /*
  1459.        * Update the main window title bar with the selected file name.
  1460.        */
  1461.       UpdateTitleText(hwndFrame, pszFileName);
  1462.  
  1463.    return( bReturn);
  1464.  
  1465. }  /* end of OpenTheFile */
  1466.  
  1467. /******************************************************************************
  1468.  * Name         :  QueryTheDefaultConnection
  1469.  *
  1470.  * Description  :  This procedure will query the default connection and find
  1471.  *                 the device play/record capabilities. Also find the device
  1472.  *                 ability to play/record 16 bit audio files.
  1473.  *
  1474.  * Concepts     :  - Query the default device of waveaudio type.
  1475.  *                 - Get the ordinal value of the first device of the waveaudio.
  1476.  *
  1477.  * MMPM/2 API's :  mciSendCommand    MCI_SYSINFO
  1478.  *
  1479.  * Parameters   :  none
  1480.  *
  1481.  * Return       :  none
  1482.  *
  1483.  ******************************************************************************/
  1484. VOID QueryTheDefaultConnection( VOID )
  1485. {
  1486.    MCI_SYSINFO_PARMS         mciSysinfoParms;
  1487.    MCI_SYSINFO_DEFAULTDEVICE mciSysinfoDefaultdevice;
  1488.    MCI_SYSINFO_QUERY_NAME    mciSysinfoQueryName;
  1489.    ULONG                     ulError;
  1490.  
  1491.  
  1492.    memset( &mciSysinfoParms, 0, sizeof( mciSysinfoParms ) );
  1493.    memset( &mciSysinfoDefaultdevice, 0, sizeof(mciSysinfoDefaultdevice));
  1494.  
  1495.    /*
  1496.     * Set up parameters to query the default device for
  1497.     * MCI_DEVTYPE_WAVEFORM_AUDIO device type. If no explicit default exists,
  1498.     * then the first device of the indicated type is implicitely the default.
  1499.     *
  1500.     * First, initialize MCI_SYSINFO_PARMS and MCI_SYSINFO_DEFAULTDEVICE
  1501.     * structures with the pertinent information then issue MCI_SYSINFO
  1502.     * command via mciSendCommand. The pSysInfoParm field points to the
  1503.     * MCI_SYSINFO_DEFAULTDEVICE structure. The default device name will be
  1504.     * returned in the szInstallName field.
  1505.     */
  1506.    mciSysinfoParms.ulItem  = MCI_SYSINFO_QUERY_DEFAULT;
  1507.    mciSysinfoParms.pSysInfoParm  = &mciSysinfoDefaultdevice;
  1508.    mciSysinfoDefaultdevice.usDeviceType  = MCI_DEVTYPE_WAVEFORM_AUDIO;
  1509.  
  1510.    ulError = mciSendCommand( (USHORT) 0,
  1511.                              MCI_SYSINFO,
  1512.                              MCI_WAIT | MCI_SYSINFO_ITEM,
  1513.                              (PVOID) &mciSysinfoParms,
  1514.                              0);
  1515.  
  1516.    if (ulError == 0L)
  1517.    {
  1518.       memset( &mciSysinfoParms , 0, sizeof(MCI_SYSINFO_PARMS));
  1519.       memset( &mciSysinfoQueryName , 0, sizeof(MCI_SYSINFO_QUERY_NAME));
  1520.  
  1521.       /*
  1522.        * Set up parameters to query the device ordinal value. This message
  1523.        * query the given device name which is in the szInstallName field of the
  1524.        * MCI_SYSINFO_DEFAULTDEVICE structure and returns the ordinal value of
  1525.        * the first device of that type. The pSysInfoParm field points to the
  1526.        * MCI_SYSINFO_QUERY_NAME structure which has the default device name.
  1527.        */
  1528.       mciSysinfoParms.ulItem  = MCI_SYSINFO_QUERY_NAMES;
  1529.       mciSysinfoParms.pSysInfoParm  = &mciSysinfoQueryName;
  1530.       memmove( &mciSysinfoQueryName.szInstallName,
  1531.                &mciSysinfoDefaultdevice.szInstallName,
  1532.                sizeof(mciSysinfoQueryName.szInstallName ) );
  1533.  
  1534.       ulError = mciSendCommand( (USHORT) 0,
  1535.                                 MCI_SYSINFO,
  1536.                                 MCI_WAIT | MCI_SYSINFO_ITEM,
  1537.                                 (PVOID) &mciSysinfoParms,
  1538.                                 0);
  1539.       if (ulError == 0L)
  1540.          /*
  1541.           * Get the device type ordinal value for further use.
  1542.           */
  1543.          usDeviceTypeOpened = (USHORT)mciSysinfoQueryName.usDeviceOrd;
  1544.    }
  1545.  
  1546.    if (ulError)
  1547.       ShowMCIErrorMessage(ulError);
  1548.  
  1549.    return;
  1550. }
  1551. /******************************************************************************
  1552.  * Name         :  FindTheDeviceCapability
  1553.  *
  1554.  * Description  :  This procedure will determine whether or not the audio
  1555.  *                 device supports all of the items on the Type menu.
  1556.  *                 If any of these options are not supported, they will be
  1557.  *                 disabled.
  1558.  *
  1559.  * Concepts     :  - Find the capabilities of an audio device.
  1560.  *
  1561.  * MMPM/2 API's :  mciSendCommand    MCI_GETDEVCAPS
  1562.  *
  1563.  * Parameters   :  none
  1564.  *
  1565.  * Return       :  none
  1566.  *
  1567.  ******************************************************************************/
  1568. VOID  FindTheDeviceCapability( VOID )
  1569. {
  1570.     ULONG                     ulRC;            /* return code from api        */
  1571.     MCI_WAVE_GETDEVCAPS_PARMS mciAudioCaps;    /* Dev Caps data structure     */
  1572.  
  1573.     memset( &mciAudioCaps , 0, sizeof(MCI_WAVE_GETDEVCAPS_PARMS));
  1574.  
  1575.     /* Set up the fields of the mciAudioCaps structure to see if the
  1576.      * device supports the different options on the Type menu of this
  1577.      * sample program. These items include:
  1578.      * Mono or Stereo, 11 kHz or 22 kHz or 44 kHz, and 8 bit or 16 bit.
  1579.      * 12 different combinations are possible, so we will
  1580.      * issue the query 12 times.  If any of the options are not supported
  1581.      * in ONE combination, we will disable that option on the Type menu.
  1582.      * Play and Record will also be tested with this api, so we can disable
  1583.      * the Play and Record pushbuttons if the device does not support the
  1584.      * function.
  1585.      */
  1586.  
  1587.     /* Test to see if the device can play 11 kHz, 8 bit, mono files.     */
  1588.     mciAudioCaps.ulBitsPerSample = 8;
  1589.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1590.     mciAudioCaps.ulSamplesPerSec = 11025;
  1591.     mciAudioCaps.ulChannels      = 1;
  1592.     mciAudioCaps.ulFormatMode    = MCI_PLAY;
  1593.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1594.  
  1595.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1596.                            MCI_GETDEVCAPS,
  1597.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1598.                                 | MCI_GETDEVCAPS_ITEM,
  1599.                            (PVOID) &mciAudioCaps,
  1600.                            0);
  1601.     ulRC &= 0x0000FFFF;
  1602.     if (ulRC != MCIERR_SUCCESS)
  1603.     {
  1604.        EvaluateReturnCode (8, 11025, 1, ulRC);
  1605.     }
  1606.  
  1607.     /* Test to see if the device can record 11 kHz, 16 bit, mono files.  */
  1608.     mciAudioCaps.ulBitsPerSample = 16;
  1609.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1610.     mciAudioCaps.ulSamplesPerSec = 11025;
  1611.     mciAudioCaps.ulChannels      = 1;
  1612.     mciAudioCaps.ulFormatMode    = MCI_RECORD;
  1613.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1614.  
  1615.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1616.                            MCI_GETDEVCAPS,
  1617.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1618.                                 | MCI_GETDEVCAPS_ITEM,
  1619.                            (PVOID) &mciAudioCaps,
  1620.                            0);
  1621.     ulRC &= 0x0000FFFF;
  1622.     if (ulRC != MCIERR_SUCCESS)
  1623.     {
  1624.        EvaluateReturnCode (16, 11025, 1, ulRC);
  1625.     }
  1626.  
  1627.     /* Test to see if the device can play 22 kHz, 8 bit, mono files.     */
  1628.     mciAudioCaps.ulBitsPerSample = 8;
  1629.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1630.     mciAudioCaps.ulSamplesPerSec = 22050;
  1631.     mciAudioCaps.ulChannels      = 1;
  1632.     mciAudioCaps.ulFormatMode    = MCI_PLAY;
  1633.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1634.  
  1635.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1636.                            MCI_GETDEVCAPS,
  1637.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1638.                                 | MCI_GETDEVCAPS_ITEM,
  1639.                            (PVOID) &mciAudioCaps,
  1640.                            0);
  1641.     ulRC &= 0x0000FFFF;
  1642.     if (ulRC != MCIERR_SUCCESS)
  1643.     {
  1644.        EvaluateReturnCode (8, 22050, 1, ulRC);
  1645.     }
  1646.  
  1647.     /* Test to see if the device can record 22 kHz, 16 bit, mono files.  */
  1648.     mciAudioCaps.ulBitsPerSample = 16;
  1649.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1650.     mciAudioCaps.ulSamplesPerSec = 22050;
  1651.     mciAudioCaps.ulChannels      = 1;
  1652.     mciAudioCaps.ulFormatMode    = MCI_RECORD;
  1653.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1654.  
  1655.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1656.                            MCI_GETDEVCAPS,
  1657.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1658.                                 | MCI_GETDEVCAPS_ITEM,
  1659.                            (PVOID) &mciAudioCaps,
  1660.                            0);
  1661.     ulRC &= 0x0000FFFF;
  1662.     if (ulRC != MCIERR_SUCCESS)
  1663.     {
  1664.        EvaluateReturnCode (16, 22050, 1, ulRC);
  1665.     }
  1666.  
  1667.     /* Test to see if the device can play 44 kHz, 8 bit, mono files.     */
  1668.     mciAudioCaps.ulBitsPerSample = 8;
  1669.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1670.     mciAudioCaps.ulSamplesPerSec = 44100;
  1671.     mciAudioCaps.ulChannels      = 1;
  1672.     mciAudioCaps.ulFormatMode    = MCI_PLAY;
  1673.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1674.  
  1675.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1676.                            MCI_GETDEVCAPS,
  1677.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1678.                                 | MCI_GETDEVCAPS_ITEM,
  1679.                            (PVOID) &mciAudioCaps,
  1680.                            0);
  1681.     ulRC &= 0x0000FFFF;
  1682.     if (ulRC != MCIERR_SUCCESS)
  1683.     {
  1684.        EvaluateReturnCode (8, 44100, 1, ulRC);
  1685.     }
  1686.  
  1687.     /* Test to see if the device can record 44 kHz, 16 bit, mono files. */
  1688.     mciAudioCaps.ulBitsPerSample = 16;
  1689.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1690.     mciAudioCaps.ulSamplesPerSec = 44100;
  1691.     mciAudioCaps.ulChannels      = 1;
  1692.     mciAudioCaps.ulFormatMode    = MCI_RECORD;
  1693.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1694.  
  1695.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1696.                            MCI_GETDEVCAPS,
  1697.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1698.                                 | MCI_GETDEVCAPS_ITEM,
  1699.                            (PVOID) &mciAudioCaps,
  1700.                            0);
  1701.     ulRC &= 0x0000FFFF;
  1702.     if (ulRC != MCIERR_SUCCESS)
  1703.     {
  1704.        EvaluateReturnCode (16, 44100, 1, ulRC);
  1705.     }
  1706.  
  1707.     /* Test to see if the device can record 11 kHz, 8 bit, stereo files. */
  1708.     mciAudioCaps.ulBitsPerSample = 8;
  1709.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1710.     mciAudioCaps.ulSamplesPerSec = 11025;
  1711.     mciAudioCaps.ulChannels      = 2;
  1712.     mciAudioCaps.ulFormatMode    = MCI_RECORD;
  1713.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1714.  
  1715.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1716.                            MCI_GETDEVCAPS,
  1717.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1718.                                 | MCI_GETDEVCAPS_ITEM,
  1719.                            (PVOID) &mciAudioCaps,
  1720.                            0);
  1721.     ulRC &= 0x0000FFFF;
  1722.     if (ulRC != MCIERR_SUCCESS)
  1723.     {
  1724.        EvaluateReturnCode (8, 11025, 2, ulRC);
  1725.     }
  1726.  
  1727.     /* Test to see if the device can support playing 11 kHz, 16 bit, stereo files. */
  1728.     mciAudioCaps.ulBitsPerSample = 16;
  1729.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1730.     mciAudioCaps.ulSamplesPerSec = 11025;
  1731.     mciAudioCaps.ulChannels      = 2;
  1732.     mciAudioCaps.ulFormatMode    = MCI_PLAY;
  1733.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1734.  
  1735.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1736.                            MCI_GETDEVCAPS,
  1737.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1738.                                 | MCI_GETDEVCAPS_ITEM,
  1739.                            (PVOID) &mciAudioCaps,
  1740.                            0);
  1741.     ulRC &= 0x0000FFFF;
  1742.     if (ulRC != MCIERR_SUCCESS)
  1743.     {
  1744.        EvaluateReturnCode (16, 11025, 2, ulRC);
  1745.     }
  1746.  
  1747.  
  1748.     /* Test to see if the device can support recording 22 kHz, 8 bit, stereo files. */
  1749.     mciAudioCaps.ulBitsPerSample = 8;
  1750.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1751.     mciAudioCaps.ulSamplesPerSec = 22050;
  1752.     mciAudioCaps.ulChannels      = 2;
  1753.     mciAudioCaps.ulFormatMode    = MCI_RECORD;
  1754.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1755.  
  1756.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1757.                            MCI_GETDEVCAPS,
  1758.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1759.                                 | MCI_GETDEVCAPS_ITEM,
  1760.                            (PVOID) &mciAudioCaps,
  1761.                            0);
  1762.     ulRC &= 0x0000FFFF;
  1763.     if (ulRC != MCIERR_SUCCESS)
  1764.     {
  1765.        EvaluateReturnCode (8, 22050, 2, ulRC);
  1766.     }
  1767.  
  1768.     /* Test to see if the device can play 22 kHz, 16 bit, stereo files.  */
  1769.     mciAudioCaps.ulBitsPerSample = 16;
  1770.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1771.     mciAudioCaps.ulSamplesPerSec = 22050;
  1772.     mciAudioCaps.ulChannels      = 2;
  1773.     mciAudioCaps.ulFormatMode    = MCI_PLAY;
  1774.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1775.  
  1776.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1777.                            MCI_GETDEVCAPS,
  1778.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1779.                                 | MCI_GETDEVCAPS_ITEM,
  1780.                            (PVOID) &mciAudioCaps,
  1781.                            0);
  1782.     ulRC &= 0x0000FFFF;
  1783.     if (ulRC != MCIERR_SUCCESS)
  1784.     {
  1785.        EvaluateReturnCode (16, 22050, 2, ulRC);
  1786.     }
  1787.  
  1788.     /* Test to see if the device can record 44 kHz, 8 bit, stereo files. */
  1789.     mciAudioCaps.ulBitsPerSample = 8;
  1790.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1791.     mciAudioCaps.ulSamplesPerSec = 44100;
  1792.     mciAudioCaps.ulChannels      = 2;
  1793.     mciAudioCaps.ulFormatMode    = MCI_RECORD;
  1794.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1795.  
  1796.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1797.                            MCI_GETDEVCAPS,
  1798.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1799.                                 | MCI_GETDEVCAPS_ITEM,
  1800.                            (PVOID) &mciAudioCaps,
  1801.                            0);
  1802.     ulRC &= 0x0000FFFF;
  1803.     if (ulRC != MCIERR_SUCCESS)
  1804.     {
  1805.        EvaluateReturnCode (8, 44100, 2, ulRC);
  1806.     }
  1807.  
  1808.     /* Test to see if the device  can play 44 kHz, 16 bit, stereo files.  */
  1809.     mciAudioCaps.ulBitsPerSample = 16;
  1810.     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
  1811.     mciAudioCaps.ulSamplesPerSec = 44100;
  1812.     mciAudioCaps.ulChannels      = 2;
  1813.     mciAudioCaps.ulFormatMode    = MCI_PLAY;
  1814.     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
  1815.  
  1816.     ulRC = mciSendCommand (mciOpenParms.usDeviceID,       /* Device ID        */
  1817.                            MCI_GETDEVCAPS,
  1818.                            MCI_WAIT | MCI_GETDEVCAPS_EXTENDED
  1819.                                 | MCI_GETDEVCAPS_ITEM,
  1820.                            (PVOID) &mciAudioCaps,
  1821.                            0);
  1822.     ulRC &= 0x0000FFFF;
  1823.     if (ulRC != MCIERR_SUCCESS)
  1824.     {
  1825.        EvaluateReturnCode (16, 44100, 2, ulRC);
  1826.     }
  1827.  
  1828.     return;
  1829. }
  1830.  
  1831. /******************************************************************************
  1832.  * Name         :  EvaluateReturnCode
  1833.  *
  1834.  * Description  :  This procedure will evaluate the return code from the
  1835.  *                 mciSendCommand - MCI_GETDEVCAPS.  It will disable the
  1836.  *                 appropriate items on the Recorder's main window and on
  1837.  *                 the Recorder's Type menu.
  1838.  *
  1839.  * Concepts     :  None
  1840.  *
  1841.  * MMPM/2 API's :  None
  1842.  *
  1843.  * Parameters   :  ULONG ulBitsPerSample        Either 8 or 16
  1844.  *                 ULONG ulSampPerSec           Either 11025, 22050, or 44100
  1845.  *                 ULONG ulChannels             Either 1 or 2
  1846.  *                 ULONG ulRC                   Return code to evaluate
  1847.  *
  1848.  * Return       :  VOID
  1849.  *
  1850.  ******************************************************************************/
  1851. VOID EvaluateReturnCode( ULONG ulBitsPerSample,
  1852.                          ULONG ulSampPerSec,
  1853.                          ULONG ulChannels,
  1854.                          ULONG ulRC)
  1855. {
  1856.  
  1857.  
  1858.     /* The return code indicates unsupported samples per second value. */
  1859.     if (ulRC == MCIERR_UNSUPP_SAMPLESPERSEC)
  1860.     {
  1861.        /* Samples per second value was 11.025 kHz */
  1862.        if (ulSampPerSec == 11025)
  1863.        {
  1864.           /* Disable the "Voice" option on the Type menu */
  1865.           DisableTheOption(
  1866.              WinWindowFromID(
  1867.                 WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1868.                 IDM_VOICE );
  1869.           fVoiceSupported = FALSE;
  1870.        }
  1871.        else
  1872.        /* Samples per second value was 22.050 kHz */
  1873.        if (ulSampPerSec == 22050)
  1874.        {
  1875.           /* Disable the "Music" option on the Type menu */
  1876.           DisableTheOption(
  1877.              WinWindowFromID(
  1878.                 WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1879.                 IDM_MUSIC );
  1880.           fMusicSupported = FALSE;
  1881.        }
  1882.        else
  1883.        /* Samples per second value was 44.100 kHz */
  1884.        {
  1885.           /* Disable the "High Fidelity" option on the Type menu */
  1886.           DisableTheOption(
  1887.              WinWindowFromID(
  1888.                 WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1889.                 IDM_HIGH_FIDELITY );
  1890.           fHiFiSupported = FALSE;
  1891.        }
  1892.     }
  1893.  
  1894.     /* The return code indicates unsupported bits per sample value. */
  1895.     if (ulRC == MCIERR_UNSUPP_BITSPERSAMPLE)
  1896.     {
  1897.        /* Samples per second value was 8 */
  1898.        if (ulBitsPerSample == 8)
  1899.        {
  1900.           /* Disable the "Low quality" item on the Options menu. */
  1901.           DisableTheOption(
  1902.              WinWindowFromID(
  1903.                 WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1904.                 IDM_LOW_QUALITY );
  1905.           fLoQualitySupported = FALSE;
  1906.        }
  1907.        else
  1908.        /* Samples per second value was 16 */
  1909.        {
  1910.           /* Disable the "High quality" item on the Options menu. */
  1911.           DisableTheOption(
  1912.              WinWindowFromID(
  1913.                 WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1914.                 IDM_HIGH_QUALITY );
  1915.           fHighQualitySupported = FALSE;
  1916.        }
  1917.     }
  1918.  
  1919.     /* The return code indicates unsupported channels value. */
  1920.     if (ulRC == MCIERR_UNSUPP_CHANNELS)
  1921.     {
  1922.        /* Stereo is not supported */
  1923.        if (ulChannels == 2)
  1924.        {
  1925.           DeselectTheOption( IDM_STEREO );     /* Deselect the "Stereo" option*/
  1926.           DisableTheOption(
  1927.              WinWindowFromID(
  1928.                 WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1929.                 IDM_STEREO );
  1930.           SelectTheOption( IDM_MONO );         /* Select the "Mono" option    */
  1931.           usStereoMono        =  MONO;         /* Set the usStereoMono to Mono*/
  1932.           fStereoSupported = FALSE;
  1933.        }
  1934.        else /* Mono is not supported */
  1935.        {
  1936.           DeselectTheOption( IDM_MONO );     /* Deselect the "Stereo" option*/
  1937.           DisableTheOption(
  1938.              WinWindowFromID(
  1939.                 WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1940.                 IDM_MONO );
  1941.           SelectTheOption( IDM_STEREO );         /* Select the "Mono" option    */
  1942.           usStereoMono        =  STEREO;         /* Set the usStereoMono to Mono*/
  1943.           fMonoSupported = FALSE;
  1944.        }
  1945.     }
  1946.  
  1947.     /* The return code indicates unsupported mode value. */
  1948.     if (ulRC == MCIERR_UNSUPP_FORMAT_MODE)
  1949.     {
  1950.        /*
  1951.         * If the device doesn't support either play or record,
  1952.         * then do the following disables.
  1953.         */
  1954.  
  1955.        WinEnableWindow (hwndPlayPB, FALSE);  /* Disable the Play pushbutton.  */
  1956.        WinEnableWindow (hwndRecordPB, FALSE);/* Disable the Record pushbutton.*/
  1957.  
  1958.        DisableTheOption(                     /* Disable the "New"  option     */
  1959.           WinWindowFromID(
  1960.              WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1961.              IDM_FILE_NEW );
  1962.  
  1963.        DisableTheOption(                     /* Disable the "Save"  option    */
  1964.           WinWindowFromID(
  1965.              WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1966.              IDM_FILE_SAVE );
  1967.  
  1968.        DisableTheOption(                     /* Disable the "Save as" option  */
  1969.           WinWindowFromID(
  1970.              WinQuerySecondaryFrame(hwndMainDialogBox), FID_MENU ),
  1971.              IDM_FILE_SAVE_AS );
  1972.     }
  1973.     return;
  1974. }
  1975.  
  1976. /******************************************************************************
  1977.  * Name         :  PlayTheAudio
  1978.  *
  1979.  * Description  :  This procedure will begin the playing of an audio file.
  1980.  *                 It is invoked when the user selects the Play pushbutton
  1981.  *                 on the Recorders main window.
  1982.  *
  1983.  * Concepts     :  Playing a audio file using the MCI interface.
  1984.  *
  1985.  * MMPM/2 API's :  mciSendCommand    MCI_PLAY
  1986.  *
  1987.  * Parameters   :  hwnd - Handle for the Main dialog box.
  1988.  *
  1989.  * Return       :  TRUE  -  if the operation was initiated without error.
  1990.  *                 FALSE -  if an error occurred.
  1991.  *
  1992.  ******************************************************************************/
  1993. BOOL PlayTheAudio( HWND hwnd)
  1994. {
  1995.    ULONG             ulError;                /* error value from mci calls    */
  1996.    MCI_PLAY_PARMS    mciPlayParms;           /* play parms for MCI_PLAY       */
  1997.  
  1998.    /*
  1999.     * In this sample program we are always going to play the audio from the
  2000.     * begining of the file.
  2001.     */
  2002.    if (!SeekTheAudio( hwnd, MCI_TO_START ))
  2003.       return( FALSE );
  2004.  
  2005.    eState = ST_PLAYING;                      /* set state to PLAYING          */
  2006.    SetAudioVolume(hwnd);                     /* set the starting volume       */
  2007.  
  2008.    /*
  2009.     * Initialize MCI_PLAY_PARMS structure with the pertinent information then
  2010.     * issue an MCI_PLAY command via mciSendCommand. A MM_MCINOTIFY message
  2011.     * will be sent to the window specified in hwndCallback field when the
  2012.     * operation is completed. Since we want the whole audio file to be played,
  2013.     * we won't specify flags MCI_FROM or MCI_TO.
  2014.     */
  2015.    mciPlayParms.hwndCallback = hwnd;         /* notify our window             */
  2016.  
  2017.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2018.                              MCI_PLAY,
  2019.                              MCI_NOTIFY,
  2020.                              (PVOID) &mciPlayParms,
  2021.                              UP_PLAY);
  2022.    if (ulError)
  2023.    {
  2024.       /*
  2025.        * If we couldn't play - we need to display the error to the user, halt
  2026.        * audio gracefully and get to stable, known state.
  2027.        */
  2028.       ShowMCIErrorMessage( ulError);
  2029.       eState = ST_STOPPED;
  2030.       StopTheDevice(hwnd);
  2031.       return ( FALSE );
  2032.    }
  2033.    return( TRUE );
  2034. }  /* end of PlayTheAudio */
  2035.  
  2036.  
  2037. /******************************************************************************
  2038.  * Name         : RecordTheAudio
  2039.  *
  2040.  * Description  : This procedure records an audio file.  In order to do this
  2041.  *                it first configures the device settings (such as input level
  2042.  *                and input source) and file attributes (such as sample size
  2043.  *                and sample rate). Finally, it records the audio data. It is
  2044.  *                invoked when the user selects the record pushbutton from the
  2045.  *                Recorder's main window.
  2046.  *
  2047.  * Concepts     : - Record an audio file using MCI interface.
  2048.  *                - Setup device and file for recording.
  2049.  *
  2050.  * MMPM/2 API's : mciSendCommand  MCI_SET
  2051.  *                                MCI_CONNECTION
  2052.  *                                MCI_CONNECTOR
  2053.  *                                MCI_RECORD
  2054.  *
  2055.  *
  2056.  * Parameters   : hwnd - Handle for the Main dialog box.
  2057.  *
  2058.  * Return       :  TRUE  -  if the operation was initiated without error.
  2059.  *                 FALSE -  if an error occurred.
  2060.  ******************************************************************************/
  2061. BOOL RecordTheAudio( HWND hwnd )
  2062. {
  2063.    MCI_RECORD_PARMS     mciRecordParms;      /* for MCI_RECORD                */
  2064.    MCI_CONNECTOR_PARMS  mciConnectorParms;   /* for MCI_CONNECTOR             */
  2065.    MCI_WAVE_SET_PARMS   mciWaveSetParms;     /* for MCI_SET, waveform devices */
  2066.    MCI_GENERIC_PARMS    mciGenericParms;     /* for MCI_ACQUIRE               */
  2067.    MCI_AMP_SET_PARMS    mciAmpSetParms;      /* for MCI_SET, amp/mix devices  */
  2068.    MCI_CONNECTION_PARMS mciConnectionParms;  /* for MCI_CONNECTION            */
  2069.    USHORT               usAmpMixerDeviceID;  /* for amp/mix device ID         */
  2070.    LONG                 lmmioAPIRc;          /* MMIO API return codes         */
  2071.    ULONG                ulError;             /* for error return code         */
  2072.  
  2073.  
  2074.    memset( &mciWaveSetParms,            /* Object to fill with zeros.      */
  2075.            0,                           /* Value to place into the object. */
  2076.            sizeof( mciWaveSetParms ) ); /* How many zero's to use.         */
  2077.  
  2078.    /*
  2079.     * Set up parameters for the audio data file (such as stereo/mono, sample
  2080.     * rate and sample size).
  2081.     *
  2082.     * First, initialize MCI_WAVE_SET_PARMS structure with the pertinent
  2083.     * information then issue an MCI_SET command via mciSendCommand.
  2084.     */
  2085.    mciWaveSetParms.usChannels = (USHORT) usStereoMono;  /* specify MONO/STEREO*/
  2086.    mciWaveSetParms.ulSamplesPerSec =
  2087.                              (ULONG) usQualityType;  /* used for waveform  */
  2088.    mciWaveSetParms.usBitsPerSample = (USHORT) usBitType;/* bits per sample */
  2089.  
  2090.    ulError =
  2091.      mciSendCommand( mciOpenParms.usDeviceID,
  2092.                      MCI_SET,
  2093.                      MCI_WAIT | MCI_WAVE_SET_CHANNELS |
  2094.                      MCI_WAVE_SET_SAMPLESPERSEC |
  2095.                      MCI_WAVE_SET_BITSPERSAMPLE,
  2096.                      (PVOID) &mciWaveSetParms,
  2097.                      UP_SET );
  2098.    if (ulError)
  2099.    {
  2100.       ShowMCIErrorMessage( ulError);
  2101.       return( FALSE);
  2102.    }
  2103.  
  2104.    /*
  2105.     * Initialize MCI_CONNECTOR_PARMS structure with zero's
  2106.     */
  2107.    memset( &mciConnectorParms,            /* Object to fill with zeros.       */
  2108.            0,                             /* Value to place into the object.  */
  2109.            sizeof( mciConnectorParms ) ); /* How many zero's to use.          */
  2110.  
  2111.    /*
  2112.     * Set up input source - microphone or line in.
  2113.     * initialize MCI_CONNECTOR_PARMS structure with the pertinent
  2114.     * information then issue an MCI_CONNECTOR command via mciSendCommand.
  2115.     */
  2116.    mciConnectorParms.ulConnectorType = usDeviceType; /* microphone/linein  */
  2117.  
  2118.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2119.                              MCI_CONNECTOR,
  2120.                              MCI_WAIT | MCI_CONNECTOR_TYPE |
  2121.                              MCI_ENABLE_CONNECTOR,
  2122.                              (PVOID) &mciConnectorParms,
  2123.                              0 );
  2124.    if (ulError)
  2125.    {
  2126.       ShowMCIErrorMessage( ulError);
  2127.       return( FALSE);
  2128.    }
  2129.  
  2130.    /*
  2131.     * Initialize MCI_CONNECTION_PARMS structure with zero's
  2132.     */
  2133.    memset( &mciConnectionParms,           /* Object to fill with zeros.       */
  2134.            0,                             /* Value to place into the object.  */
  2135.            sizeof( mciConnectionParms ) );/* How many zero's to use.          */
  2136.  
  2137.    /*
  2138.     * Get the Amp/Mixer device ID.
  2139.     *
  2140.     * First, initialize MCI_CONNECTION_PARMS structure ulConnectorType with
  2141.     * the MCI_WAVE_STREAM_CONNECTOR. The digital input or output for the
  2142.     * waveform audio device is streamed to an Amp/Mixer device.
  2143.     */
  2144.    mciConnectionParms.ulConnectorType  =   MCI_WAVE_STREAM_CONNECTOR;
  2145.  
  2146.    /*
  2147.     * Next, issue an MCI_CONNECTION command via mciSendCommand. This will
  2148.     * return the Amp/Mixer device ID.
  2149.     */
  2150.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2151.                              MCI_CONNECTION,
  2152.                              MCI_WAIT | MCI_QUERY_CONNECTION |
  2153.                              MCI_CONNECTOR_TYPE,
  2154.                              (PVOID) &mciConnectionParms,
  2155.                              UP_CONNECTION );
  2156.    if (ulError)
  2157.    {
  2158.       ShowMCIErrorMessage( ulError);
  2159.       return( FALSE);
  2160.    }
  2161.  
  2162.    /*
  2163.     * Amp/Mixer device ID is needed to control the "Monitor input" and the
  2164.     * "Input level" off of the Options menu.
  2165.     */
  2166.    usAmpMixerDeviceID = mciConnectionParms.usToDeviceID;
  2167.  
  2168.    /*
  2169.     * Initialize MCI_AMP_SET_PARMS structure with zero's
  2170.     */
  2171.    memset( &mciAmpSetParms,            /* Object to fill with zeros.       */
  2172.            0,                          /* Value to place into the object.  */
  2173.            sizeof( mciAmpSetParms ) ); /* How many zero's to use.          */
  2174.  
  2175.    /*
  2176.     * Set the Monitor on if the user requested it.
  2177.     */
  2178.    if ( fMonitor )
  2179.    {
  2180.       /*
  2181.        * User selected the "Monitor input" item from the Options menu - turn
  2182.        * the monitor ON.
  2183.        * First, initialize MCI_AMP_SET_PARMS structure ulItem with
  2184.        * MCI_AMP_SET_MONITOR.  Using this in conjunction with the MCI_SET_ON
  2185.        * flag will instruct the ampmix device to monitor the currently
  2186.        * selected connector.  This item is used to listen to (monitor) a
  2187.        * source while it is being recorded.
  2188.        */
  2189.       mciAmpSetParms.ulItem     = MCI_AMP_SET_MONITOR;
  2190.  
  2191.       /*
  2192.        * Next, issue an MCI_SET command via mciSendCommand. This message will
  2193.        * turn the monitor ON.
  2194.        */
  2195.       ulError = mciSendCommand( usAmpMixerDeviceID,
  2196.                                 MCI_SET,
  2197.                                 MCI_WAIT | MCI_SET_ITEM | MCI_SET_ON,
  2198.                                 (PVOID) &mciAmpSetParms,
  2199.                                 UP_SETMONITOR );
  2200.    }
  2201.    else
  2202.    {
  2203.       /*
  2204.        * User deselected the "Monitor input" item from the Options menu - turn
  2205.        * the monitor OFF.
  2206.        * First, initialize MCI_AMP_SET_PARMS structure ulItem with
  2207.        * MCI_AMP_SET_MONITOR.  Using this in conjunction with the MCI_SET_OFF
  2208.        * flag will instruct the ampmix device to NOT to monitor the currently
  2209.        * selected connector.
  2210.        */
  2211.       mciAmpSetParms.ulItem     = MCI_AMP_SET_MONITOR;
  2212.  
  2213.       /*
  2214.        * Next, issue an MCI_SET command via mciSendCommand.  This message will
  2215.        * turn the monitor OFF.
  2216.        */
  2217.       ulError = mciSendCommand( usAmpMixerDeviceID,
  2218.                                 MCI_SET,
  2219.                                 MCI_WAIT | MCI_SET_ITEM | MCI_SET_OFF,
  2220.                                 (PVOID) &mciAmpSetParms,
  2221.                                 UP_SETMONITOR );
  2222.    }
  2223.  
  2224.    if (ulError)
  2225.    {
  2226.       ShowMCIErrorMessage( ulError);
  2227.       return( FALSE);
  2228.    }
  2229.    /*
  2230.     * Set the appropriate input level.
  2231.     * Initialize MCI_AMP_SET_PARMS structure with the pertinent
  2232.     * information then issue an MCI_SET command via mciSendCommand.
  2233.     */
  2234.    mciAmpSetParms.ulAudio    = MCI_SET_AUDIO_ALL;    /* all the channels. */
  2235.    mciAmpSetParms.ulLevel    = (ULONG) usInputLevel; /* set audio level.  */
  2236.  
  2237.    ulError = mciSendCommand( usAmpMixerDeviceID,
  2238.                              MCI_SET,
  2239.                              MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN,
  2240.                              (PVOID) &mciAmpSetParms,
  2241.                              UP_SETAMP );
  2242.    if (ulError)
  2243.    {
  2244.       ShowMCIErrorMessage( ulError);
  2245.       return( FALSE);
  2246.    }
  2247.  
  2248.    /*
  2249.     * Now all the setup is done - Ready to Record.
  2250.     *
  2251.     * First, initialize MCI_RECORD_PARMS structure with zero's
  2252.     */
  2253.    memset( &mciRecordParms,            /* Object to fill with zeros.       */
  2254.            0,                          /* Value to place into the object.  */
  2255.            sizeof( mciRecordParms ) ); /* How many zero's to use.          */
  2256.  
  2257.    /*
  2258.     * Next, initialize MCI_RECORD_PARMS structure with the pertinent
  2259.     * information then issue an MCI_RECORD command via mciSendCommand.
  2260.     */
  2261.    mciRecordParms.hwndCallback = hwnd; /* notify main window     */
  2262.  
  2263.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2264.                              MCI_RECORD,
  2265.                              MCI_NOTIFY | MCI_RECORD_OVERWRITE,  /* flags */
  2266.                              (PVOID) &mciRecordParms,
  2267.                              UP_RECORD );
  2268.    if (ulError)
  2269.    {
  2270.       ShowMCIErrorMessage( ulError );
  2271.       StopTheDevice(hwnd);
  2272.       return(FALSE);
  2273.    }
  2274.    else
  2275.    {
  2276.      fModified = TRUE;
  2277.      eState    = ST_RECORDING;
  2278.      UpdateTheStatusLine(hwnd, IDS_RECORDING);
  2279.      /*
  2280.       * Start record button animation
  2281.       */
  2282.      WinSendMsg ( hwndRecordPB,              /* Record push button handle  */
  2283.                   GBM_ANIMATE,               /* Animation control          */
  2284.                   MPFROMSHORT(TRUE),         /* Animation flag             */
  2285.                   NULL );                    /* Ignore return data         */
  2286.    }
  2287.    return( TRUE );
  2288.  
  2289. }  /* End of RecordTheAudio*/
  2290.  
  2291.  
  2292. /******************************************************************************
  2293.  * Name         :  SeekTheAudio
  2294.  *
  2295.  * Description  :  This procedure will Seek to the specified position in
  2296.  *                 an audio file.
  2297.  *
  2298.  * Concepts     :  Changing the current position in an audio file using the
  2299.  *                 MCI interface.
  2300.  *
  2301.  * MMPM/2 API's :  mciSendCommand    MCI_SEEK
  2302.  *
  2303.  * Parameters   :  hwnd       - Handle for the Main dialog box.
  2304.  *                 ulPosition - seeking position.
  2305.  *
  2306.  * Return       :  TRUE  -  if the operation was initiated without error.
  2307.  *                 FALSE -  if an error occurred.
  2308.  *
  2309.  ******************************************************************************/
  2310. BOOL SeekTheAudio(HWND hwnd, ULONG ulPosition )
  2311. {
  2312.    MCI_SEEK_PARMS  mciSeekParms;     /* for MCI_SEEK                  */
  2313.    ULONG           ulError;          /* return value for mci command  */
  2314.    BOOL            bReturn = TRUE;   /* function return value         */
  2315.  
  2316.  
  2317.    memset( &mciSeekParms,            /* Object to fill with zeros.       */
  2318.            0,                        /* Value to place into the object.  */
  2319.            sizeof( mciSeekParms ) ); /* How many zero's to use.          */
  2320.  
  2321.    mciSeekParms.hwndCallback = hwnd;
  2322.  
  2323.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2324.                              MCI_SEEK,
  2325.                              MCI_WAIT | ulPosition,
  2326.                              (PVOID) &mciSeekParms,
  2327.                              UP_SEEK);
  2328.    /*
  2329.     * If the recorder is currently recording
  2330.     */
  2331.    if (eState == ST_RECORDING)
  2332.    {
  2333.       /*
  2334.        * Stop the record button animation
  2335.        */
  2336.       WinSendMsg ( hwndRecordPB,                /* Record push button handle  */
  2337.                    GBM_ANIMATE,                 /* Animation control          */
  2338.                    MPFROMSHORT(FALSE),          /* Animation flag             */
  2339.                    NULL );                      /* Ignore return data         */
  2340.       eState = ST_STOPPED;                      /* Set state to stopped       */
  2341.    }
  2342.    /*
  2343.     * If the recorder is currently playing
  2344.     */
  2345.    else if (eState == ST_PLAYING)
  2346.    {
  2347.       /*
  2348.        * Stop the play button animation
  2349.        */
  2350.       WinSendMsg( hwndPlayPB,                    /* Play push button handle   */
  2351.                   GBM_ANIMATE,                   /* Animation control         */
  2352.                   MPFROMSHORT(FALSE),            /* Animation flag            */
  2353.                   NULL );                        /* Ignore return data        */
  2354.       eState = ST_STOPPED;                       /* Set state to stopped      */
  2355.    }
  2356.  
  2357.    if (ulError) {                             /* If an error     */
  2358.       ShowMCIErrorMessage( ulError);
  2359.       bReturn = FALSE;
  2360.    }
  2361.    /*
  2362.     * Update the status line with appropriate message.
  2363.     */
  2364.    UpdateTheStatusLine(hwnd, IDS_STOPPED);
  2365.  
  2366.    return( bReturn );
  2367. }  /* end of SeekTheAudio */
  2368.  
  2369.  
  2370. /******************************************************************************
  2371.  * Name         :  StopTheDevice
  2372.  *
  2373.  * Description  :  This procedure will stop the device that is playing or
  2374.  *                 recording.
  2375.  *
  2376.  * Concepts     :  Stopping a device using the MCI interface.
  2377.  *
  2378.  * MMPM/2 API's :  mciSendCommand    MCI_STOP
  2379.  *
  2380.  * Parameters   :  hwnd - Handle for the Main dialog box.
  2381.  *
  2382.  * Return       :  nothing.
  2383.  *
  2384.  ******************************************************************************/
  2385. VOID StopTheDevice(HWND hwnd)
  2386. {
  2387.    ULONG                ulError;          /* return value for mci command  */
  2388.    MCI_GENERIC_PARMS    mciGenericParms;  /* info data structure for cmd.  */
  2389.  
  2390.  
  2391.    /*
  2392.     * To stop the device , we will issue an MCI_STOP command via mciSendCommand
  2393.     * using an MCI_GENERIC_PARMS structure.  This stop command is done for
  2394.     * the device ID.
  2395.     */
  2396.    mciGenericParms.hwndCallback = hwndMainDialogBox;
  2397.  
  2398.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2399.                              MCI_STOP,
  2400.                              MCI_WAIT,
  2401.                              (PVOID) &mciGenericParms,
  2402.                              UP_STOP);
  2403.    if (ulError)
  2404.       ShowMCIErrorMessage( ulError);
  2405.  
  2406.    if (eState == ST_RECORDING)
  2407.    {
  2408.       /*
  2409.        * Stop the record button animation
  2410.        */
  2411.       WinSendMsg ( hwndRecordPB,                /* Record push button handle  */
  2412.                    GBM_ANIMATE,                 /* Animation control          */
  2413.                    MPFROMSHORT(FALSE),          /* Animation flag             */
  2414.                    NULL );                      /* Ignore return data         */
  2415.    }
  2416.    else
  2417.    {
  2418.       /*
  2419.        * Stop the play button animation
  2420.        */
  2421.       WinSendMsg( hwndPlayPB,                    /* Play push button handle   */
  2422.                   GBM_ANIMATE,                   /* Animation control         */
  2423.                   MPFROMSHORT(FALSE),            /* Animation flag            */
  2424.                   NULL );                        /* Ignore return data        */
  2425.    }
  2426.  
  2427.    /*
  2428.     * Update the status line with appropriate message.
  2429.     */
  2430.    UpdateTheStatusLine(hwnd, IDS_STOPPED);
  2431.    eState = ST_STOPPED;
  2432.  
  2433.    return;
  2434. }  /* end of StopTheDevice */
  2435.  
  2436.  
  2437. /******************************************************************************
  2438.  * Name         :  SaveTheAudio
  2439.  *
  2440.  * Description  :  This procedure will save the audio file that is currently
  2441.  *                 loaded.
  2442.  *
  2443.  * Concepts     :  Save an audio file using MCI interface.
  2444.  *
  2445.  * MMPM/2 API's :  mciSendCommand    MCI_SAVE
  2446.  *
  2447.  * Parameters   :  hwnd - Handle for the Main dialog box.
  2448.  *
  2449.  * Return       :  nothing.
  2450.  *
  2451.  ******************************************************************************/
  2452. VOID SaveTheAudio(HWND hwnd)
  2453. {
  2454.    ULONG                ulError;          /* return value for mci command  */
  2455.    MCI_GENERIC_PARMS    mciGenericParms;  /* info data structure for cmd.  */
  2456.    MCI_SAVE_PARMS       mciSaveParms;
  2457.  
  2458.  
  2459.    /*
  2460.     * Change pointer to a waiting pointer first, since this might take a
  2461.     * couple of seconds.
  2462.     */
  2463.    WinSetPointer ( HWND_DESKTOP, hptrWait );
  2464.  
  2465.    /*
  2466.     * Update the status line with appropriate message.
  2467.     */
  2468.    UpdateTheStatusLine(hwnd, IDS_SAVINGFILE);
  2469.  
  2470.    memset( &mciSaveParms,            /* Object to fill with zeros.       */
  2471.            0,                        /* Value to place into the object.  */
  2472.            sizeof( mciSaveParms ) ); /* How many zero's to use.          */
  2473.    /*
  2474.     * Initialize the MCI_SAVE_PARMS data structure with the pertinent
  2475.     * information then issue an MCI_SAVE command via mciSendCommand
  2476.     * to save the currently opened audio file.
  2477.     */
  2478.    mciSaveParms.hwndCallback = hwnd;
  2479.    mciSaveParms.pszFileName = (PSZ)szFileName;   /* audio file to save      */
  2480.  
  2481.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2482.                              MCI_SAVE,
  2483.                              MCI_WAIT | MCI_SAVE_FILE,
  2484.                              (PVOID) &mciSaveParms,
  2485.                              0 );
  2486.    /*
  2487.     * Change the pointer back to an arrow and update the status line with the
  2488.     * appropriate message.
  2489.     */
  2490.    WinSetPointer ( HWND_DESKTOP, hptrArrow );
  2491.    UpdateTheStatusLine(hwnd, IDS_STOPPED);
  2492.    if (ulError)
  2493.    {
  2494.       MessageBox( IDS_CANNOT_SAVE_FILE,                /* ID of the message  */
  2495.                   MB_OK | MB_ERROR  | MB_MOVEABLE);    /* style              */
  2496.       return;
  2497.    }
  2498.  
  2499.    /*
  2500.     * Get the currently loaded file header information and check the correct
  2501.     * options disable all the other option options in the Type menu pulldown.
  2502.     */
  2503.    SetTheOptions(EXISTING_FILE);
  2504.  
  2505.  
  2506.    /*
  2507.     * File has been saved. Set the flags.
  2508.     */
  2509.    fTempFileInUse = FALSE;
  2510.    fModified      = FALSE;
  2511.    return;
  2512. }
  2513.  
  2514. /******************************************************************************
  2515.  * Name         :  CloseTheDevice
  2516.  *
  2517.  * Description  :  This procedure will close the audio device.
  2518.  *
  2519.  * Concepts     :  Closing a device using MCI interface.
  2520.  *
  2521.  * MMPM/2 API's :  mciSendCommand    MCI_CLOSE
  2522.  *
  2523.  * Parameters   :  None.
  2524.  *
  2525.  * Return       :  nothing.
  2526.  *
  2527.  ******************************************************************************/
  2528.  
  2529. VOID CloseTheDevice( VOID)
  2530. {
  2531.    ULONG                ulError;          /* return value for mci command  */
  2532.    MCI_GENERIC_PARMS    mciGenericParms;  /* info data structure for cmd.  */
  2533.  
  2534.    /*
  2535.     * Now, we close the device. This is done by issuing MCI_CLOSE command.
  2536.     */
  2537.    ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2538.                              MCI_CLOSE,
  2539.                              MCI_WAIT,
  2540.                              (PVOID) &mciGenericParms,
  2541.                              UP_CLOSE);
  2542.    if (ulError)
  2543.       ShowMCIErrorMessage( ulError);
  2544.  
  2545.    mciOpenParms.usDeviceID = (USHORT) NULL;
  2546.  
  2547.    return;
  2548.  
  2549. }  /* end of CloseTheDevice */
  2550.  
  2551.  
  2552. /******************************************************************************
  2553.  * Name         :  MessageBox
  2554.  *
  2555.  * Description  :  This procedure will display messages for the application
  2556.  *                 based upon string IDs passed in.  The actual text will be
  2557.  *                 loaded from the string table in the resource.
  2558.  *
  2559.  * Concepts     :  None.
  2560.  *
  2561.  * MMPM/2 API's :  None.
  2562.  *
  2563.  * Parameters   :  usMessageID - ID of the message string
  2564.  *                 ulStyle     - Style of the message box (WinMessageBox)
  2565.  *
  2566.  * Return       :  TRUE  -  if the operation was initiated without error.
  2567.  *                 FALSE -  if an error occurred.
  2568.  *
  2569.  ******************************************************************************/
  2570. USHORT MessageBox( USHORT usMessageID, ULONG  ulStyle)
  2571. {
  2572.    CHAR     achMessage[LEN_ERROR_MESSAGE];
  2573.    USHORT   usResult;
  2574.  
  2575.    /*
  2576.     * Get the string from the Resource defined string table and show it
  2577.     * in the message box.
  2578.     */
  2579.    WinLoadString(
  2580.       hab,                             /* HAB for this dialog box.            */
  2581.       (HMODULE) NULL,                  /* Get the string from the .exe file.  */
  2582.       usMessageID,                     /* Which string to get.                */
  2583.       (SHORT) sizeof( achMessage),     /* The size of the buffer.             */
  2584.       achMessage );                    /* The buffer to place the string.     */
  2585.  
  2586.    usResult =
  2587.       WinMessageBox(
  2588.          HWND_DESKTOP,                 /* Parent handle of the message box.   */
  2589.          hwndMainDialogBox,            /* Owner handle of the message box.    */
  2590.          achMessage,                   /* String to show in the message box.  */
  2591.          achMsgBoxTitle,               /* Title to shown in the message box.  */
  2592.          (USHORT) ID_MESSAGEBOX,       /* Message Box Id.                     */
  2593.          ulStyle );                    /* The style of the message box.       */
  2594.  
  2595.    return( usResult );
  2596.  
  2597. }  /* End of MessageBox */
  2598.  
  2599.  
  2600. /******************************************************************************
  2601.  * Name         :  ShowMCIErrorMessage
  2602.  *
  2603.  * Description  :  This window procedure displays an MCI error message
  2604.  *                 based upon a ulError return code.  The MCI function
  2605.  *                 mciGetErrorString is used to convert the error code into
  2606.  *                 a text string and the title is pulled from the resource
  2607.  *                 based upon a string id.
  2608.  *
  2609.  * Concepts     :  Using mciGetErrorString to convert an error code into
  2610.  *                 a textual message.
  2611.  *
  2612.  * MMPM/2 API's :  mciGetErrorString
  2613.  *
  2614.  * Parameters   :  ulError  -  MCI error code.
  2615.  *
  2616.  * Return       :  nothing
  2617.  *
  2618.  ******************************************************************************/
  2619. VOID  ShowMCIErrorMessage( ULONG ulError)
  2620. {
  2621.    CHAR  achBuffer[LEN_ERROR_MESSAGE];
  2622.  
  2623.    switch(mciGetErrorString( ulError, (PSZ)achBuffer,   sizeof( achBuffer)))
  2624.    {
  2625.       case MCIERR_SUCCESS:
  2626.          /*
  2627.           * This is what we want.  We were able to use mciGetErrorString to
  2628.           * retrieve a textual error message we can show in a message box.
  2629.           */
  2630.          WinMessageBox( HWND_DESKTOP,
  2631.                         hwndMainDialogBox,
  2632.                         achBuffer,
  2633.                         achMsgBoxTitle,
  2634.                         (USHORT) ID_MESSAGEBOX,
  2635.                         MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  2636.          break;
  2637.  
  2638.       case MCIERR_INVALID_DEVICE_ID:
  2639.       case MCIERR_OUTOFRANGE:
  2640.       case MCIERR_INVALID_BUFFER:
  2641.       default:
  2642.          MessageBox( IDS_UNKNOWN,
  2643.                      MB_CANCEL | MB_HELP | MB_ERROR | MB_MOVEABLE);
  2644.          break;
  2645.    }
  2646.  
  2647.    return;
  2648.  
  2649. }  /* end of ShowMCIErrorMessage */
  2650.  
  2651.  
  2652. /******************************************************************************
  2653.  * Name         :  DoesFileExist
  2654.  *
  2655.  * Description  :  This helper function determines if a file with a given
  2656.  *                 file name exists.
  2657.  *
  2658.  * Concepts     :  Using MMIO interface to access a data file.
  2659.  *
  2660.  * MMPM/2 API's :  mmioOpen
  2661.  *                 mmioClose
  2662.  *
  2663.  * Parameters   :  none
  2664.  *
  2665.  * Return       :  TRUE  -  if a file exists matching szFilename
  2666.  *                 FALSE -  if the file does not exist
  2667.  *
  2668.  ******************************************************************************/
  2669. BOOL DoesFileExist( VOID )
  2670. {
  2671.    BOOL  bReturn;    /* function return value   */
  2672.    HMMIO hFile;      /* handle to file          */
  2673.  
  2674.    /*
  2675.     * Notice that these MMIO functions are analogous to the standard
  2676.     * C functions, fopen and fclose.
  2677.     */
  2678.  
  2679.    hFile = mmioOpen( szFileName, (PMMIOINFO) NULL, MMIO_READ);
  2680.  
  2681.    if (hFile != (HMMIO) NULL)
  2682.    {
  2683.       mmioClose( hFile, 0);
  2684.       bReturn = TRUE;
  2685.    }
  2686.    else
  2687.       bReturn = FALSE;
  2688.  
  2689.    return( bReturn);
  2690. }
  2691.  
  2692. /******************************************************************************
  2693.  * Name         :  SetAudioVolume
  2694.  *
  2695.  * Description  :  This helper function sets the audio file volume based upon
  2696.  *                 the position of the volume slider.  The slider will be
  2697.  *                 queried and the audio file volume will be set.
  2698.  *
  2699.  * Concepts     :  Setting the volume of a device.
  2700.  *
  2701.  * MMPM/2 API's :  mciSendCommand    MCI_SET
  2702.  *
  2703.  * Parameters   :  hwnd      - Handle for the Main dialog box.
  2704.  *
  2705.  * Return       :  nothing.
  2706.  *
  2707.  ******************************************************************************/
  2708. VOID SetAudioVolume( HWND hwnd )
  2709. {
  2710.    ULONG                ulError;       /* error value for mci returns   */
  2711.    MCI_WAVE_SET_PARMS   mspSet;        /* set values for volume, etc.   */
  2712.  
  2713.  
  2714.    if ((!fPassedDevice) && (eState==ST_PLAYING || eState==ST_RECORDING))
  2715.    {
  2716.       /*
  2717.        * To set the volume,  first, the MCI_SET_PARMS structure must be
  2718.        * filled with the necessary values.  Then an MCI_SET command
  2719.        * should be issued to the device to perform the volume change.
  2720.        */
  2721.       mspSet.hwndCallback = hwnd;
  2722.       mspSet.ulAudio    = MCI_SET_AUDIO_ALL;    /* set all channels     */
  2723.       mspSet.ulLevel    = (ULONG) sVolumeLevel; /* volume level desired */
  2724.  
  2725.       ulError = mciSendCommand( mciOpenParms.usDeviceID,
  2726.                                 MCI_SET,
  2727.                                 MCI_NOTIFY | MCI_SET_AUDIO | MCI_SET_VOLUME,
  2728.                                 (PVOID) &mspSet,
  2729.                                 UP_VOLUME);
  2730.       if (ulError)
  2731.          ShowMCIErrorMessage( ulError);
  2732.    }
  2733.    return;
  2734. }  /* end of SetAudioVolume */
  2735.  
  2736. /******************************************************************************
  2737.  *
  2738.  *  Name         : UpdateTitleText
  2739.  *
  2740.  *  Description  : Updates the text in the main window's title bar to
  2741.  *                 display the app name, followed by the separator,
  2742.  *                 followed by the file name.
  2743.  *
  2744.  *  Concepts    :  none
  2745.  *
  2746.  *  MMPM/2 API's:  none
  2747.  *
  2748.  *  Parameters  :  hwnd        = Frame window handle
  2749.  *                 pszFileName = filename to update the title bar
  2750.  *
  2751.  *  Return      :  none
  2752.  *
  2753.  ******************************************************************************/
  2754. VOID UpdateTitleText(HWND hwnd, PSZ pszFileName)
  2755. {
  2756.    CHAR  szBuffer[                                /* To store the program name*/
  2757.            MAXNAMEL+TITLESEPARATORLEN+CCHMAXPATH];/* + separator + file name  */
  2758.    CHAR  szSeparator[TITLESEPARATORLEN+1];        /* To store the separator   */
  2759.    PCHAR pcFileName;                              /* Buffer for file name     */
  2760.  
  2761.  
  2762.    /*
  2763.     * Load the program title into the szBuffer.
  2764.     */
  2765.    WinLoadString(hab, (HMODULE)0, IDS_PROGRAM_TITLE, MAXNAMEL, szBuffer);
  2766.  
  2767.    /*
  2768.     * Load the title separator into the szSeparator.
  2769.     */
  2770.    WinLoadString( hab,
  2771.                   (HMODULE)0,
  2772.                   IDS_TITLEBARSEPARATOR,
  2773.                   TITLESEPARATORLEN,
  2774.                   szSeparator);
  2775.  
  2776.    /*
  2777.     * pszFileName is the fully qualified file name. Parse it to get just
  2778.     * the file name to display it on the title bar.
  2779.     */
  2780.    pcFileName =  strrchr(((PCHAR)pszFileName + 1), '\\');
  2781.  
  2782.    if (!pcFileName)
  2783.       pcFileName = pszFileName;
  2784.    else
  2785.        pcFileName++;
  2786.  
  2787.    strcat(szBuffer, szSeparator);/* First append the separator to the title   */
  2788.    strcat(szBuffer, pcFileName); /* Next append the audio file name           */
  2789.  
  2790.    /*
  2791.     * Display the title on the program title bar.
  2792.     */
  2793.    WinSetWindowText(WinWindowFromID(hwnd, FID_TITLEBAR), szBuffer);
  2794.  
  2795. }   /* End of UpdateTitleText   */
  2796.  
  2797. /******************************************************************************
  2798.  *
  2799.  *  Name         : FileSaveAs
  2800.  *
  2801.  *  Description  : Processes the File menu's Save as item.  Called whenever
  2802.  *                 SAVE AS from the FILE menu is selected. Routine prompts the
  2803.  *                 user for the name of the file, then saves the file.
  2804.  *
  2805.  *  Concepts     : None
  2806.  *
  2807.  *  MMPM/2 API's : None
  2808.  *
  2809.  *  Parameters   : hwnd - Handle for the Main dialog box.
  2810.  *
  2811.  *  Return       : TRUE  -  if the operation was initiated without error.
  2812.  *                 FALSE -  if an error occurred.
  2813.  *
  2814.  *************************************************************************/
  2815. BOOL FileSaveAs(HWND hwnd)
  2816. {
  2817.    USHORT usResult;
  2818.  
  2819.    /*
  2820.     * Display Save As Dialog box.
  2821.     */
  2822.    if ( !ShowStandardFileDlg(IDM_FILE_SAVE_AS) )
  2823.    {
  2824.       return( FALSE );
  2825.    }
  2826.  
  2827.    /*
  2828.     * if the selected file exists, ask if we want to overwrite it
  2829.     */
  2830.    if ( DoesFileExist() )
  2831.    {
  2832.       usResult =
  2833.         MessageBox( IDS_FILE_EXISTS, MB_QUERY | MB_OKCANCEL);
  2834.  
  2835.       /*
  2836.        * If the user wants to overwrite the file, call the SaveTheAudio routine.
  2837.        */
  2838.       if( usResult == MBID_OK )
  2839.          SaveTheAudio(hwnd);
  2840.       /*
  2841.        * If the user doesnot want to overwrite the file, put up the Save As
  2842.        * dialog box again to enter a new name.
  2843.        */
  2844.       else if ( usResult == MBID_CANCEL )
  2845.          FileSaveAs(hwnd);
  2846.       else
  2847.          return( FALSE );
  2848.    }
  2849.    /*
  2850.     * The selected file name does not exist in the path. Save the currently
  2851.     * loaded file with the selected file name.
  2852.     */
  2853.    else
  2854.       SaveTheAudio(hwnd);
  2855.  
  2856.    return( TRUE );
  2857. }   /* End of FileSaveAs   */
  2858.  
  2859. /******************************************************************************
  2860.  * Name         :  ShowStandardFileDlg
  2861.  *
  2862.  * Description  :  Based upon the parameters passed in, show the user either
  2863.  *                 the Open dialog box or the Save as dialog box.
  2864.  *
  2865.  * Concepts     :  None.
  2866.  *
  2867.  * MMPM/2 API's :  None.
  2868.  *
  2869.  * Parameters   :  usSelection - Indicates which dlg to display-Open or Save as
  2870.  *
  2871.  * Return       :  TRUE  -  if the a file open is success.
  2872.  *                 FALSE -  if could not open the file.
  2873.  *
  2874.  ******************************************************************************/
  2875. BOOL ShowStandardFileDlg( USHORT usSelection)
  2876. {
  2877.    FILEDLG fileDialog;                     /* Open file dialog structure.     */
  2878.    CHAR    szTitle[FILE_NAME_SIZE];        /* Application title.              */
  2879.    CHAR    szButtonText[FILE_NAME_SIZE];   /* Save as dialog box button text. */
  2880.    USHORT  usResult = 0;                   /* To store return result.         */
  2881.  
  2882.    /*
  2883.     * Initialize the structure
  2884.     */
  2885.    memset( &fileDialog,                    /* Object to fill with zeros.      */
  2886.            0,                              /* Value to place into the object. */
  2887.            sizeof(fileDialog));            /* How many zero's to use.         */
  2888.  
  2889.    fileDialog.cbSize = sizeof(FILEDLG);
  2890.    fileDialog.pfnDlgProc = (PFNWP)OpenFileDlgProc;
  2891.    fileDialog.ulUser = (ULONG) hwndMainDialogBox;
  2892.  
  2893.    switch (usSelection)
  2894.    {
  2895.       case IDM_FILE_OPEN :
  2896.  
  2897.          WinLoadString(hab,(HMODULE)0,IDS_FILEOPEN_TITLE,CCHMAXPATH,szTitle);
  2898.          fileDialog.pszTitle = szTitle;
  2899.          fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_OPEN_DIALOG;
  2900.          fileDialog.usDlgId = IDD_FILEWINDOW;
  2901.  
  2902.          WinLoadString(hab, (HMODULE)0, IDS_FILEOPENEXT, CCHMAXPATH,
  2903.                        fileDialog.szFullFile);
  2904.          break;
  2905.  
  2906.       case IDM_FILE_SAVE_AS :
  2907.  
  2908.          WinLoadString(hab, (HMODULE)0, IDS_SAVE_AS, CCHMAXPATH, szButtonText);
  2909.          WinLoadString(hab,(HMODULE)0,IDS_FILESAVEAS_TITLE,CCHMAXPATH,szTitle);
  2910.          fileDialog.pszTitle = szTitle;
  2911.          fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG;
  2912.          fileDialog.usDlgId = FILESAVE;
  2913.          fileDialog.pszOKButton = (PSZ) szButtonText;
  2914.          break;
  2915.    }
  2916.    /*
  2917.     *Call the standard file dialog to get the file
  2918.     */
  2919.    usResult = WinFileDlg(HWND_DESKTOP, hwndMainDialogBox, &fileDialog);
  2920.  
  2921.    if (usResult != 0)
  2922.    {
  2923.       if (fileDialog.lReturn == DID_OK)
  2924.       {
  2925.          /*
  2926.           * initialize szFileName variable to get a new file name.
  2927.           */
  2928.          memset( szFileName, 0, sizeof(szFileName ));
  2929.  
  2930.          strncpy( (PCHAR)szFileName, fileDialog.szFullFile,
  2931.                   min( strlen( &fileDialog.szFullFile[0]),
  2932.                        CCHMAXPATH ));
  2933.       }
  2934.       else if (fileDialog.lReturn == DID_CANCEL)
  2935.       {
  2936.          return( FALSE );
  2937.       }
  2938.    }
  2939.    return( TRUE );
  2940. }
  2941.  
  2942. /******************************************************************************
  2943.  * Name         :  OpenFileDlgProc
  2944.  *
  2945.  * Description  :  This function displays the standard open dialog box.
  2946.  
  2947.  * Concepts     :  None.
  2948.  *
  2949.  * MMPM/2 API's :  None.
  2950.  *
  2951.  * Parameters   :  hwnd - Handle for the File dialog box.
  2952.  *                 msg  - Message received by the dialog box.
  2953.  *                 mp1  - Parameter 1 for the just received message.
  2954.  *                 mp2  - Parameter 2 for the just received message.
  2955.  *
  2956.  * Return       :  result of default processing.
  2957.  ******************************************************************************/
  2958.  
  2959. MRESULT EXPENTRY OpenFileDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  2960. {
  2961.    return WinDefFileDlgProc(hwnd, msg, mp1, mp2);
  2962. }
  2963.  
  2964. /******************************************************************************
  2965.  * Name         :  SaveTheChanges
  2966.  *
  2967.  * Description  :  If the file has been modified, this function asks the user
  2968.  *                 if he wants to save the changes or not.
  2969.  *
  2970.  * Concepts     :  none
  2971.  *
  2972.  * MMPM/2 API's :  none
  2973.  *
  2974.  * Parameters   :  hwnd  - Handle to the main dialog box.
  2975.  *
  2976.  * Return       :  TRUE  -  if changes saved or not saved .
  2977.  *                 FALSE -  if cancel out.
  2978.  *************************************************************************/
  2979. USHORT SaveTheChanges( HWND hwnd )
  2980. {
  2981.    USHORT   usResult;
  2982.  
  2983.    /*
  2984.     * Display a message box asking the user to save the changes made to the
  2985.     * audio file or not.
  2986.     */
  2987.    usResult =
  2988.      MessageBox( IDS_FILE_CHANGED,
  2989.                  MB_WARNING | MB_YESNOCANCEL | MB_MOVEABLE | MB_HELP);
  2990.    if (usResult == MBID_YES)
  2991.    {
  2992.       /*
  2993.        * User wants to save the changes made to the audio file. If the
  2994.        * currently loaded file is a tempfile display Save as dialog box for
  2995.        * the file name. Else call SaveTheAudio routine to save the audio file.
  2996.        */
  2997.       if (fTempFileInUse)
  2998.          FileSaveAs(hwnd);
  2999.       else
  3000.          SaveTheAudio(hwnd);
  3001.    }
  3002.    /*
  3003.     * If the user does not want to save the changes made to the file set the
  3004.     * flags.
  3005.     */
  3006.    else if (usResult == MBID_NO)
  3007.    {
  3008.       fModified      = FALSE;
  3009.       fTempFileInUse = FALSE;
  3010.    }
  3011.  
  3012.    return( usResult );
  3013. }
  3014.