home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pentlk11.zip / MMINK.C < prev    next >
C/C++ Source or Header  |  1994-01-13  |  31KB  |  726 lines

  1. /******************************************************************************
  2. *                                                                             *
  3. *   Name:  MMINK.C                                                            *
  4. *                                                                             *
  5. *   Copyright : COPYRIGHT IBM CORPORATION, 1993                               *
  6. *               LICENSED MATERIAL - PROGRAM PROPERTY OF IBM                   *
  7. *                                                                             *
  8. *   Description: This program loads a predefined bitmap in client window and  *
  9. *                allows user to record the audio synchronized with stroke     *
  10. *                data. Also allows to play it back.                           *
  11. *                                                                             *
  12. *   Execution Instruction: MMINK                                              *
  13. *                                                                             *
  14. *   Hardware Requirement: Audio I/O device.                                   *
  15. *                                                                             *
  16. *   Software Requirement: IBM OS/2 V2.1, Pen for OS/2 V1.0, and MMPM/2 V1.1   *
  17. *                                                                             *
  18. *   Subroutine Names and their function:                                      *
  19. *                                                                             *
  20. *      main : main drive routine                                              *
  21. *                                                                             *
  22. *      ClientWinProc : Client window procedure which has a bitmap in client   *
  23. *                      area and handles the annotation menu item.             *
  24. *                                                                             *
  25. *      AudioDlgProc: Audio dialog procedure which handles the recording and   *
  26. *                    playing back of the recorded voice and strokes.          *
  27. *                                                                             *
  28. *  DISCLAIMER OF WARRANTIES.  The following [enclosed] code is                *
  29. *      sample code created by IBM Corporation. This sample code is not        *
  30. *      part of any standard or IBM product and is provided to you solely      *
  31. *      for  the purpose of assisting you in the development of your           *
  32. *      applications.  The code is provided "AS IS", without                   *
  33. *      warranty of any kind.  IBM shall not be liable for any damages         *
  34. *      arising out of your use of the sample code, even if they have been     *
  35. *      advised of the possibility of such damages.                            *
  36. *                                                                             *
  37. ******************************************************************************/
  38.  
  39. /******************************************************************************
  40. * Note: You may notice slow inking during the recording of audio and ink on   *
  41. * slower machines. This is a result of MMINK being designed as a single       *
  42. * threaded application. Performance should improve by modifying the           *
  43. * application to use a multi-threaded model. The choice of a single thread    *
  44. * was made in order to increase the readability and simplicity the source     *
  45. * code.                                                                       *
  46. ******************************************************************************/
  47.  
  48. #define    INCL_WIN
  49. #define    INCL_ERRORS
  50. #define    INCL_GPI
  51. #define    INCL_DOS
  52. #define    INCL_CIRCULARSLIDER
  53. #include   <os2.h>
  54. #include   <string.h>
  55. #include   <stdlib.h>
  56. #include   <stdio.h>
  57. #include   <os2me.h>
  58. #include   <penpm.h>
  59. #include   <sw.h>
  60. #include   "mmink.h"
  61.  
  62. /*****************************************************************************
  63. *                                                                            *
  64. *   Subroutine Name : main                                                   *
  65. *                                                                            *
  66. *   Function: Main procedure to create the client window, process the window *
  67. *             messages, and exits the program.                               *
  68. *                                                                            *
  69. *   Parameters: None.                                                        *
  70. *                                                                            *
  71. *****************************************************************************/
  72. VOID main(VOID)
  73. {
  74.    ULONG flFrameFlags = FCF_SIZEBORDER | FCF_MINMAX | FCF_TITLEBAR |
  75.                         FCF_ICON | FCF_MENU | FCF_TASKLIST;
  76.    QMSG         qmsg;
  77.    HMQ          hmq;
  78.    USHORT       i;
  79.    CHAR         achClass[] = "MMINK";
  80.  
  81.    hab = WinInitialize(0UL);
  82.    hmq = WinCreateMsgQueue(hab, 0);
  83.  
  84.    WinRegisterClass(hab,
  85.                     achClass,
  86.                     ClientWinProc,
  87.                     CS_SYNCPAINT,
  88.                     0);
  89.  
  90.    hwndFrame  = WinCreateStdWindow(HWND_DESKTOP,
  91.                                    WS_VISIBLE,
  92.                                    &flFrameFlags,
  93.                                    achClass,
  94.                                    NULL,
  95.                                    0UL,
  96.                                    0UL,
  97.                                    ID_MMINK,
  98.                                    &hwndClient);
  99.  
  100.    WinSetWindowPos(hwndFrame,
  101.                    HWND_TOP,
  102.                    (WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) - CLIENTCX) / 2,
  103.                    (WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - CLIENTCY) / 2,
  104.                    CLIENTCX,
  105.                    CLIENTCY,
  106.                    SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
  107.  
  108.    /************************************************************************
  109.    *  When the modeless Audio dialog window ends, it makes the WinGetMsg   *
  110.    *  false. So, add a flag which is TRUE when user clicks Exit menu item. *
  111.    ************************************************************************/
  112.    while (!fFinish)
  113.    {
  114.       while (WinGetMsg(hab, &qmsg, 0UL, 0UL, 0UL))
  115.          WinDispatchMsg( hab, &qmsg );
  116.    }
  117.  
  118.    WinDestroyWindow(hwndFrame);
  119.    WinDestroyMsgQueue( hmq );
  120.    WinTerminate( hab );
  121.    DosExit(1, 0);
  122. }
  123.  
  124. /*****************************************************************************
  125. *                                                                            *
  126. *   Subroutine Name : ClientWinProc                                          *
  127. *                                                                            *
  128. *   Function: Window procedure of the main client window.                    *
  129. *             Process all messages and menu items in this window.            *
  130. *                                                                            *
  131. *   Parameters: HWND    hwnd                                                 *
  132. *               ULONG   msg                                                  *
  133. *               MAPRAM  mp1                                                  *
  134. *               MPARAM  mp2                                                  *
  135. *                                                                            *
  136. *   Pen message processed: WM_RECO                                           *
  137. *                                                                            *
  138. *****************************************************************************/
  139. MRESULT EXPENTRY ClientWinProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  140. {
  141. CHAR                       err[80];
  142. static HDC                 hdc;
  143. static HPS                 hpsMem;
  144. HPS                        hps;
  145. static HBITMAP             hbm;
  146. static BITMAPINFOHEADER2   bmhData;
  147. static SIZEL               sizel;
  148. POINTL                     aptl[4];
  149. RECTL                      rcl;
  150. static LONG                lCx, lCy;
  151.  
  152.    switch (msg)
  153.    {
  154.       case WM_CREATE:
  155.          /*******************************************************************
  156.          *  . Get the menu handle to enable/disable the ANNOTATE menu item  *
  157.          *  . Get the memory device context, create the presentation space, *
  158.          *    and load predefined bitmap.                                   *
  159.          *  . Get the bitmap information.                                   *
  160.          *******************************************************************/
  161.          hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
  162.                                     FID_MENU);
  163.          hdc = DevOpenDC(hab,
  164.                          OD_MEMORY,
  165.                          "*",         /* No device info */
  166.                          0L,
  167.                          (PDEVOPENDATA) NULL,
  168.                          NULLHANDLE);
  169.  
  170.          sizel.cx = sizel.cy = 0;
  171.          hpsMem = GpiCreatePS(hab,
  172.                               hdc,
  173.                               &sizel,
  174.                               PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT);
  175.  
  176.          hbm = GpiLoadBitmap(hpsMem,
  177.                              NULLHANDLE,
  178.                              IDB_MMINK,
  179.                              0L,      /* NO stretch in X and Y direction */
  180.                              0L);
  181.          GpiSetBitmap(hpsMem, hbm);
  182.  
  183.          /* Get the bitmap information */
  184.          bmhData.cbFix = sizeof(bmhData);
  185.          GpiQueryBitmapInfoHeader(hbm, &bmhData);
  186.          sizel.cx = bmhData.cx;
  187.          sizel.cy = bmhData.cy;
  188.          return FALSE;
  189.  
  190.       case WM_SIZE:
  191.          if ( hwndAudio )
  192.          {
  193.             WinSendMsg ( hwndAudio, WM_COMMAND, (MPARAM) AUDIOCTL_STOP, (MPARAM) 0 );
  194.          };
  195.          lCx = SHORT1FROMMP(mp2);
  196.          lCy = SHORT2FROMMP(mp2);
  197.          if ( hwndInk )
  198.          {
  199.             WinQueryWindowRect ( hwnd, &rcl );
  200.             WinSetWindowPos ( hwndInk,
  201.                               HWND_TOP,
  202.                               0,
  203.                               0,
  204.                               rcl.xRight,
  205.                               rcl.yTop,
  206.                               SWP_MOVE | SWP_SIZE  );
  207.          }
  208.          else
  209.             WinInvalidateRect ( hwnd, NULL, TRUE );
  210.          return FALSE;
  211.  
  212.       case WM_PAINT:
  213.       {
  214.          RECTL     rctl;
  215.  
  216.          hps = WinBeginPaint(hwnd, (ULONG) NULL, (PRECTL) &rctl);
  217.  
  218.          /* Target coordinate */
  219.          aptl[0].x = rctl.xLeft;
  220.          aptl[0].y = rctl.yBottom;
  221.          aptl[1].x = rctl.xRight;
  222.          aptl[1].y = rctl.yTop;
  223.  
  224.          /* Source Coordinate */
  225.          aptl[2].x = rctl.xLeft * sizel.cx / lCx;
  226.          aptl[2].y = rctl.yBottom * sizel.cy / lCy;
  227.          aptl[3].x = rctl.xRight * sizel.cx / lCx;
  228.          aptl[3].y = rctl.yTop * sizel.cy / lCy;
  229.  
  230.          GpiBitBlt(hps,
  231.                    hpsMem,
  232.                    4L,
  233.                    aptl,
  234.                    ROP_SRCCOPY,
  235.                    BBO_IGNORE);
  236.  
  237.          WinEndPaint(hps);
  238.          return FALSE;
  239.       }
  240.  
  241.       case WM_RECO:
  242.       {
  243.          RECODATA   rcData;
  244.  
  245.          /******************************************************************
  246.          *  Process the uppercase 'A' gesture as if the Annotate menu item *
  247.          *  is selected.                                                   *
  248.          ******************************************************************/
  249.          rcData = * (RECODATA *) PVOIDFROMMP(mp2);
  250.          if ((rcData.virtual_id == VIRTUAL_ID) && (rcData.char_code == UPPERA))
  251.          {
  252.             WinPostMsg(hwnd, WM_COMMAND, MPFROMSHORT(IDM_ANNOT), NULL);
  253.             return((MRESULT) RECO_PROCESSED);
  254.          }
  255.          return(FALSE);
  256.       }
  257.  
  258.       case WM_COMMAND:
  259.          switch(SHORT1FROMMP(mp1))
  260.          {
  261.             case IDM_ANNOT:
  262.                /*************************************************************
  263.                *  Disable this menu item, it will be enabled later when the *
  264.                *  dialog box is closed.                                     *
  265.                *************************************************************/
  266.                WinSendMsg(hwndMenu,
  267.                           MM_SETITEMATTR,
  268.                           MPFROM2SHORT(IDM_ANNOT, TRUE),
  269.                           MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
  270.  
  271.                hwndInk = InitTimedInk(hwnd, &CurrMMTime);
  272.                if ( !hwndInk )
  273.                {
  274.                    SetText(hwnd, err, "Failed to initialize timed Ink.",
  275.                            "Errors", 0,
  276.                            (ULONG) MB_ERROR | MB_OK, TRUE);
  277.                    WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
  278.                }
  279.                else
  280.                    hwndAudio = WinLoadDlg(HWND_DESKTOP,
  281.                                           hwnd,
  282.                                           AudioDlgProc,
  283.                                           0UL,
  284.                                           IDD_AUDIO,
  285.                                           0UL);
  286.                return FALSE;
  287.  
  288.             case IDM_EXIT:
  289.                fFinish = TRUE;
  290.                WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
  291.                return FALSE;
  292.          }
  293.          return FALSE;
  294.  
  295.       case WM_CLOSE:
  296.          GpiDestroyPS(hpsMem);
  297.          DevCloseDC(hdc);
  298.          GpiDeleteBitmap(hbm);
  299.          break;
  300.  
  301.       default:
  302.          break;
  303.  
  304.    } /* end of switch */
  305.  
  306.    return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  307. }
  308.  
  309. /*****************************************************************************
  310. *                                                                            *
  311. *   Subroutine Name : SetText                                                *
  312. *                                                                            *
  313. *   Function: Error message is given in a message box if fMessage is TRUE.   *
  314. *             This function put a text and number in ASCII in an array       *
  315. *             so that the sprintf C function is not used.                    *
  316. *                                                                            *
  317. *   Parameters: HWND    hwnd                                                 *
  318. *               PSZ     pszArray:arrary which will have the error message    *
  319. *               PSZ     pszStr: error message                                *
  320. *               PSZ     pszTitle: title of the message box                   *
  321. *               ULONG   ulRc: error code                                     *
  322. *               ULONG   ulFlags: flags for the message box                   *
  323. *               BOOL    fMessage: give message box or not                    *
  324. *                                                                            *
  325. *               All parameters are input.                                    *
  326. *                                                                            *
  327. *****************************************************************************/
  328. VOID SetText(HWND hwnd, PSZ pszArray, PSZ pszStr, PSZ pszTitle, ULONG ulRc,
  329.              ULONG ulFlags, BOOL fMessage)
  330. {
  331. PSZ  pszTemp;
  332.  
  333.     strcpy(pszArray, pszStr);
  334.     pszTemp = pszArray + strlen(pszArray);
  335.     _itoa(ulRc, pszTemp, 10);
  336.     *(pszTemp + 3) = '\0';
  337.  
  338.     if (fMessage)
  339.     {
  340.        WinMessageBox(HWND_DESKTOP,
  341.                      hwnd,
  342.                      pszArray,
  343.                      pszTitle,
  344.                      0,
  345.                      ulFlags);
  346.     }
  347.  
  348. }
  349.  
  350. /*****************************************************************************
  351. *                                                                            *
  352. *   Subroutine Name : AudioDlgProc                                           *
  353. *                                                                            *
  354. *   Function: Window procedure of the audio dialog window.                   *
  355. *             Process all messages and button messages in this window.       *
  356. *                                                                            *
  357. *   Parameters: HWND    hwnd                                                 *
  358. *               ULONG   msg                                                  *
  359. *               MAPRAM  mp1                                                  *
  360. *               MPARAM  mp2                                                  *
  361. *                                                                            *
  362. *****************************************************************************/
  363. MRESULT EXPENTRY AudioDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  364. {
  365.   static SHORT      sAudioLevel = 100;
  366.   static USHORT     usTotTime = 0;
  367.   static SBCDATA    sbc =  { 14, 0, 0, 100, 50, 1, 100 };
  368.   static BTNCDATA   bBut;
  369.   SHORT             rc;
  370.   CHAR              err[80];
  371.   HPS               hps;
  372.   static SHORT      currentMode = IDLE_MODE;
  373.   ULONG             ulReturn, i;
  374.   static USHORT     usPos = 0;
  375.   USHORT            usNotifyCode;          /* notification message code            */
  376.   SHORT             sWmControlID;          /* WM_CONTROL id                        */
  377.   USHORT            usTime;     /* Duration and Elapsed Time in second */
  378.  
  379.   switch (msg)
  380.   {
  381.      case WM_COMMAND:
  382.      {
  383.         switch (SHORT1FROMMP(mp1))
  384.         {
  385.            case AUDIOCTL_PLAY:
  386.            /******************************************************************
  387.            *  User clicks the PLAY button after recording.                   *
  388.            *  If any old stroke in window, erase it.                         *
  389.            *  Acquire the audio device.                                      *
  390.            *  Play the recorded audio data.                                  *
  391.            *  For stroke data, convert sensor resolution to screen resolution*
  392.            *  Enable STOP buttons and disable the other buttons.             *
  393.            ******************************************************************/
  394.            {
  395.               PSTROKEDATA pStroke;
  396.  
  397.               if (ulReturn = mmsrvAcquire())
  398.               {
  399.                  SetText(hwnd, err, "Error during Acquire, rc = ",
  400.                          "MMPM/2 Error", ulReturn,
  401.                          (ULONG) MB_ERROR | MB_OK, TRUE);
  402.                  return  FALSE;
  403.               }
  404.  
  405.               if (ulReturn = mmsrvPlay(hwnd))
  406.               {
  407.                  SetText(hwnd, err, "Error during Playback, rc = ",
  408.                          "Audio Error", ulReturn,
  409.                          (ULONG) MB_ERROR | MB_OK, TRUE);
  410.                  return  FALSE;
  411.               }
  412.  
  413.               usPos = 0;
  414.               currentMode = PLAYING_MODE;
  415.  
  416.               PlayTimedInk ( hwndInk );
  417.               WinSetDlgItemText(hwnd,
  418.                                 AUDIOCTL_INFO,
  419.                                 "Playing voice & handwriting.");
  420.  
  421.               /***********************************************************
  422.               *  Disable the PLAY and RECORD buttons but enable STOP but *
  423.               ***********************************************************/
  424.               WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
  425.               WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), FALSE);
  426.               WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), TRUE);
  427.               break;
  428.            }  /* of case AUDIOCTL_PLAY                                */
  429.  
  430.            case AUDIOCTL_REC:
  431.            /******************************************************************
  432.            *  User clicks the RECORD button.                                 *
  433.            *  If any old stroke in window, erase it.                         *
  434.            *  Acquire the audio device.                                      *
  435.            *  Record the audio data.                                         *
  436.            *  Enable STOP buttons and disable the other buttons.             *
  437.            ******************************************************************/
  438.            {
  439.               if (ulReturn = mmsrvAcquire())
  440.               {
  441.                  SetText(hwnd, err, "Error during Acquire, rc = ",
  442.                          "MMPM/2 Error", ulReturn,
  443.                          (ULONG) MB_ERROR | MB_OK, TRUE);
  444.                  return  FALSE;
  445.               }
  446.  
  447.               if (ulReturn = mmsrvRecord(hwnd))
  448.               {
  449.                  SetText(hwnd, err, "Error during Recording, rc = ",
  450.                          "Audio Error", ulReturn,
  451.                          (ULONG) MB_ERROR | MB_OK, TRUE);
  452.                  return  FALSE;
  453.               }
  454.               usPos = 0;
  455.               currentMode = RECORDING_MODE;
  456.               WinSetDlgItemText(hwnd,
  457.                                 AUDIOCTL_INFO,
  458.                                 "Recording voice & handwriting.");
  459.  
  460.               RecordTimedInk(hwndInk);
  461.  
  462.               /************************************************************
  463.               *  Enable the STOP button, but disables the PLAY and RECORD *
  464.               *  buttons.                                                 *
  465.               ************************************************************/
  466.               WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), TRUE);
  467.               WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), FALSE);
  468.               WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
  469.               break;
  470.            }  /* of case AUDIOCTL_REC                                 */
  471.  
  472.            case AUDIOCTL_STOP:
  473.            /******************************************************************
  474.            *  User clicks the STOP button while recording or playing.        *
  475.            *  Depending upon the mode (playing or recording), set correct    *
  476.            *  text in INFO field of dialog box.                              *
  477.            *  Stop recording/playing auiod data.                             *
  478.            ******************************************************************/
  479.            {
  480.               StopTimedInk(hwndInk);
  481.               switch (currentMode)
  482.               {
  483.                  case RECORDING_MODE:
  484.                  {
  485.                     WinSetDlgItemText(hwnd,
  486.                                       AUDIOCTL_INFO,
  487.                                       "Stopping voice/pen recording.");
  488.                     break;
  489.                  }  /* of case RECORDING_MODE                         */
  490.  
  491.                  case  PLAYING_MODE:
  492.                  {
  493.                     WinSetDlgItemText(hwnd,
  494.                                       AUDIOCTL_INFO,
  495.                                       "Stopping voice/pen playback.");
  496.                     break;
  497.                  }  /* of case PLAYING_MODE                           */
  498.               }  /*  of switch(currentMode)                           */
  499.  
  500.               (void) mmsrvStop();
  501.               currentMode = IDLE_MODE;
  502.               break;
  503.  
  504.            }  /* of case AUDIOCTL_STOP                                */
  505.         }  /* of switch(SHORT1FROMMP(mp1))                            */
  506.         return  FALSE;
  507.      }  /* of case WM_COMMAND                                         */
  508.  
  509.      case MM_MCINOTIFY:
  510.      /*********************************************************************
  511.      *  This message is sent from MMPM/2 system when the MMPM/2 device    *
  512.      *  successfully completes the action indicated by media message or   *
  513.      *  when an error occurs.                                             *             *
  514.      *********************************************************************/
  515.      {
  516.          USHORT usNotifyCode;
  517.          USHORT usReceivedMessage;
  518.  
  519.          StopTimedInk ( hwndInk );
  520.  
  521.          usNotifyCode = SHORT1FROMMP(mp1);
  522.          usReceivedMessage = SHORT2FROMMP(mp2);
  523.          WinSetDlgItemText(hwnd,
  524.                            AUDIOCTL_ELAP,
  525.                            "Elapsed: 0");
  526.          WinSetDlgItemText(hwnd,
  527.                            AUDIOCTL_INFO,
  528.                            "");
  529.          if (usNotifyCode == MCI_NOTIFY_SUCCESSFUL
  530.              || usNotifyCode == MCI_NOTIFY_SUPERSEDED
  531.              || usNotifyCode == MCI_NOTIFY_ABORTED)
  532.          {
  533.             if (ulReturn = mmsrvRelease())
  534.             {
  535.                SetText(hwnd, err, "Error during Release, rc = ",
  536.                        "MMPM/2 Error", ulReturn,
  537.                        (ULONG) MB_ERROR | MB_OK, TRUE);
  538.                return  FALSE;
  539.             };
  540.             if (usReceivedMessage == MCI_RECORD)
  541.             {
  542.                if (usPos == 0)
  543.                   WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY),
  544.                                   FALSE);
  545.                else
  546.                {
  547.                   usTime = usPos / 10;
  548.                   SetText(hwnd, err, "Duration: ",
  549.                           NULL, usTime,
  550.                           (ULONG) NULL, FALSE);
  551.                   WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
  552.                };
  553.             };
  554.          }
  555.          else
  556.          {
  557.             SetText(hwnd, err, "Play/Record could not succeed",
  558.                     "Audio Error", 0,
  559.                     (ULONG) MB_ERROR | MB_OK, TRUE);
  560.          };  /* of else                       */
  561.  
  562.          for (i = AUDIOCTL_PLAY; i < AUDIOCTL_STOP; i++)
  563.             WinEnableWindow(WinWindowFromID(hwnd, i),
  564.                             TRUE);
  565.  
  566.          WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP),
  567.                          FALSE);
  568.          return  FALSE;
  569.      }   /* of case MM_MCINOTIFY          */
  570.  
  571.      /**********************************************************************
  572.      *  This message is sent from multi media device for every one tenth   *
  573.      *  second while audio data is played or recorded. This one tenth of   *
  574.      *  time interval was done in mmsrvOpen().                             *
  575.      **********************************************************************/
  576.      case MM_MCIPOSITIONCHANGE:
  577.      {
  578.          usPos++;
  579.          usTime = usPos / 10;
  580.  
  581.          switch (currentMode)
  582.          {
  583.             case RECORDING_MODE:
  584.             {
  585.                SetText(hwnd, err, "Duration: ",
  586.                        NULL, usTime,
  587.                        (ULONG) NULL, FALSE);
  588.                WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
  589.  
  590.                SetText(hwnd, err, "Elapsed: ",
  591.                        NULL, usTime,
  592.                        (ULONG) NULL, FALSE);
  593.                WinSetDlgItemText(hwnd, AUDIOCTL_ELAP, err);
  594.                CurrMMTime = (MMTIME) mp2;
  595.                break;
  596.             }
  597.  
  598.             case PLAYING_MODE:
  599.             {
  600.                SetText(hwnd, err, "Duration: ",
  601.                        NULL, usTime,
  602.                        (ULONG) NULL, FALSE);
  603.                WinSetDlgItemText(hwnd, AUDIOCTL_DUR, err);
  604.                SetText(hwnd, err, "Elapsed: ",
  605.                        NULL, usTime,
  606.                        (ULONG) NULL, FALSE);
  607.                WinSetDlgItemText(hwnd, AUDIOCTL_ELAP, err);
  608.  
  609.                CurrMMTime = (MMTIME) mp2;
  610.                InkTimedInk ( hwndInk, (MMTIME) mp2 );
  611.  
  612.                break;
  613.             }
  614.          }  /* end of switch(currentMode)                               */
  615.          return FALSE;
  616.      }   /* of case MM_MCIPOSITIONCHANGE                                */
  617.  
  618.      case WM_HSCROLL:
  619.      {
  620.         switch (SHORT2FROMMP(mp2))
  621.         {
  622.            case SB_LINELEFT:
  623.               sAudioLevel = max(0, sAudioLevel - 1);
  624.               break;
  625.  
  626.            case SB_LINERIGHT:
  627.               sAudioLevel = min(100, sAudioLevel + 1);
  628.               break;
  629.  
  630.            case SB_PAGELEFT:
  631.               sAudioLevel = max(0, sAudioLevel - 10);
  632.               break;
  633.  
  634.            case SB_PAGERIGHT:
  635.               sAudioLevel = min(100, sAudioLevel + 10);
  636.               break;
  637.  
  638.            case SB_SLIDERTRACK:
  639.               sAudioLevel = SHORT1FROMMP(mp2);
  640.               break;
  641.  
  642.            case SB_ENDSCROLL:
  643.            case SB_SLIDERPOSITION:
  644.               mmsrvSetVolume((USHORT) sAudioLevel);
  645.               return  FALSE;
  646.         }  /* of switch(SHORT2FROMMP...       */
  647.  
  648.         WinSendDlgItemMsg(hwnd,
  649.                           AUDIOCTL_SCRL,
  650.                           SBM_SETPOS,
  651.                           MPFROMSHORT(sAudioLevel),
  652.                           NULL);
  653.  
  654.         SetText(hwnd, err, "Volume: ",
  655.                 NULL, sAudioLevel,
  656.                 (ULONG) NULL, FALSE);
  657.         WinSetDlgItemText(hwnd, AUDIOCTL_VOL, err);
  658.         return  FALSE;
  659.  
  660.      }  /* of case WM_HSCROLL */
  661.  
  662.  
  663.      case WM_INITDLG:
  664.      {
  665.         HWND    hwndVol;
  666.  
  667.         fAudioAvail = TRUE;
  668.  
  669.         /* volume control scroll bar
  670.         WinCreateWindow(hwnd,
  671.                         WC_SCROLLBAR,
  672.                         NULL,
  673.                         WS_VISIBLE | WS_SYNCPAINT | SBS_HORZ,
  674.                         (ANWINSIZE / 2),
  675.                         38,
  676.                         (ANWINSIZE - 20) / 2,
  677.                         18,
  678.                         hwnd,
  679.                         HWND_TOP,
  680.                         AUDIOCTL_SCRL,
  681.                         &sbc,
  682.                         NULL);         */
  683.  
  684.         /* give slider position */
  685.         WinSendDlgItemMsg(hwnd,
  686.                           AUDIOCTL_SCRL,
  687.                           SBM_SETPOS,
  688.                           MPFROMSHORT(sAudioLevel),
  689.                           NULL);
  690.  
  691.         /* Initial setup for recording */
  692.         currentMode = IDLE_MODE;
  693.         usTotTime = 0;
  694.  
  695.         mmsrvOpen(hwnd);
  696.  
  697.         WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_PLAY), FALSE);
  698.         WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_REC), TRUE);
  699.         WinEnableWindow(WinWindowFromID(hwnd, AUDIOCTL_STOP), FALSE);
  700.         return (FALSE);
  701.      }  /* of case WM_CREATE */
  702.  
  703.      case WM_CLOSE:
  704.      {
  705.         mmsrvClose();
  706.         DestroyTimedInk ( hwndInk );
  707.         fAudioActive = FALSE;
  708.         WinSetFocus(HWND_DESKTOP, hwndClient);
  709.  
  710.         /*******************************************************************
  711.         *  Enable the Voice & Ink menu item.                               *
  712.         *******************************************************************/
  713.         WinSendMsg(hwndMenu,
  714.                    MM_SETITEMATTR,
  715.                    MPFROM2SHORT(IDM_ANNOT, TRUE),
  716.                    MPFROM2SHORT(MIA_DISABLED, FALSE));
  717.  
  718.         WinDestroyWindow(hwnd);
  719.         return(FALSE);
  720.      }  /* of case WM_CLOSE */
  721.   }  /* of switch(msg)        */
  722.  
  723.   return (WinDefDlgProc(hwnd, msg, mp1, mp2));
  724. }
  725.  
  726.