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