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

  1. /*****************************************************************************
  2. *                                                                            *
  3. *  File Name   : ISMPROCS.C                                                  *
  4. *                                                                            *
  5. *  Description : Window Procedures for the ISM_SAMP.EXE                      *
  6. *                                                                            *
  7. *  Function:  This file has all the window procedures for the ISM_SAMP.EXE.  *
  8. *                                                                            *
  9. *  Copyright (C) 1993 IBM Corporation                                        *
  10. *                                                                            *
  11. *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is           *
  12. *      sample code created by IBM Corporation. This sample code is not       *
  13. *      part of any standard or IBM product and is provided to you solely     *
  14. *      for  the purpose of assisting you in the development of your          *
  15. *      applications.  The code is provided "AS IS", without                  *
  16. *      warranty of any kind.  IBM shall not be liable for any damages        *
  17. *      arising out of your use of the sample code, even if they have been    *
  18. *      advised of the possibility of such damages.                           *
  19. *                                                                            *
  20. *****************************************************************************/
  21.  
  22. /*****************************************************************************
  23. * Defines                                                                    *
  24. *****************************************************************************/
  25. #define  INCL_PM
  26. #define  INCL_GPIPRIMATIVES
  27.  
  28. /*****************************************************************************
  29. * Includes                                                                   *
  30. *****************************************************************************/
  31. #include <os2.h>
  32. #include <penpm.h>
  33. #include "ism_samp.h"
  34.  
  35. BOOL ChangeColor    ( PMYWINDOWDATA pMyWindowData, LONG NewColor );
  36. HRGN CreateClipRect ( PMYWINDOWDATA  pMyWindowData, SHORT NumSegments );
  37. HWND CreateInkControls ( HWND hWnd );
  38. MRESULT APIENTRY InkEditHelp (  HWND hWnd, ULONG ulMsg, MPARAM mp1, MPARAM mp2 );
  39.  
  40. /*****************************************************************************
  41. * Debug Messages                                                             *
  42. *****************************************************************************/
  43. VOID DebugMessage ( char dmessage[50] )
  44.    {
  45.    WinMessageBox ( HWND_DESKTOP,
  46.                    HWND_DESKTOP,
  47.                    dmessage,
  48.                    "Debug Message",
  49.                    0,
  50.                    MB_OK            |
  51.                    MB_ERROR         |
  52.                    MB_SYSTEMMODAL   |
  53.                    MB_MOVEABLE );
  54.    }
  55.  
  56. /*****************************************************************************
  57. * Update the status window                                                   *
  58. *****************************************************************************/
  59. VOID StatusLine ( PMYWINDOWDATA pMyWindowData, CHAR *StatusText )
  60.    {
  61.    WinSetWindowText ( pMyWindowData->StatusWindow, StatusText );
  62.    return;
  63.    }
  64.  
  65. /*****************************************************************************
  66. * COMMON WINDOWPROC MESSAGE HANDLING                                         *
  67. *                                                                            *
  68. * All of the window procedures will call this module if they do not handle   *
  69. * any given message. This routine will in turn call the default window       *
  70. * procedure ( WinDefWindowProc ) if the message isn't handled here.          *
  71. *****************************************************************************/
  72. MRESULT EXPENTRY ISMCOMMON ( HWND hWnd,
  73.                              ULONG ulMsg,
  74.                              MPARAM mp1,
  75.                              MPARAM mp2 )
  76.    {
  77.    PMYWINDOWDATA  pMyWindowData;
  78.    RECTL          rcl;
  79.    HPS            hps;
  80.    HWND           hFrame;
  81.  
  82.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  83.    switch ( ulMsg )
  84.       {
  85.       case  WM_INITMYWINDOW:
  86.                DosAllocMem ( (VOID *) &pMyWindowData,
  87.                              sizeof(MYWINDOWDATA),
  88.                              PAG_COMMIT   |
  89.                                  PAG_READ |
  90.                                  PAG_WRITE );
  91.                WinSetWindowPtr ( hWnd, 0, (PVOID) pMyWindowData );
  92.                pMyWindowData->StatusWindow = (HWND) mp1;
  93.                pMyWindowData->MyWindow = hWnd;
  94.                return ( (MRESULT) TRUE );
  95.                break;
  96.  
  97.       case  WM_CLOSE:
  98.                StatusLine ( pMyWindowData, "" );
  99.                hFrame = WinQueryWindow ( hWnd, QW_PARENT );
  100.                WinDestroyWindow ( hFrame );
  101.                return ( (MRESULT) 0 );
  102.                break;
  103.  
  104.       case  WM_COMMAND:
  105.             switch ( LONGFROMMP(mp1) )
  106.                {
  107.                case  ID_QUIT:
  108.                      WinPostMsg ( hWnd, WM_CLOSE, 0, 0 );
  109.                      break;
  110.  
  111.                default:
  112.                      break;
  113.                }
  114.             break;
  115.  
  116.       case  WM_SETFOCUS:
  117.                if ( pMyWindowData != NULL )
  118.                   StatusLine ( pMyWindowData, "" );
  119.                break;
  120.  
  121.       case  WM_PAINT:
  122.                hps = WinBeginPaint  ( hWnd, NULLHANDLE, (PRECTL)NULL );
  123.                WinQueryWindowRect   ( hWnd, &rcl );
  124.                WinFillRect          ( hps,  &rcl, SYSCLR_MENU );
  125.                WinEndPaint          ( hps );
  126.                return ( (MRESULT) TRUE );
  127.                break;
  128.  
  129.       default:
  130.             break;
  131.       }
  132.    return( (MRESULT) WinDefWindowProc ( hWnd, ulMsg, mp1, mp2 )  );
  133.    }
  134.  
  135. /*****************************************************************************
  136. * WM_TOUCHDOWN: RETURN CODE: TDN_DEFAULT_DELAY                               *
  137. *                                                                            *
  138. * Use the default delay between WM_TOUCHDOWN and WM_BUTTONxDOWN. The result  *
  139. * of this is that if the user touches the sensor and pauses for a duration   *
  140. * equal to the default delay, mouse emulation is performed. However, if the  *
  141. * user touches the sensor and begins a stroke, then gesture recognition is   *
  142. * attempted.                                                                 *
  143. *****************************************************************************/
  144. MRESULT APIENTRY  tdn_default_delay (  HWND     hWnd,
  145.                                        ULONG    ulMsg,
  146.                                        MPARAM   mp1,
  147.                                        MPARAM   mp2   )
  148.    {
  149.    RECTL       rcl;
  150.    HPS         hps;
  151.    PMYWINDOWDATA  pMyWindowData;
  152.  
  153.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  154.  
  155.    switch ( ulMsg )
  156.       {
  157.       case  WM_TOUCHDOWN:
  158.                pMyWindowData->td = TRUE;
  159.                StatusLine ( pMyWindowData, "Returning TDN_DEFAULT_DELAY." );
  160.                return ( (MRESULT) TDN_DEFAULT_DELAY );
  161.                break;
  162.  
  163.       case  WM_BUTTON1DOWN:
  164.                if ( pMyWindowData->td )
  165.                   {
  166.                   pMyWindowData->td = FALSE;
  167.                   StatusLine ( pMyWindowData, "Mouse Emulation Mode" );
  168.                   };
  169.                return ( (MRESULT) TRUE );
  170.                break;
  171.  
  172.       case  WM_STROKE:
  173.                pMyWindowData->td = FALSE;
  174.                StatusLine ( pMyWindowData, "Gesture Mode" );
  175.                break;
  176.  
  177.       default:
  178.                break;
  179.       };
  180.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  181.    };
  182.  
  183. /*****************************************************************************
  184. * WM_TOUCHDOWN: RETURN CODE: TDN_IMMEDIATE                                   *
  185. *                                                                            *
  186. * No delay. The program will recieve a  WM_BUTTONxDOWN  message immediately. *
  187. * Note that a stroke buffer is not built when using this return code.        *
  188. *****************************************************************************/
  189. MRESULT APIENTRY  tdn_immediate (  HWND     hWnd,
  190.                                    ULONG    ulMsg,
  191.                                    MPARAM   mp1,
  192.                                    MPARAM   mp2   )
  193.    {
  194.    RECTL       rcl;
  195.    HPS         hps;
  196.    PMYWINDOWDATA  pMyWindowData;
  197.  
  198.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  199.  
  200.    switch ( ulMsg )
  201.       {
  202.       case  WM_TOUCHDOWN:
  203.                StatusLine ( pMyWindowData, "Returning TDN_IMMEDIATE" );
  204.                return ( (MRESULT) TDN_IMMEDIATE );
  205.                break;
  206.  
  207.       case  WM_BUTTON1DOWN:
  208.                StatusLine ( pMyWindowData, "WM_BUTTON1DOWN has been received" );
  209.                return ( (MRESULT) TRUE );
  210.                break;
  211.  
  212.       default:
  213.                break;
  214.       };
  215.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  216.    };
  217.  
  218. /*****************************************************************************
  219. * WM_TOUCHDOWN: RETURN CODE: TDN_INFINITE                                    *
  220. *                                                                            *
  221. * The program will not recieve a WM_BUTTONxDOWN message as a result of       *
  222. * touchdown.                                                                 *
  223. *****************************************************************************/
  224. MRESULT APIENTRY  tdn_infinite (  HWND     hWnd,
  225.                                   ULONG    ulMsg,
  226.                                   MPARAM   mp1,
  227.                                   MPARAM   mp2   )
  228.    {
  229.    RECTL       rcl;
  230.    HPS         hps;
  231.    PMYWINDOWDATA  pMyWindowData;
  232.  
  233.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  234.    switch ( ulMsg )
  235.       {
  236.       case  WM_TOUCHDOWN:
  237.                pMyWindowData->td = TRUE;
  238.                StatusLine ( pMyWindowData, "Returning TDN_INFINITE." );
  239.                return ( (MRESULT) TDN_INFINITE );
  240.                break;
  241.  
  242.       case  WM_BUTTON1DOWN:
  243.                if ( pMyWindowData->td )
  244.                   {
  245.                   StatusLine ( pMyWindowData, "Error: WM_TOUCHDOWN generated WM_BUTTON1DOWN" );
  246.                   };
  247.                return ( (MRESULT) TRUE );
  248.                break;
  249.  
  250.       case  WM_LIFTOFF:
  251.                pMyWindowData->td = FALSE;
  252.                break;
  253.  
  254.       case  WM_EXIT_PROXIMITY:
  255.                pMyWindowData->td = FALSE;
  256.                break;
  257.  
  258.       default:
  259.                break;
  260.       };
  261.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  262.    };
  263.  
  264. /*****************************************************************************
  265. * WM_TOUCHDOWN: RETURN CODE: TDN_INK_STROKE                                  *
  266. *                                                                            *
  267. * Let PenPM do the inking of the stroke for you. The ink is not actually     *
  268. * placed in your window. It is draw in a transparent window that covers the  *
  269. * screen.                                                                    *
  270. *****************************************************************************/
  271. MRESULT APIENTRY  tdn_ink_stroke (  HWND     hWnd,
  272.                                     ULONG    ulMsg,
  273.                                     MPARAM   mp1,
  274.                                     MPARAM   mp2   )
  275.    {
  276.    RECTL       rcl;
  277.    HPS         hps;
  278.  
  279.    PMYWINDOWDATA  pMyWindowData;
  280.  
  281.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  282.    switch ( ulMsg )
  283.       {
  284.       case  WM_TOUCHDOWN:
  285.                StatusLine ( pMyWindowData, "Returning TDN_INK_STROKE." );
  286.                return ( (MRESULT) TDN_INK_STROKE );
  287.                break;
  288.  
  289.       default:
  290.                break;
  291.       };
  292.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  293.    };
  294.  
  295. /*****************************************************************************
  296. * WM_TOUCHDOWN: RETURN CODE: TDN_NO_INK_STROKE                               *
  297. *                                                                            *
  298. * PenPM will not ink the stroke. This is usually used when the program       *
  299. * intends to do the inking itself.                                           *
  300. *****************************************************************************/
  301. MRESULT APIENTRY  tdn_no_ink_stroke (  HWND     hWnd,
  302.                                        ULONG    ulMsg,
  303.                                        MPARAM   mp1,
  304.                                        MPARAM   mp2   )
  305.    {
  306.    RECTL       rcl;
  307.    HPS         hps;
  308.  
  309.    PMYWINDOWDATA  pMyWindowData;
  310.  
  311.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  312.    switch ( ulMsg )
  313.       {
  314.       case  WM_TOUCHDOWN:
  315.                StatusLine ( pMyWindowData, "Returning TDN_NO_INK_STROKE." );
  316.                return ( (MRESULT) TDN_NO_INK_STROKE );
  317.                break;
  318.  
  319.       default:
  320.                break;
  321.       };
  322.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  323.    };
  324.  
  325. /*****************************************************************************
  326. * WM_TOUCHDOWN: RETURN CODE: TDN_LEAVE_INK                                   *
  327. *                                                                            *
  328. * Inform PenPM to ink the stroke and leave it on the screen if the stroke    *
  329. * does not leave the window that received WM_TOUCHDOWN. However, if the      *
  330. * stroke extends outside the window then the ink is removed. When your       *
  331. * window repaints, the ink left by PenPM will not be repainted. If you wish  *
  332. * to retain the ink, you must capture the point and/or stroke data and paint *
  333. * the ink yourself.                                                          *
  334. *****************************************************************************/
  335. MRESULT APIENTRY  tdn_leave_ink (   HWND     hWnd,
  336.                                     ULONG    ulMsg,
  337.                                     MPARAM   mp1,
  338.                                     MPARAM   mp2   )
  339.    {
  340.    RECTL       rcl;
  341.    HPS         hps;
  342.  
  343.    PMYWINDOWDATA  pMyWindowData;
  344.  
  345.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  346.    switch ( ulMsg )
  347.       {
  348.       case  WM_TOUCHDOWN:
  349.                StatusLine ( pMyWindowData, "Returning TDN_LEAVE_INK." );
  350.                return ( (MRESULT) TDN_LEAVE_INK );
  351.                break;
  352.  
  353.       default:
  354.                break;
  355.       };
  356.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  357.    };
  358.  
  359. /*****************************************************************************
  360. * WM_TOUCHDOWN: RETURN CODE: TDN_HIFREQ_MOUSEMOVE                            *
  361. *                                                                            *
  362. * Inform PenPM to report all pointing device movements as WM_MOUSEMOVE's at  *
  363. * full bandwidth. The points are reported in window coordinates. This is     *
  364. * primarily used when all you are doing is inking to the window or display.  *
  365. * If you are inking to a higher resolution bitmap or if you intend to do     *
  366. * some type of recoginition on the strokes then use WM_SENSOR_MOVE since the *
  367. * sensors generally have a higher resolution.                                *
  368. *****************************************************************************/
  369. MRESULT APIENTRY  tdn_hifreq_mousemove (  HWND     hWnd,
  370.                                           ULONG    ulMsg,
  371.                                           MPARAM   mp1,
  372.                                           MPARAM   mp2   )
  373.    {
  374.    RECTL       rcl;
  375.    HPS         hps;
  376.    PMYWINDOWDATA  pMyWindowData;
  377.  
  378.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  379.    switch ( ulMsg )
  380.       {
  381.       case  WM_TOUCHDOWN:
  382.                pMyWindowData->td = TRUE;
  383.                StatusLine ( pMyWindowData, "Returning TDN_HIFREQ_MOUSEMOVE." );
  384.                return ( (MRESULT) TDN_HIFREQ_MOUSEMOVE );
  385.                break;
  386.  
  387.       case  WM_MOUSEMOVE:
  388.                if ( pMyWindowData->td )
  389.                   {
  390.                   StatusLine ( pMyWindowData, "WM_MOUSMOVE" );
  391.                   return ( (MRESULT) TRUE );
  392.                   }
  393.                break;
  394.  
  395.       default:
  396.                break;
  397.       };
  398.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  399.    };
  400.  
  401. /*****************************************************************************
  402. * WM_TOUCHDOWN: RETURN CODE: TDN_SENSOR_MOVE                                 *
  403. *                                                                            *
  404. * Inform PenPM to report all pointing device movements as WM_SENSOR_MOVE's   *
  405. * at sensor resolution. This is usually used when you are inking to a high   *
  406. * resolution bitmap or when you are using the strokes and or points for some *
  407. * type of recoginition. If you are only inking to the display use the        *
  408. * WM_HIGHFREQ_MOUSEMOVE message, since it does not require any scaling of    *
  409. * the point data.                                                            *
  410. *****************************************************************************/
  411. MRESULT APIENTRY  tdn_sensor_move (  HWND     hWnd,
  412.                                      ULONG    ulMsg,
  413.                                      MPARAM   mp1,
  414.                                      MPARAM   mp2   )
  415.    {
  416.    RECTL                    rcl;
  417.    HPS                      hps;
  418.    static HPS               hpsClient;
  419.    static POINTL            points = { 0, 0 } ;
  420.    static BOOL              FirstTime = TRUE;
  421.    static WRTLOCATORDEVINFO WrtLocatorDevInfo;
  422.    WRTEVENTDATA             WrtEventData;
  423.    static SHORT             changecolor = 0;
  424.    static SHORT             numpoints  = 26;
  425.  
  426.    PMYWINDOWDATA  pMyWindowData;
  427.  
  428.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  429.    switch ( ulMsg )
  430.       {
  431.       case  WM_TOUCHDOWN:
  432.                if ( FirstTime )
  433.                   {
  434.                   WrtEventData = *( (PWRTEVENTDATA) PVOIDFROMMP ( mp2 ) );
  435.                   WrtLocatorDevInfo.cbStructSize = sizeof ( WRTLOCATORDEVINFO );
  436.                   WrtQueryLocatorCaps ( &WrtEventData.ulLocatorID, &WrtLocatorDevInfo );
  437.                   FirstTime=FALSE;
  438.                   };
  439.                WinSetCapture ( HWND_DESKTOP, hWnd );
  440.                hpsClient = WinGetPS ( hWnd );
  441.                points.x = SHORT1FROMMP ( mp1 );
  442.                points.y = SHORT2FROMMP ( mp1 );
  443.                GpiMove ( hpsClient, &points );
  444.                GpiSetColor ( hpsClient, CLR_BLUE );
  445.                numpoints = 25;
  446.                StatusLine ( pMyWindowData, "Returning TDN_INFINITE | TDN_SENSOR_MOVE | TDN_NO_INK_STROKE." );
  447.                return ( (MRESULT) ( TDN_INFINITE | TDN_SENSOR_MOVE | TDN_NO_INK_STROKE ) );
  448.                break;
  449.  
  450.       case  WM_SENSOR_MOVE:
  451.                points.x = SHORT1FROMMP ( mp1 );
  452.                points.y = SHORT2FROMMP ( mp1 );
  453.                WrtMapPointLong ( hWnd,
  454.                                  &points,
  455.                                  MP_SCALE,
  456.                                  WrtLocatorDevInfo.ulSensorXpts,
  457.                                  WrtLocatorDevInfo.ulSensorYpts,
  458.                                  0L,
  459.                                  0L,
  460.                                  1 );
  461.                GpiLine ( hpsClient, &points );
  462.                numpoints--;
  463.                if ( numpoints == 0 )
  464.                   {
  465.                   if ( changecolor )
  466.                      {
  467.                      changecolor = 0;
  468.                      GpiSetColor ( hpsClient, CLR_BLUE );
  469.                      }
  470.                   else
  471.                      {
  472.                      changecolor = 1;
  473.                      GpiSetColor ( hpsClient, CLR_RED );
  474.                      };
  475.                   numpoints=25;
  476.                   };
  477.                GpiMove ( hpsClient, &points );
  478.                return ( (MRESULT) 0 );
  479.                break;
  480.  
  481.       case  WM_LIFTOFF:
  482.                WinSetCapture ( HWND_DESKTOP, NULLHANDLE );
  483.                points.x = SHORT1FROMMP ( mp1 );
  484.                points.y = SHORT2FROMMP ( mp1 );
  485.                GpiLine ( hpsClient, &points );
  486.                WinReleasePS ( hpsClient );
  487.                return ( (MRESULT) LO_STROKE_PROCESSED );
  488.                break;
  489.  
  490.       default:
  491.                break;
  492.       };
  493.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  494.    };
  495.  
  496. /*****************************************************************************
  497. * WM_TOUCHDOWN: RETURN CODE: TDN_IMMEDIATE |                                 *
  498. *                            TDN_HEFREQ_MOUSEMOVE |                          *
  499. *                            TDN_NO_INK_STROKE                               *
  500. *                                                                            *
  501. * This is an example of how to use ink without a stroke buffer.              *
  502. *****************************************************************************/
  503. MRESULT APIENTRY  ink_without_stroke_buffer (  HWND     hWnd,
  504.                                                ULONG    ulMsg,
  505.                                                MPARAM   mp1,
  506.                                                MPARAM   mp2   )
  507.    {
  508.    HPS            hps;
  509.    static HPS     hpsClient;
  510.    static POINTL  points = { 0, 0 } ;
  511.    static RECTL   rcl;
  512.  
  513.    PMYWINDOWDATA  pMyWindowData;
  514.  
  515.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  516.    switch ( ulMsg )
  517.       {
  518.       case  WM_TOUCHDOWN:
  519.                pMyWindowData->td = TRUE;
  520.                hpsClient = WinGetPS ( hWnd );
  521.  
  522.                WinSetCapture ( HWND_DESKTOP, hWnd );
  523.                points.x = SHORT1FROMMP ( mp1 );
  524.                points.y = SHORT2FROMMP ( mp1 );
  525.                GpiMove ( hpsClient, &points );
  526.                WinQueryWindowRect   ( hWnd, &rcl );
  527.  
  528.  
  529.                StatusLine ( pMyWindowData, "Returning TDN_IMMEDIATE | TDN_HIFREQ_MOUSEMOVE | TDN_NO_INK_STROKE." );
  530.                return ( (MRESULT) ( TDN_IMMEDIATE        |
  531.                                     TDN_HIFREQ_MOUSEMOVE |
  532.                                     TDN_NO_INK_STROKE ));
  533.                break;
  534.  
  535.       case  WM_MOUSEMOVE:
  536.                if ( pMyWindowData->td )
  537.                   {
  538.                   /**********************************************************
  539.                   * Make sure that the sign is preserved by casting it to a *
  540.                   **********************************************************/
  541.                   points.x = (SHORT) SHORT1FROMMP ( mp1 );
  542.                   points.y = (SHORT) SHORT2FROMMP ( mp1 );
  543.  
  544.                   GpiLine ( hpsClient, &points );
  545.                   GpiMove ( hpsClient, &points );
  546.                   };
  547.                break;
  548.  
  549.       case  WM_LIFTOFF:
  550.                WinSetCapture ( HWND_DESKTOP, NULLHANDLE );
  551.                pMyWindowData->td = FALSE;
  552.                GpiMove ( hpsClient, &points );
  553.                points.x = SHORT1FROMMP ( mp1 );
  554.                points.y = SHORT2FROMMP ( mp1 );
  555.                GpiLine ( hpsClient, &points );
  556.  
  557.                WinReleasePS ( hpsClient );
  558.  
  559.                return ( (MRESULT) LO_DEFAULT );
  560.                break;
  561.  
  562.       default:
  563.                break;
  564.       };
  565.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  566.    };
  567.  
  568. /*****************************************************************************
  569. * WM_TOUCHDOWN: RETURN CODE: TDN_INFINITE  |                                 *
  570. *                            TDN_SENSOR_MOVE |                               *
  571. *                            TDN_LEAVE_INK                                   *
  572. *                                                                            *
  573. * This is an example of how to use ink with a stroke buffer.                 *
  574. *****************************************************************************/
  575. MRESULT APIENTRY  ink_with_stroke_buffer  ( HWND     hWnd,
  576.                                             ULONG    ulMsg,
  577.                                             MPARAM   mp1,
  578.                                             MPARAM   mp2   )
  579.    {
  580.    RECTL          rcl;
  581.    HPS            hps;
  582.    ULONG          ulBufLen;
  583.    PSTROKEDATA    pStrokeData;
  584.    ULONG          ulConversionOptions;
  585.    ULONG          ulXOutput;
  586.    ULONG          ulYOutput;
  587.    ULONG          ulAuxData;
  588.  
  589.    PMYWINDOWDATA  pMyWindowData;
  590.  
  591.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  592.    switch ( ulMsg )
  593.       {
  594.       case  WM_TOUCHDOWN:
  595.                StatusLine ( pMyWindowData, "Returning TDN_INFINITE | TDN_SENSOR_MOVE | TDN_LEAVE_INK" );
  596.                WinSetCapture ( HWND_DESKTOP, hWnd );
  597.                return ( (MRESULT) ( TDN_INFINITE    |
  598.                                     TDN_SENSOR_MOVE |
  599.                                     TDN_LEAVE_INK ));
  600.                break;
  601.  
  602.       case  WM_LIFTOFF:
  603.  
  604.                WinSetCapture ( HWND_DESKTOP, NULLHANDLE );
  605.  
  606.                /***************************************************************
  607.                * Get the stroke data size                                     *
  608.                ***************************************************************/
  609.                pStrokeData          = NULL;
  610.                ulBufLen             = 0;
  611.                ulConversionOptions  = QSD_SCALE;
  612.                ulXOutput            = 0;
  613.                ulYOutput            = 0;
  614.                ulAuxData            = 0;
  615.                if ( !WrtQueryStrokeData ( (PBYTE) pStrokeData,
  616.                                           &ulBufLen,
  617.                                           hWnd,
  618.                                           ulConversionOptions,
  619.                                           ulXOutput,
  620.                                           ulYOutput,
  621.                                           ulAuxData ) )
  622.                   {
  623.                   /************************************************************
  624.                   * Check to verify that buffer length is net set to zero     *
  625.                   ************************************************************/
  626.                   if ( !ulBufLen )
  627.                      {
  628.                      StatusLine ( pMyWindowData,"Zero Buffer Length");
  629.                      return((MPARAM)FALSE);
  630.                      };
  631.  
  632.                   /************************************************************
  633.                   * Allocate the memory for the stroke data                   *
  634.                   ************************************************************/
  635.                   DosAllocMem ( (VOID *) &pStrokeData,
  636.                                 ulBufLen,
  637.                                 PAG_COMMIT   |
  638.                                     PAG_READ |
  639.                                     PAG_WRITE );
  640.                   if ( pStrokeData == NULL )
  641.                      {
  642.                      StatusLine ( pMyWindowData,"DosAllocMem Failed");
  643.                      return((MPARAM)FALSE);
  644.                      };
  645.  
  646.                   /************************************************************
  647.                   * Initialize the structure                                  *
  648.                   ************************************************************/
  649.                   pStrokeData->cbStructSize = sizeof ( STROKEDATA );
  650.                   if ( !WrtQueryStrokeData ( (PBYTE) pStrokeData,
  651.                                              &ulBufLen,
  652.                                              hWnd,
  653.                                              ulConversionOptions,
  654.                                              ulXOutput,
  655.                                              ulYOutput,
  656.                                              ulAuxData ) )
  657.                      {
  658.                      hps = WinGetPS ( hWnd );
  659.                      GpiSetColor ( hps, CLR_BLUE );
  660.                      GpiMove ( hps,
  661.                                pStrokeData->pXY );
  662.                      GpiPolyLine( hps,
  663.                                   pStrokeData->ulNumPoints - 1L,
  664.                                   pStrokeData->pXY++ );
  665.                      WinReleasePS ( hps );
  666.                      };
  667.                   DosFreeMem ( (VOID *) pStrokeData );
  668.                   };
  669.  
  670.                return ( (MRESULT) LO_STROKE_PROCESSED );
  671.                break;
  672.  
  673.       default:
  674.                break;
  675.       };
  676.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  677.    };
  678.  
  679. /*****************************************************************************
  680. * WM_TOUCHDOWN: RETURN CODE: TDN_DEFAULT_DELAY |                             *
  681. *                            TDN_INK_STROKE                                  *
  682. *                                                                            *
  683. * This is default ink processing.                                            *
  684. *****************************************************************************/
  685. MRESULT APIENTRY  default_inking     ( HWND     hWnd,
  686.                                        ULONG    ulMsg,
  687.                                        MPARAM   mp1,
  688.                                        MPARAM   mp2   )
  689.    {
  690.    RECTL       rcl;
  691.    static      HPS         hps;
  692.    static      HPOINTER    hptrOld;
  693.    HPOINTER                hptrNew;
  694.  
  695.    PMYWINDOWDATA  pMyWindowData;
  696.  
  697.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  698.    switch ( ulMsg )
  699.       {
  700.       case  WM_TOUCHDOWN:
  701.                StatusLine ( pMyWindowData, "Returning TDN_DEFAULT_DELAY | TDN_INK_STROKE" );
  702.                WinSetCapture ( HWND_DESKTOP, hWnd );
  703.                return ( (MRESULT) ( TDN_DEFAULT_DELAY |
  704.                                     TDN_INK_STROKE      ) );
  705.                break;
  706.  
  707.       case  WM_PAUSE_TIMEOUT:
  708.                hptrNew = WinQuerySysPointer ( HWND_DESKTOP,
  709.                                               SPTR_ILLEGAL,
  710.                                               FALSE );
  711.                hptrOld = WinQueryPointer ( HWND_DESKTOP );
  712.                WinSetPointer ( HWND_DESKTOP, hptrNew );
  713.                break;
  714.  
  715.       case  WM_LIFTOFF:
  716.                WinSetPointer ( HWND_DESKTOP, hptrOld );
  717.                break;
  718.  
  719.       default:
  720.                break;
  721.       };
  722.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  723.    };
  724.  
  725. /*****************************************************************************
  726. * WM_LIFTOFF: RETURN CODE: LO_DEFAULT                                        *
  727. *                                                                            *
  728. * The default behavior is to continue with gesture recognition and send a    *
  729. * WM_STROKE and WM_RECO messages.                                            *
  730. *****************************************************************************/
  731. MRESULT APIENTRY  lo_default (  HWND     hWnd,
  732.                                 ULONG    ulMsg,
  733.                                 MPARAM   mp1,
  734.                                 MPARAM   mp2   )
  735.    {
  736.    RECTL       rcl;
  737.    HPS         hps;
  738.  
  739.    PMYWINDOWDATA  pMyWindowData;
  740.  
  741.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  742.    switch ( ulMsg )
  743.       {
  744.       case  WM_LIFTOFF:
  745.                StatusLine ( pMyWindowData, "Returning LO_DEFAULT" );
  746.                return ( (MRESULT) LO_DEFAULT );
  747.                break;
  748.  
  749.       case  WM_STROKE:
  750.                StatusLine ( pMyWindowData, "WM_STROKE received");
  751.                return ( (MRESULT) TRUE );
  752.                break;
  753.  
  754.       case  WM_RECO:
  755.                StatusLine ( pMyWindowData, "WM_RECO received");
  756.                return ( (MRESULT) TRUE );
  757.                break;
  758.  
  759.       default:
  760.                break;
  761.       };
  762.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  763.    };
  764.  
  765. /*****************************************************************************
  766. * WM_LIFTOFF: RETURN CODE: LO_STROKE_PROCESSED                               *
  767. *                                                                            *
  768. * Inform PenPM that the stroke has been processed and to not perform any     *
  769. * furthur processing on the stroke.
  770. *****************************************************************************/
  771. MRESULT APIENTRY  lo_stroke_processed (  HWND     hWnd,
  772.                                          ULONG    ulMsg,
  773.                                          MPARAM   mp1,
  774.                                          MPARAM   mp2   )
  775.    {
  776.    RECTL       rcl;
  777.    HPS         hps;
  778.  
  779.    PMYWINDOWDATA  pMyWindowData;
  780.  
  781.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  782.    switch ( ulMsg )
  783.       {
  784.       case  WM_LIFTOFF:
  785.                StatusLine ( pMyWindowData, "Returning LO_STROKE_PROCESSED" );
  786.                return ( (MRESULT) LO_STROKE_PROCESSED );
  787.                break;
  788.  
  789.       default:
  790.                break;
  791.       };
  792.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  793.    };
  794.  
  795. /*****************************************************************************
  796. * WM_LIFTOFF: RETURN CODE: LO_EMULATE_MOUSE                                  *
  797. *                                                                            *
  798. * Inform PenPM to send the mouse button down and up messages.                *
  799. *****************************************************************************/
  800. MRESULT APIENTRY  lo_emulate_mouse (  HWND     hWnd,
  801.                                       ULONG    ulMsg,
  802.                                       MPARAM   mp1,
  803.                                       MPARAM   mp2   )
  804.    {
  805.    RECTL       rcl;
  806.    HPS         hps;
  807.    int         b1d;
  808.    int         b1u;
  809.  
  810.    PMYWINDOWDATA  pMyWindowData;
  811.  
  812.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  813.    switch ( ulMsg )
  814.       {
  815.       case  WM_LIFTOFF:
  816.                StatusLine ( pMyWindowData, "Returning LO_EMULATE_MOUSE" );
  817.                return ( (MRESULT) LO_EMULATE_MOUSE );
  818.                break;
  819.  
  820.       case  WM_BUTTON1DOWN:
  821.                StatusLine ( pMyWindowData, "WM_BUTTON1DOWN" );
  822.                b1d++;
  823.                break;
  824.  
  825.       case  WM_BUTTON1UP:
  826.                b1u++;
  827.                StatusLine ( pMyWindowData, "WM_BUTTON1UP" );
  828.                break;
  829.  
  830.       default:
  831.                break;
  832.       };
  833.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  834.    };
  835.  
  836. /*****************************************************************************
  837. * WM_STROKE: RETURN CODE: STK_DEFAULT                                        *
  838. *                                                                            *
  839. * Application does not process stroke. Informs PenPM to do gesture           *
  840. * recognition processing.                                                    *
  841. *****************************************************************************/
  842. MRESULT APIENTRY  stk_default (  HWND     hWnd,
  843.                                  ULONG    ulMsg,
  844.                                  MPARAM   mp1,
  845.                                  MPARAM   mp2   )
  846.    {
  847.    RECTL       rcl;
  848.    HPS         hps;
  849.  
  850.    PMYWINDOWDATA  pMyWindowData;
  851.  
  852.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  853.    switch ( ulMsg )
  854.       {
  855.       case  WM_STROKE:
  856.                StatusLine ( pMyWindowData, "Returning STK_DEFAULT" );
  857.                return ( (MRESULT) STK_DEFAULT );
  858.                break;
  859.  
  860.       case  WM_RECO:
  861.                StatusLine ( pMyWindowData, "WM_RECO received");
  862.                return ( (MRESULT) TRUE );
  863.                break;
  864.  
  865.       default:
  866.                break;
  867.       };
  868.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  869.    };
  870.  
  871. /*****************************************************************************
  872. * WM_STROKE: RETURN CODE: STK_STROKE_PROCESSED                               *
  873. *                                                                            *
  874. * Inform PenPM that the application has already processed the stroke and     *
  875. * thus do not continue with gesture recognition processing.                  *
  876. *****************************************************************************/
  877. MRESULT APIENTRY  stk_stroke_processed (  HWND     hWnd,
  878.                                           ULONG    ulMsg,
  879.                                           MPARAM   mp1,
  880.                                           MPARAM   mp2   )
  881.    {
  882.    RECTL       rcl;
  883.    HPS         hps;
  884.  
  885.    PMYWINDOWDATA  pMyWindowData;
  886.  
  887.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  888.    switch ( ulMsg )
  889.       {
  890.       case  WM_STROKE:
  891.                StatusLine ( pMyWindowData, "Returning STK_STROKE_PROCESSED" );
  892.                return ( (MRESULT) STK_STROKE_PROCESSED );
  893.                break;
  894.  
  895.       default:
  896.                break;
  897.       };
  898.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  899.    };
  900.  
  901. /*****************************************************************************
  902. * WM_SENSOR_MOVE: RETURN: VOID                                               *
  903. *                                                                            *
  904. * Inform PenPM at WM_TOUCHDOWN to send us all points as WM_SENSOR_MOVE's     *
  905. * with sensor resolution. Note that this does not mean that WM_MOUSEMOVE's   *
  906. * will not be sent. WM_MOUSEMOVE's are always being sent around PM to move   *
  907. * mouse pointer. WM_SENSOR_MOVE's at sensor resolution are usually much      *
  908. * better for things like gesture and handwriting recognition processing.     *
  909. *****************************************************************************/
  910. MRESULT APIENTRY  wm_sensor_move (  HWND     hWnd,
  911.                                     ULONG    ulMsg,
  912.                                     MPARAM   mp1,
  913.                                     MPARAM   mp2   )
  914.    {
  915.    RECTL                    rcl;
  916.    HPS                      hps;
  917.    static HPS               hpsClient;
  918.    static POINTL            points = { 0, 0 } ;
  919.    static BOOL              FirstTime = TRUE;
  920.    static WRTLOCATORDEVINFO WrtLocatorDevInfo;
  921.    WRTEVENTDATA             WrtEventData;
  922.    static SHORT             changecolor = 0;
  923.    static SHORT             numpoints  = 26;
  924.  
  925.    PMYWINDOWDATA  pMyWindowData;
  926.  
  927.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  928.    switch ( ulMsg )
  929.       {
  930.       case  WM_TOUCHDOWN:
  931.                if ( FirstTime )
  932.                   {
  933.                   WrtEventData = *( (PWRTEVENTDATA) PVOIDFROMMP ( mp2 ) );
  934.                   WrtLocatorDevInfo.cbStructSize = sizeof ( WRTLOCATORDEVINFO );
  935.                   WrtQueryLocatorCaps ( &WrtEventData.ulLocatorID, &WrtLocatorDevInfo );
  936.                   FirstTime=FALSE;
  937.                   };
  938.                WinSetCapture ( HWND_DESKTOP, hWnd );
  939.                hpsClient = WinGetPS ( hWnd );
  940.                points.x = SHORT1FROMMP ( mp1 );
  941.                points.y = SHORT2FROMMP ( mp1 );
  942.                GpiMove ( hpsClient, &points );
  943.                GpiSetColor ( hpsClient, CLR_BLUE );
  944.                numpoints = 25;
  945.                StatusLine ( pMyWindowData, "Returning TDN_INFINITE | TDN_SENSOR_MOVE | TDN_NO_INK_STROKE." );
  946.                return ( (MRESULT) ( TDN_INFINITE | TDN_SENSOR_MOVE | TDN_NO_INK_STROKE ) );
  947.                break;
  948.  
  949.       case  WM_SENSOR_MOVE:
  950.                points.x = SHORT1FROMMP ( mp1 );
  951.                points.y = SHORT2FROMMP ( mp1 );
  952.                WrtMapPointLong ( hWnd,
  953.                                  &points,
  954.                                  MP_SCALE,
  955.                                  WrtLocatorDevInfo.ulSensorXpts,
  956.                                  WrtLocatorDevInfo.ulSensorYpts,
  957.                                  0L,
  958.                                  0L,
  959.                                  1 );
  960.                GpiLine ( hpsClient, &points );
  961.                numpoints--;
  962.                if ( numpoints == 0 )
  963.                   {
  964.                   if ( changecolor )
  965.                      {
  966.                      changecolor = 0;
  967.                      GpiSetColor ( hpsClient, CLR_BLUE );
  968.                      }
  969.                   else
  970.                      {
  971.                      changecolor = 1;
  972.                      GpiSetColor ( hpsClient, CLR_RED );
  973.                      };
  974.                   numpoints=25;
  975.                   };
  976.                GpiMove ( hpsClient, &points );
  977.                return ( (MRESULT) 0 );
  978.                break;
  979.  
  980.       case  WM_LIFTOFF:
  981.                WinSetCapture ( HWND_DESKTOP, NULLHANDLE );
  982.                points.x = SHORT1FROMMP ( mp1 );
  983.                points.y = SHORT2FROMMP ( mp1 );
  984.                GpiLine ( hpsClient, &points );
  985.                WinReleasePS ( hpsClient );
  986.                return ( (MRESULT) LO_STROKE_PROCESSED );
  987.                break;
  988.  
  989.       default:
  990.                break;
  991.       };
  992.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  993.    };
  994.  
  995. /*****************************************************************************
  996. * WM_TAP: RETURN: TP_DEFAULT                                                 *
  997. *                                                                            *
  998. * Tell PenPM to perform mouse emulation, ie send WM_BUTTON1DOWN and          *
  999. * WM_BUTTON1UP messages. However, if you return TDN_INFINITE at WM_TOUCHDOWN *
  1000. * the button events will not be sent.                                        *
  1001. *****************************************************************************/
  1002. MRESULT APIENTRY  tap_tp_default (  HWND     hWnd,
  1003.                                     ULONG    ulMsg,
  1004.                                     MPARAM   mp1,
  1005.                                     MPARAM   mp2   )
  1006.    {
  1007.    RECTL       rcl;
  1008.    HPS         hps;
  1009.    static int  tap = FALSE;
  1010.  
  1011.    PMYWINDOWDATA  pMyWindowData;
  1012.  
  1013.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1014.    switch ( ulMsg )
  1015.       {
  1016.       case  WM_TAP:
  1017.                tap = TRUE;
  1018.                StatusLine ( pMyWindowData, "Returning TP_DEFAULT. ");
  1019.                return ( (MRESULT) TP_DEFAULT );
  1020.                break;
  1021.  
  1022.       case  WM_BUTTON1DOWN:
  1023.                if ( tap )
  1024.                   {
  1025.                   StatusLine ( pMyWindowData, "Mouse emulation" );
  1026.                   tap = FALSE;
  1027.                   };
  1028.                break;
  1029.  
  1030.       default:
  1031.                break;
  1032.       };
  1033.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1034.    };
  1035.  
  1036. /*****************************************************************************
  1037. * WM_TAP: RETURN: TP_TAP_PROCESSED                                           *
  1038. *                                                                            *
  1039. * Inform PenPM that the application has processed the WM_TAP message and     *
  1040. * take no furthur action in processing the event.                            *
  1041. *****************************************************************************/
  1042. MRESULT APIENTRY  tap_tp_tap_processed (  HWND     hWnd,
  1043.                                           ULONG    ulMsg,
  1044.                                           MPARAM   mp1,
  1045.                                           MPARAM   mp2   )
  1046.    {
  1047.    RECTL       rcl;
  1048.    HPS         hps;
  1049.    static int  tap = FALSE;
  1050.  
  1051.    PMYWINDOWDATA  pMyWindowData;
  1052.  
  1053.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1054.    switch ( ulMsg )
  1055.       {
  1056.       case  WM_TAP:
  1057.                tap = TRUE;
  1058.                StatusLine ( pMyWindowData, "Returning TP_TAP_PROCESSED. ");
  1059.                return ( (MRESULT) TP_TAP_PROCESSED );
  1060.                break;
  1061.  
  1062.       case  WM_BUTTON1DOWN:
  1063.                if ( tap )
  1064.                   {
  1065.                   StatusLine ( pMyWindowData, "Mouse emulation" );
  1066.                   tap = FALSE;
  1067.                   };
  1068.                break;
  1069.  
  1070.       default:
  1071.                break;
  1072.       };
  1073.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1074.    };
  1075.  
  1076. /*****************************************************************************
  1077. * WM_DBL_TAP: RETURN: TP_DEFAULT                                             *
  1078. *                                                                            *
  1079. * Tell PenPM to perform mouse emulation, ie send WM_BUTTON1DOWN and          *
  1080. * WM_BUTTON1UP messages. However, if you return TDN_INFINITE at WM_TOUCHDOWN *
  1081. * the button events will not be sent.                                        *
  1082. *****************************************************************************/
  1083. MRESULT APIENTRY  dbl_tap_tp_default (  HWND     hWnd,
  1084.                                         ULONG    ulMsg,
  1085.                                         MPARAM   mp1,
  1086.                                         MPARAM   mp2   )
  1087.    {
  1088.    RECTL       rcl;
  1089.    HPS         hps;
  1090.    static int  tap = FALSE;
  1091.  
  1092.    PMYWINDOWDATA  pMyWindowData;
  1093.  
  1094.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1095.    switch ( ulMsg )
  1096.       {
  1097.       case  WM_DBL_TAP:
  1098.                tap = TRUE;
  1099.                StatusLine ( pMyWindowData, "Returning TP_DEFAULT. ");
  1100.                return ( (MRESULT) TP_DEFAULT );
  1101.                break;
  1102.  
  1103.       case  WM_BUTTON1DOWN:
  1104.                if ( tap )
  1105.                   {
  1106.                   StatusLine ( pMyWindowData, "Mouse emulation." );
  1107.                   tap = FALSE;
  1108.                   };
  1109.                break;
  1110.  
  1111.       default:
  1112.                break;
  1113.       };
  1114.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1115.    };
  1116.  
  1117. /*****************************************************************************
  1118. * WM_DBL_TAP: RETURN: TP_TAP_PROCESSED                                       *
  1119. *                                                                            *
  1120. * Inform PenPM that the application has processed the WM_TAP message and     *
  1121. * take no furthur action in processing the event.                            *
  1122. *****************************************************************************/
  1123. MRESULT APIENTRY  dbl_tap_tp_tap_processed (  HWND     hWnd,
  1124.                                               ULONG    ulMsg,
  1125.                                               MPARAM   mp1,
  1126.                                               MPARAM   mp2   )
  1127.    {
  1128.    RECTL       rcl;
  1129.    HPS         hps;
  1130.    static int  tap = FALSE;
  1131.  
  1132.    PMYWINDOWDATA  pMyWindowData;
  1133.  
  1134.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1135.    switch ( ulMsg )
  1136.       {
  1137.       case  WM_DBL_TAP:
  1138.                tap = TRUE;
  1139.                StatusLine ( pMyWindowData, "Returning TP_TAP_PROCESSED. ");
  1140.                return ( (MRESULT) TP_TAP_PROCESSED );
  1141.                break;
  1142.  
  1143.       case  WM_BUTTON1DOWN:
  1144.                if ( tap )
  1145.                   {
  1146.                   tap = FALSE;
  1147.                   StatusLine ( pMyWindowData, "Mouse emulation." );
  1148.                   };
  1149.                break;
  1150.  
  1151.       default:
  1152.                break;
  1153.       };
  1154.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1155.    };
  1156.  
  1157. /*****************************************************************************
  1158. * WM_PAUSE_TIMEOUT: RETURN: PTO_DEFAULT                                      *
  1159. *                                                                            *
  1160. * This message is generated by PenPM when the user has touched the sensor    *
  1161. * and remained motionless for a period of time. PTO_DEFAULT tells PenPM to   *
  1162. * allow mouse emulation.                                                     *
  1163. *****************************************************************************/
  1164. MRESULT APIENTRY  pto_default (  HWND     hWnd,
  1165.                                  ULONG    ulMsg,
  1166.                                  MPARAM   mp1,
  1167.                                  MPARAM   mp2   )
  1168.    {
  1169.    RECTL       rcl;
  1170.    HPS         hps;
  1171.    static BOOL pto = FALSE;
  1172.  
  1173.    PMYWINDOWDATA  pMyWindowData;
  1174.  
  1175.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1176.    switch ( ulMsg )
  1177.       {
  1178.       case  WM_PAUSE_TIMEOUT:
  1179.                pto = TRUE;
  1180.                StatusLine ( pMyWindowData, "Returning PTO_DEFAULT. ");
  1181.                return ( (MRESULT) PTO_DEFAULT );
  1182.                break;
  1183.  
  1184.       case  WM_BUTTON1DOWN:
  1185.                if ( pto )
  1186.                   {
  1187.                   StatusLine ( pMyWindowData, "Mouse emulation" );
  1188.                   pto = FALSE;
  1189.                   };
  1190.                break;
  1191.  
  1192.       default:
  1193.                break;
  1194.       };
  1195.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1196.    };
  1197.  
  1198. /*****************************************************************************
  1199. * WM_PAUSE_TIMEOUT: RETURN: PTO_CONTINUE                                     *
  1200. *                                                                            *
  1201. * This message is generated by PenPM when the user has touched the sensor    *
  1202. * and remained motionless for a period of time. PTO_CONTINUE tells PenPM to  *
  1203. * remain in a gesture mode and not perform mouse emulation.                  *
  1204. *****************************************************************************/
  1205. MRESULT APIENTRY  pto_continue (  HWND     hWnd,
  1206.                                   ULONG    ulMsg,
  1207.                                   MPARAM   mp1,
  1208.                                   MPARAM   mp2   )
  1209.    {
  1210.    RECTL       rcl;
  1211.    HPS         hps;
  1212.  
  1213.    PMYWINDOWDATA  pMyWindowData;
  1214.  
  1215.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1216.    switch ( ulMsg )
  1217.       {
  1218.       case  WM_PAUSE_TIMEOUT:
  1219.                StatusLine ( pMyWindowData, "Returning PTO_CONTINUE. ");
  1220.                return ( (MRESULT) PTO_CONTINUE );
  1221.                break;
  1222.  
  1223.       default:
  1224.                break;
  1225.       };
  1226.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1227.    };
  1228.  
  1229. /*****************************************************************************
  1230. * WM_EXIT_PROXIMITY: RETURN: VOID                                            *
  1231. *                                                                            *
  1232. * This indicates that the pointing device has left proximity to the sensor.  *
  1233. * Note that not all devices provide proximity data.                          *
  1234. *****************************************************************************/
  1235. MRESULT APIENTRY  wm_exit_proximity (  HWND     hWnd,
  1236.                                        ULONG    ulMsg,
  1237.                                        MPARAM   mp1,
  1238.                                        MPARAM   mp2   )
  1239.    {
  1240.    RECTL       rcl;
  1241.    HPS         hps;
  1242.  
  1243.    PMYWINDOWDATA  pMyWindowData;
  1244.  
  1245.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1246.    switch ( ulMsg )
  1247.       {
  1248.       case  WM_EXIT_PROXIMITY:
  1249.                StatusLine ( pMyWindowData, "Exiting Proximity" );
  1250.                return ( (MRESULT) 0 );
  1251.                break;
  1252.  
  1253.       default:
  1254.                break;
  1255.       };
  1256.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1257.    };
  1258.  
  1259. /*****************************************************************************
  1260. * WM_WRT_DEV_CAPS_CHANGE: RETURN: VOID                                       *
  1261. *                                                                            *
  1262. * This message indicates a change to the device capabilities has been        *
  1263. * reported to PenPM.                                                         *
  1264. *****************************************************************************/
  1265. MRESULT APIENTRY  wm_wrt_dev_caps_change (  HWND     hWnd,
  1266.                                             ULONG    ulMsg,
  1267.                                             MPARAM   mp1,
  1268.                                             MPARAM   mp2   )
  1269.    {
  1270.    RECTL       rcl;
  1271.    HPS         hps;
  1272.  
  1273.    PMYWINDOWDATA  pMyWindowData;
  1274.  
  1275.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1276.    switch ( ulMsg )
  1277.       {
  1278.       case  WM_WRT_DEV_CAPS_CHANGE:
  1279.                StatusLine ( pMyWindowData, "Device capabilities changed" );
  1280.                return ( (MRESULT) 0 );
  1281.                break;
  1282.  
  1283.       default:
  1284.                break;
  1285.       };
  1286.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1287.    };
  1288.  
  1289. /*****************************************************************************
  1290. * WM_WRT_SYSVALUECHANGED: RETURN: VOID                                       *
  1291. *                                                                            *
  1292. * This message indicates that a change to the PenPM system variables has     *
  1293. * occurred. Note that it is the responsibility of the program changing the   *
  1294. * value to broadcaset this message to the rest of the system.                *
  1295. *****************************************************************************/
  1296. MRESULT APIENTRY  wm_wrt_sysvaluechanged (  HWND     hWnd,
  1297.                                             ULONG    ulMsg,
  1298.                                             MPARAM   mp1,
  1299.                                             MPARAM   mp2   )
  1300.    {
  1301.    RECTL       rcl;
  1302.    HPS         hps;
  1303.  
  1304.    PMYWINDOWDATA  pMyWindowData;
  1305.  
  1306.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1307.    switch ( ulMsg )
  1308.       {
  1309.       case  WM_WRT_SYSVALUECHANGED:
  1310.                StatusLine ( pMyWindowData, "System value changed" );
  1311.                return ( (MRESULT) 0 );
  1312.                break;
  1313.  
  1314.       default:
  1315.                break;
  1316.       };
  1317.    return( (MRESULT) ISMCOMMON ( hWnd, ulMsg, mp1, mp2 )  );
  1318.    };
  1319.  
  1320. /*****************************************************************************
  1321. * This is an example of inking and editing of ink using the capabilities of  *
  1322. * the graphics engine, provided with OS/2 2.1. You enter ink while in a      *
  1323. * freehand mode. The ink is grouped into sets of strokes from the moment of  *
  1324. * touchdown until the sensor leaves proximity. You can change the color of   *
  1325. * an entire group with a C-tap gesture. You can delete an entire group with  *
  1326. * an X gesture. You can delete any individual stroke with a pigtail gesture. *
  1327. *****************************************************************************/
  1328. MRESULT APIENTRY InkEditing (  HWND     hWnd,
  1329.                                ULONG    ulMsg,
  1330.                                MPARAM   mp1,
  1331.                                MPARAM   mp2   )
  1332. {
  1333.    RECTL          rcl;
  1334.    SIZEL          PickSize;
  1335.    SHORT          NumHits;
  1336.    SIZEL          PageSize;
  1337.    HWND           hMenu;
  1338.    MENUITEM       menuitem;
  1339.    PMYWINDOWDATA  pMyWindowData;
  1340.    HRGN           hrgn;
  1341.    HRGN           hrgnold;
  1342.    HPS            hpspaint;
  1343.    LINEWIDTHORDER LineWidthOrder;
  1344.    SHORT          i;
  1345.  
  1346.    PickSize.cx = 10;
  1347.    PickSize.cy = 10;
  1348.    pMyWindowData = (PMYWINDOWDATA) WinQueryWindowPtr ( hWnd, 0 );
  1349.    switch ( ulMsg )
  1350.       {
  1351.       case  WM_INITMYWINDOW:
  1352.  
  1353.                /**************************************************************
  1354.                * Add Pen input mode menu item                                *
  1355.                **************************************************************/
  1356.                hMenu = WinWindowFromID ( WinQueryWindow ( hWnd, QW_PARENT ),
  1357.                                          FID_MENU );
  1358.                menuitem.iPosition   = MIT_END;
  1359.                menuitem.afStyle     = MIS_TEXT;
  1360.                menuitem.afAttribute = 0;
  1361.                menuitem.id          = ID_MENUITEM;
  1362.                menuitem.hItem       = 0;
  1363.                menuitem.hwndSubMenu = 0;
  1364.  
  1365.                WinSendMsg ( hMenu,
  1366.                             MM_INSERTITEM,
  1367.                             (MPARAM) &menuitem,
  1368.                             (MPARAM) "GestureMode" );
  1369.  
  1370.                /**************************************************************
  1371.                * Initialize window instance data                             *
  1372.                **************************************************************/
  1373.                DosAllocMem ( (VOID *) &pMyWindowData,
  1374.                              sizeof(MYWINDOWDATA),
  1375.                              PAG_COMMIT   |
  1376.                                  PAG_READ |
  1377.                                  PAG_WRITE );
  1378.                pMyWindowData->MyWindow = hWnd;
  1379.                pMyWindowData->StatusWindow   = (HWND) mp1;
  1380.                pMyWindowData->freehand       = TRUE;
  1381.                pMyWindowData->NewSegment     = TRUE;
  1382.                pMyWindowData->SegmentName    = 1;
  1383.                pMyWindowData->ElementName    = 0;
  1384.                if ( !WinSetWindowPtr ( hWnd, 0, (PVOID) pMyWindowData ) )
  1385.                   return ( (MPARAM) FALSE );
  1386.  
  1387.                /**************************************************************
  1388.                * Create the presentation space for the window                *
  1389.                **************************************************************/
  1390.                pMyWindowData->hab = WinQueryAnchorBlock ( hWnd );
  1391.                pMyWindowData->hdc = WinOpenWindowDC ( hWnd );
  1392.                DevQueryCaps ( pMyWindowData->hdc, CAPS_WIDTH, 1L, &PageSize.cx );
  1393.                DevQueryCaps ( pMyWindowData->hdc, CAPS_WIDTH, 1L, &PageSize.cy );
  1394.                pMyWindowData->hps = GpiCreatePS ( pMyWindowData->hab,
  1395.                                                   pMyWindowData->hdc,
  1396.                                                   &PageSize,
  1397.                                                   ( PU_PELS      |
  1398.                                                     GPIT_NORMAL  |
  1399.                                                     GPIF_LONG    |
  1400.                                                     GPIA_ASSOC   ) );
  1401.                if ( pMyWindowData->hps == GPI_ERROR )
  1402.                   {
  1403.                   StatusLine ( pMyWindowData, "Could not create PS" );
  1404.                   WinPostMsg ( hWnd, WM_CLOSE, (MPARAM) 0, (MPARAM) 0 );
  1405.                   };
  1406.  
  1407.                /**************************************************************
  1408.                * Prepare the presentation space for drawing and retaining    *
  1409.                * the graphic primatives                                      *
  1410.                **************************************************************/
  1411.                GpiSetDrawingMode         ( pMyWindowData->hps,
  1412.                                            DM_DRAWANDRETAIN );
  1413.                GpiSetInitialSegmentAttrs ( pMyWindowData->hps,
  1414.                                            ATTR_FASTCHAIN,
  1415.                                            ATTR_OFF );
  1416.                GpiSetDrawControl         ( pMyWindowData->hps,
  1417.                                            DCTL_ERASE,
  1418.                                            DCTL_OFF );
  1419.                GpiSetDrawControl         ( pMyWindowData->hps,
  1420.                                            DCTL_CORRELATE,
  1421.                                            DCTL_ON );
  1422.                GpiSetDrawControl         ( pMyWindowData->hps,
  1423.                                            DCTL_BOUNDARY,
  1424.                                            DCTL_OFF );
  1425.                GpiSetInitialSegmentAttrs ( pMyWindowData->hps,
  1426.                                            ATTR_DETECTABLE,
  1427.                                            ATTR_OFF );
  1428.                pMyWindowData->points.x = 0;
  1429.                pMyWindowData->points.y = 0;
  1430.                GpiMove ( pMyWindowData->hps, &pMyWindowData->points );
  1431.                pMyWindowData->points.x = PageSize.cx;
  1432.                pMyWindowData->points.y = PageSize.cy;
  1433.                GpiOpenSegment  ( pMyWindowData->hps,
  1434.                                  pMyWindowData->SegmentName );
  1435.                GpiSetColor ( pMyWindowData->hps, CLR_PALEGRAY );
  1436.                GpiBox ( pMyWindowData->hps, DRO_FILL, &pMyWindowData->points, 0L, 0L );
  1437.                GpiCloseSegment ( pMyWindowData->hps );
  1438.                pMyWindowData->CurrentColor = InkColor[0];
  1439.                GpiSetColor ( pMyWindowData->hps, pMyWindowData->CurrentColor );
  1440.                GpiSetInitialSegmentAttrs ( pMyWindowData->hps,
  1441.                                            ATTR_DETECTABLE,
  1442.                                            ATTR_ON );
  1443.  
  1444.                WinShowWindow ( hWnd, TRUE );
  1445.  
  1446.                pMyWindowData->InkColors = CreateInkControls ( hWnd );
  1447.                GpiSetPickApertureSize ( pMyWindowData->hps, PICKAP_REC, &PickSize );
  1448.  
  1449.                WinSetFocus     ( HWND_DESKTOP, hWnd );
  1450.  
  1451.                StatusLine ( pMyWindowData, "Freehand Mode" );
  1452.                return((MRESULT) TRUE);
  1453.                break;
  1454.  
  1455.       /***********************************************************************
  1456.       * Process the help request                                             *
  1457.       ***********************************************************************/
  1458.       case  WM_PROCESSDIALOG:
  1459.                WinDlgBox (  HWND_DESKTOP,
  1460.                             hWnd,
  1461.                             InkEditHelp,
  1462.                             NULLHANDLE,
  1463.                             ID_INKEDITGESTUREHELP,
  1464.                             NULL );
  1465.                return((MRESULT) TRUE);
  1466.                break;
  1467.  
  1468.       /***********************************************************************
  1469.       * Process the menu selections                                          *
  1470.       ***********************************************************************/
  1471.       case  WM_COMMAND:
  1472.                switch ( SHORT1FROMMP (mp1) )
  1473.                   {
  1474.                   case  ID_QUIT:
  1475.                         WinPostMsg ( hWnd, WM_CLOSE, 0, 0 );
  1476.                         break;
  1477.  
  1478.                   case  ID_MENUITEM:
  1479.                            pMyWindowData->freehand = FALSE;
  1480.                            StatusLine ( pMyWindowData, "Gesture Mode - ? for Help" );
  1481.                            break;
  1482.                   default:
  1483.                         break;
  1484.                   };
  1485.                break;
  1486.  
  1487.       /***********************************************************************
  1488.       * When we get focus, update the status line to indicate the mode this  *
  1489.       * window is in.                                                        *
  1490.       ***********************************************************************/
  1491.       case  WM_SETFOCUS:
  1492.                if ( pMyWindowData != NULL )
  1493.                   {
  1494.                   if ( pMyWindowData->freehand )
  1495.                      {
  1496.                      StatusLine ( pMyWindowData, "Freehand Mode" );
  1497.                      }
  1498.                   else
  1499.                      {
  1500.                      StatusLine ( pMyWindowData, "Gesture Mode - ? for Help" );
  1501.                      };
  1502.                   };
  1503.                break;
  1504.  
  1505.       /***********************************************************************
  1506.       * Set the current color to the value selected in the ink colors        *
  1507.       * value set control.                                                   *
  1508.       ***********************************************************************/
  1509.       case  WM_CONTROL:
  1510.                switch ( SHORT2FROMMP(mp1) )
  1511.                   {
  1512.                   case  VN_SELECT:
  1513.                         switch ( SHORT1FROMMP(mp1) )
  1514.                         {
  1515.                            case  ID_VALUE_SET_INK:
  1516.                                  pMyWindowData->CurrentColor = InkColor[SHORT1FROMMP ( mp2 )-1];
  1517.                                  break;
  1518.  
  1519.                            default:
  1520.                                  break;
  1521.                         };
  1522.                         return( (MPARAM)TRUE );
  1523.                         break;
  1524.  
  1525.                   default:
  1526.                         break;
  1527.                   };
  1528.                break;
  1529.  
  1530.       /***********************************************************************
  1531.       * The use has touched the sensor. If this is to be a new segment, then *
  1532.       * setup the segment attributes for color, width, lineend, and linejoin.*
  1533.       * Then begin a new stroke. The importent thing to do here is set the   *
  1534.       * tag for the element and set a label with the same value for later    *
  1535.       * locating this point.                                                 *
  1536.       ***********************************************************************/
  1537.       case  WM_TOUCHDOWN:
  1538.                if ( pMyWindowData->freehand )
  1539.                   {
  1540.                   pMyWindowData->SegmentName++;
  1541.                   if ( pMyWindowData->NewSegment )
  1542.                      {
  1543.                      pMyWindowData->ElementName = 0;
  1544.                      pMyWindowData->NewSegment  = FALSE;
  1545.                      GpiOpenSegment      ( pMyWindowData->hps,
  1546.                                            pMyWindowData->SegmentName );
  1547.                      GpiLabel            ( pMyWindowData->hps,
  1548.                                            LABEL_BEGIN_SEGMENT );
  1549.  
  1550.                      GpiLabel            ( pMyWindowData->hps,
  1551.                                            LABEL_BEGIN_COLOR );
  1552.                      GpiSetColor         ( pMyWindowData->hps,
  1553.                                            pMyWindowData->CurrentColor );
  1554.                      GpiLabel            ( pMyWindowData->hps,
  1555.                                            LABEL_END_COLOR );
  1556.  
  1557.                      GpiLabel            ( pMyWindowData->hps,
  1558.                                            LABEL_BEGIN_WIDTH );
  1559.                      GpiSetLineWidthGeom ( pMyWindowData->hps, 1L );
  1560.                      GpiLabel            ( pMyWindowData->hps,
  1561.                                            LABEL_END_WIDTH );
  1562.  
  1563.                      GpiSetLineEnd       ( pMyWindowData->hps, LINEEND_ROUND );
  1564.                      GpiSetLinejOIN      ( pMyWindowData->hps, LINEJOIN_ROUND );
  1565.  
  1566.                      };
  1567.                   pMyWindowData->ElementName++;
  1568.                   GpiSetTag       ( pMyWindowData->hps,
  1569.                                     pMyWindowData->ElementName );
  1570.                   GpiLabel        ( pMyWindowData->hps,
  1571.                                     pMyWindowData->ElementName );
  1572.                   GpiLabel        ( pMyWindowData->hps,
  1573.                                     LABEL_BEGIN_STROKE );
  1574.                   GpiLabel        ( pMyWindowData->hps,
  1575.                                     LABEL_BEGIN_BEGIN_PATH );
  1576.                   GpiLabel        ( pMyWindowData->hps,
  1577.                                     LABEL_END_BEGIN_PATH );
  1578.  
  1579.                   pMyWindowData->td = TRUE;
  1580.                   WinSetCapture ( HWND_DESKTOP, hWnd );
  1581.                   pMyWindowData->points.x = SHORT1FROMMP ( mp1 );
  1582.                   pMyWindowData->points.y = SHORT2FROMMP ( mp1 );
  1583.                   GpiMove ( pMyWindowData->hps, &pMyWindowData->points );
  1584.                   return ( (MRESULT) ( TDN_IMMEDIATE        |
  1585.                                        TDN_HIFREQ_MOUSEMOVE |
  1586.                                        TDN_NO_INK_STROKE ));
  1587.                   }
  1588.                else
  1589.                   {
  1590.                   return((MRESULT) ( TDN_DEFAULT_DELAY | TDN_INK_STROKE ));
  1591.                   };
  1592.                break;
  1593.  
  1594.       /***********************************************************************
  1595.       * In this case we are using the hifrequency mouse moves to do the      *
  1596.       * inking. We could have just as easily used sensor moves if we desired *
  1597.       * a higher resolution.                                                 *
  1598.       ***********************************************************************/
  1599.       case  WM_MOUSEMOVE:
  1600.                if ( pMyWindowData->td )
  1601.                   {
  1602.  
  1603.                   /**********************************************************
  1604.                   * Make sure that the sign is preserved by casting it to a *
  1605.                   * short                                                   *
  1606.                   **********************************************************/
  1607.                   pMyWindowData->points.x = (SHORT) SHORT1FROMMP ( mp1 );
  1608.                   pMyWindowData->points.y = (SHORT) SHORT2FROMMP ( mp1 );
  1609.  
  1610.                   GpiLine ( pMyWindowData->hps, &pMyWindowData->points );
  1611.                   };
  1612.                break;
  1613.  
  1614.       /***********************************************************************
  1615.       * When the user lifts the pointing device off of the sensor, we will   *
  1616.       * finish the stroke and set the labels for later editing.              *
  1617.       ***********************************************************************/
  1618.       case  WM_LIFTOFF:
  1619.                if ( pMyWindowData->td )
  1620.                   {
  1621.                   WinSetCapture ( HWND_DESKTOP, NULLHANDLE );
  1622.                   pMyWindowData->td = FALSE;
  1623.                   pMyWindowData->points.x = SHORT1FROMMP ( mp1 );
  1624.                   pMyWindowData->points.y = SHORT2FROMMP ( mp1 );
  1625.                   GpiLine ( pMyWindowData->hps, &pMyWindowData->points );
  1626.                   GpiLabel ( pMyWindowData->hps, LABEL_BEGIN_END_PATH );
  1627.                   GpiLabel ( pMyWindowData->hps, LABEL_END_END_PATH );
  1628.                   GpiLabel ( pMyWindowData->hps, LABEL_END_STROKE );
  1629.                   return ( (MRESULT) LO_STROKE_PROCESSED );
  1630.                   }
  1631.                else
  1632.                   {
  1633.                   return ( (MRESULT) LO_DEFAULT );
  1634.                   };
  1635.                break;
  1636.  
  1637.       /***********************************************************************
  1638.       * Close the segment when the pointer device leaves proximity.          *
  1639.       ***********************************************************************/
  1640.       case  WM_EXIT_PROXIMITY:
  1641.                pMyWindowData->NewSegment  = TRUE;
  1642.                pMyWindowData->ElementName = 0;
  1643.                GpiLabel        ( pMyWindowData->hps, LABEL_END_SEGMENT );
  1644.                GpiCloseSegment ( pMyWindowData->hps );
  1645.                break;
  1646.  
  1647.       /***********************************************************************
  1648.       * When in a gesture mode, the reco engine will inform us of any reco   *
  1649.       * event. mp1 contains the hotspot of the gesture. mp2 has a pointer to *
  1650.       * the reco event data.                                                 *
  1651.       ***********************************************************************/
  1652.       case  WM_RECO:
  1653.                pMyWindowData->HotSpot.x = (SHORT) SHORT1FROMMP ( mp1 );
  1654.                pMyWindowData->HotSpot.y = (SHORT) SHORT2FROMMP ( mp1 );
  1655.                pMyWindowData->RecoData  = *((PRECODATA) PVOIDFROMMP ( mp2 ));
  1656.                switch ( pMyWindowData->RecoData.virtual_id )
  1657.                   {
  1658.  
  1659.                   /***********************************************************
  1660.                   * By default a ? gesture is mapped to the virtual id for   *
  1661.                   * help. Pop up a dialog box with the help information.     *
  1662.                   ***********************************************************/
  1663.                   case  VE_HELP:
  1664.                         WinPostMsg ( hWnd, WM_PROCESSDIALOG, (MPARAM)0, (MPARAM)0 );
  1665.                         return( (MRESULT) RECO_PROCESSED );
  1666.                         break;
  1667.  
  1668.                   /***********************************************************
  1669.                   * This event is mapped to the scratchout gesture. We will  *
  1670.                   * use this to delete all segments contained within the     *
  1671.                   * bounding box for the gesture.                            *
  1672.                   ***********************************************************/
  1673.                   case  VE_SCRATCHOUT:
  1674.                         PickSize.cx = pMyWindowData->RecoData.bound_box.xRight - pMyWindowData->RecoData.bound_box.xLeft;
  1675.                         PickSize.cy = pMyWindowData->RecoData.bound_box.yTop - pMyWindowData->RecoData.bound_box.yBottom;
  1676.                         GpiSetPickApertureSize ( pMyWindowData->hps, PICKAP_REC, &PickSize );
  1677.                         NumHits = GpiCorrelateChain ( pMyWindowData->hps,
  1678.                                                       PICKSEL_VISIBLE,
  1679.                                                       &pMyWindowData->HotSpot,
  1680.                                                       10L,
  1681.                                                       1L,
  1682.                                                       &pMyWindowData->SegmentHits[0].Segment );
  1683.                         if ( NumHits )
  1684.                         {
  1685.                            hrgn = CreateClipRect   ( pMyWindowData, NumHits );
  1686.                            for ( i=0; i<NumHits; i++ )
  1687.                            {
  1688.                               GpiDeleteSegment ( pMyWindowData->hps,
  1689.                                                  pMyWindowData->SegmentHits[i].Segment );
  1690.                            };
  1691.                            GpiSetClipRegion ( pMyWindowData->hps, hrgn, &hrgnold );
  1692.                            GpiDrawChain     ( pMyWindowData->hps );
  1693.                            GpiSetClipRegion ( pMyWindowData->hps, hrgnold, NULL );
  1694.                            GpiDestroyRegion ( pMyWindowData->hps, hrgn );
  1695.                            WinValidateRect  ( hWnd, (PRECTL) NULL, TRUE );
  1696.                         }
  1697.                         else
  1698.                         {
  1699.                            DosBeep ( 200, 200 );
  1700.                         };
  1701.                         return( (MRESULT) RECO_PROCESSED );
  1702.                         break;
  1703.  
  1704.                   /***********************************************************
  1705.                   * This event is mapped to the X-out gesture. We will use   *
  1706.                   * this to delete the entire segment under the hotspot.     *
  1707.                   ***********************************************************/
  1708.                   case  VE_DELETE:
  1709.                         NumHits = GpiCorrelateChain ( pMyWindowData->hps,
  1710.                                                       PICKSEL_VISIBLE,
  1711.                                                       &pMyWindowData->HotSpot,
  1712.                                                       1L,
  1713.                                                       1L,
  1714.                                                       &pMyWindowData->SegmentHits[0].Segment );
  1715.                         if ( NumHits )
  1716.                         {
  1717.                            hrgn = CreateClipRect   ( pMyWindowData, NumHits );
  1718.                            GpiDeleteSegment ( pMyWindowData->hps,
  1719.                                               pMyWindowData->SegmentHits[0].Segment );
  1720.                            GpiSetClipRegion ( pMyWindowData->hps, hrgn, &hrgnold );
  1721.                            GpiDrawChain     ( pMyWindowData->hps );
  1722.                            GpiSetClipRegion ( pMyWindowData->hps, hrgnold, NULL );
  1723.                            GpiDestroyRegion ( pMyWindowData->hps, hrgn );
  1724.                            WinValidateRect  ( hWnd, (PRECTL) NULL, TRUE );
  1725.                         }
  1726.                         else
  1727.                         {
  1728.                            DosBeep ( 200, 200 );
  1729.                         };
  1730.                         return( (MRESULT) RECO_PROCESSED );
  1731.                         break;
  1732.  
  1733.                   /***********************************************************
  1734.                   * By default the system maps a pigtail gesture to the      *
  1735.                   * virtual event for deleting a character. We will use this *
  1736.                   * to delete the stroke under the hot spot from the segment *
  1737.                   * under the hotspot.                                       *
  1738.                   ***********************************************************/
  1739.                   case  VE_DELETECHAR:
  1740.                         NumHits = GpiCorrelateChain ( pMyWindowData->hps,
  1741.                                                       PICKSEL_VISIBLE,
  1742.                                                       &pMyWindowData->HotSpot,
  1743.                                                       1L,
  1744.                                                       1L,
  1745.                                                       &pMyWindowData->SegmentHits[0].Segment );
  1746.                         if ( NumHits )
  1747.                            {
  1748.                            hrgn = CreateClipRect ( pMyWindowData, NumHits );
  1749.                            GpiSetDrawingMode     ( pMyWindowData->hps, DM_RETAIN );
  1750.                            GpiSetEditMode        ( pMyWindowData->hps, SEGEM_INSERT );
  1751.                            GpiOpenSegment        ( pMyWindowData->hps, pMyWindowData->SegmentHits[0].Segment );
  1752.                            GpiSetElementPointerAtLabel    ( pMyWindowData->hps,
  1753.                                                             pMyWindowData->SegmentHits[0].Element );
  1754.                            GpiDeleteElementsBetweenLabels ( pMyWindowData->hps,
  1755.                                                             LABEL_BEGIN_STROKE,
  1756.                                                             LABEL_END_STROKE );
  1757.                            GpiCloseSegment   ( pMyWindowData->hps );
  1758.                            GpiSetDrawingMode ( pMyWindowData->hps,
  1759.                                                DM_DRAWANDRETAIN );
  1760.                            GpiSetClipRegion  ( pMyWindowData->hps, hrgn, &hrgnold );
  1761.                            GpiDrawChain      ( pMyWindowData->hps );
  1762.                            GpiSetClipRegion  ( pMyWindowData->hps, hrgnold, NULL );
  1763.                            GpiDestroyRegion  ( pMyWindowData->hps, hrgn );
  1764.                            WinValidateRect   ( hWnd, (PRECTL) NULL, TRUE );
  1765.                            }
  1766.                         else
  1767.                            {
  1768.                            DosBeep ( 200, 200 );
  1769.                            };
  1770.                         return( (MRESULT) RECO_PROCESSED );
  1771.                         break;
  1772.  
  1773.                   /***********************************************************
  1774.                   * User has entered a letter gesture                        *
  1775.                   ***********************************************************/
  1776.                   case  VE_LETTERGESTURE:
  1777.                         switch ( pMyWindowData->RecoData.char_code )
  1778.                            {
  1779.                            /**************************************************
  1780.                            * Change the color to the currently selected      *
  1781.                            * color.                                          *
  1782.                            **************************************************/
  1783.                            case  'C':
  1784.                                  NumHits = GpiCorrelateChain ( pMyWindowData->hps,
  1785.                                                                PICKSEL_VISIBLE,
  1786.                                                                &pMyWindowData->HotSpot,
  1787.                                                                1L,
  1788.                                                                1L,
  1789.                                                                &pMyWindowData->SegmentHits[0].Segment );
  1790.                                  if ( NumHits )
  1791.                                     {
  1792.                                     ChangeColor ( pMyWindowData, pMyWindowData->CurrentColor );
  1793.                                     }
  1794.                                  else
  1795.                                     {
  1796.                                     DosBeep ( 200, 200 );
  1797.                                     };
  1798.                                  return( (MRESULT) RECO_PROCESSED );
  1799.                                  break;
  1800.  
  1801.                            /**************************************************
  1802.                            * Decrease the ink width                          *
  1803.                            **************************************************/
  1804.                            case  'D':
  1805.                                  NumHits = GpiCorrelateChain ( pMyWindowData->hps,
  1806.                                                                PICKSEL_VISIBLE,
  1807.                                                                &pMyWindowData->HotSpot,
  1808.                                                                1L,
  1809.                                                                1L,
  1810.                                                                &pMyWindowData->SegmentHits[0].Segment );
  1811.                                  if ( NumHits )
  1812.                                     {
  1813.                                     hrgn = CreateClipRect ( pMyWindowData, NumHits );
  1814.                                     GpiSetDrawingMode     ( pMyWindowData->hps, DM_RETAIN );
  1815.                                     GpiSetEditMode        ( pMyWindowData->hps, SEGEM_INSERT );
  1816.                                     GpiOpenSegment        ( pMyWindowData->hps, pMyWindowData->SegmentHits[0].Segment );
  1817.                                     GpiSetElementPointerAtLabel ( pMyWindowData->hps,
  1818.                                                                   LABEL_BEGIN_WIDTH );
  1819.                                     GpiOffsetElementPointer ( pMyWindowData->hps, 1L );
  1820.                                     GpiQueryElement         ( pMyWindowData->hps, 0L, sizeof(LWO), (PBYTE) &LineWidthOrder );
  1821.                                     if ( LineWidthOrder.width > 1 )
  1822.                                        {
  1823.                                        GpiSetElementPointer ( pMyWindowData->hps, 1L );
  1824.                                        GpiDeleteElementsBetweenLabels ( pMyWindowData->hps,
  1825.                                                                      LABEL_BEGIN_WIDTH,
  1826.                                                                      LABEL_END_WIDTH );
  1827.                                        GpiSetLineWidthGeom ( pMyWindowData->hps, LineWidthOrder.width/2 );
  1828.                                        };
  1829.                                     GpiCloseSegment   ( pMyWindowData->hps );
  1830.                                     GpiSetDrawingMode ( pMyWindowData->hps,
  1831.                                                         DM_DRAWANDRETAIN );
  1832.                                     GpiSetClipRegion  ( pMyWindowData->hps, hrgn, &hrgnold );
  1833.                                     GpiDrawChain      ( pMyWindowData->hps );
  1834.                                     GpiSetClipRegion  ( pMyWindowData->hps, hrgnold, NULL );
  1835.                                     GpiDestroyRegion  ( pMyWindowData->hps, hrgn );
  1836.                                     }
  1837.                                  else
  1838.                                     {
  1839.                                     DosBeep ( 200, 200 );
  1840.                                     };
  1841.                                  return( (MRESULT) RECO_PROCESSED );
  1842.                                  break;
  1843.  
  1844.                            /**************************************************
  1845.                            * Erase the presentation space, except for the    *
  1846.                            * background palegray box.                        *
  1847.                            **************************************************/
  1848.                            case  'E':
  1849.                                  GpiDeleteSegments ( pMyWindowData->hps, 2, pMyWindowData->SegmentName );
  1850.                                  pMyWindowData->SegmentName=1;
  1851.                                  GpiDrawChain ( pMyWindowData->hps );
  1852.                                  return( (MRESULT) RECO_PROCESSED );
  1853.                                  break;
  1854.  
  1855.                            /**************************************************
  1856.                            * Return to freehand drawing mode                 *
  1857.                            **************************************************/
  1858.                            case  'F':
  1859.                                  pMyWindowData->freehand = TRUE;
  1860.                                  StatusLine ( pMyWindowData, "Freehand Mode" );
  1861.                                  return( (MRESULT) RECO_PROCESSED );
  1862.                                  break;
  1863.  
  1864.                            /**************************************************
  1865.                            * Increase the ink width                          *
  1866.                            **************************************************/
  1867.                            case  'I':
  1868.                                  NumHits = GpiCorrelateChain ( pMyWindowData->hps,
  1869.                                                                PICKSEL_VISIBLE,
  1870.                                                                &pMyWindowData->HotSpot,
  1871.                                                                1L,
  1872.                                                                1L,
  1873.                                                                &pMyWindowData->SegmentHits[0].Segment );
  1874.                                  if ( NumHits )
  1875.                                     {
  1876.                                     GpiSetDrawingMode     ( pMyWindowData->hps, DM_RETAIN );
  1877.                                     GpiSetEditMode        ( pMyWindowData->hps, SEGEM_INSERT );
  1878.                                     GpiOpenSegment        ( pMyWindowData->hps, pMyWindowData->SegmentHits[0].Segment );
  1879.                                     GpiSetElementPointerAtLabel ( pMyWindowData->hps,
  1880.                                                                   LABEL_BEGIN_WIDTH );
  1881.                                     GpiOffsetElementPointer ( pMyWindowData->hps, 1L );
  1882.                                     GpiQueryElement     ( pMyWindowData->hps, 0L, sizeof(LWO), (PBYTE) &LineWidthOrder );
  1883.                                     GpiSetElementPointer ( pMyWindowData->hps, 1L );
  1884.                                     GpiDeleteElementsBetweenLabels ( pMyWindowData->hps,
  1885.                                                                      LABEL_BEGIN_WIDTH,
  1886.                                                                      LABEL_END_WIDTH );
  1887.                                     GpiSetLineWidthGeom ( pMyWindowData->hps, LineWidthOrder.width*2 );
  1888.                                     if ( LineWidthOrder.width == 1 )
  1889.                                        {
  1890.                                        while ( GpiSetElementPointerAtLabel ( pMyWindowData->hps,
  1891.                                                                              LABEL_BEGIN_BEGIN_PATH ) )
  1892.                                           {
  1893.                                           GpiBeginPath ( pMyWindowData->hps, 1L );
  1894.                                           GpiSetElementPointerAtLabel ( pMyWindowData->hps,
  1895.                                                                      LABEL_BEGIN_END_PATH );
  1896.                                           GpiEndPath ( pMyWindowData->hps );
  1897.                                           GpiStrokePath ( pMyWindowData->hps, 1L, 0L );
  1898.                                           };
  1899.                                        };
  1900.                                     GpiCloseSegment   ( pMyWindowData->hps );
  1901.                                     hrgn = CreateClipRect ( pMyWindowData, NumHits );
  1902.                                     GpiSetDrawingMode ( pMyWindowData->hps,
  1903.                                                         DM_DRAWANDRETAIN );
  1904.                                     GpiSetClipRegion  ( pMyWindowData->hps, hrgn, &hrgnold );
  1905.                                     GpiDrawChain      ( pMyWindowData->hps );
  1906.                                     GpiSetClipRegion  ( pMyWindowData->hps, hrgnold, NULL );
  1907.                                     GpiDestroyRegion  ( pMyWindowData->hps, hrgn );
  1908.                                     }
  1909.                                  else
  1910.                                     {
  1911.                                     DosBeep ( 200, 200 );
  1912.                                     };
  1913.                                  return( (MRESULT) RECO_PROCESSED );
  1914.                                  break;
  1915.  
  1916.                            default:
  1917.                                  break;
  1918.                            };
  1919.                         break;
  1920.  
  1921.                   default:
  1922.                         break;
  1923.                   }
  1924.                   return ( (MRESULT) RECO_MAP );
  1925.                break;
  1926.  
  1927.       /***********************************************************************
  1928.       * Make sure we resize the ink control when the window is resized       *
  1929.       ***********************************************************************/
  1930.       case  WM_SIZE:
  1931.                WinQueryWindowRect ( hWnd, &rcl );
  1932.                if ( pMyWindowData != NULL )
  1933.                   {
  1934.                   WinSetWindowPos ( pMyWindowData->InkColors,
  1935.                                     HWND_TOP,
  1936.                                     0,
  1937.                                     0,
  1938.                                     25,
  1939.                                     rcl.yTop,
  1940.                                     SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW );
  1941.                   };
  1942.                break;
  1943.  
  1944.       /***********************************************************************
  1945.       * Repaint the window                                                   *
  1946.       ***********************************************************************/
  1947.       case  WM_PAINT:
  1948.                hpspaint = WinBeginPaint  ( hWnd, pMyWindowData->hps, &rcl );
  1949.                GpiDrawChain         ( hpspaint );
  1950.                WinUpdateWindow      ( pMyWindowData->InkColors );
  1951.                WinEndPaint          ( hpspaint );
  1952.                return ( (MRESULT) TRUE );
  1953.                break;
  1954.  
  1955.       /***********************************************************************
  1956.       * Clean up before we close the window                                  *
  1957.       ***********************************************************************/
  1958.       case  WM_CLOSE:
  1959.                GpiDestroyPS      ( pMyWindowData->hps );
  1960.                StatusLine        ( pMyWindowData, "" );
  1961.                WinDestroyWindow  ( WinQueryWindow ( hWnd, QW_PARENT ) );
  1962.                DosFreeMem        ( (PVOID) pMyWindowData );
  1963.                return ( (MRESULT) 0 );
  1964.                break;
  1965.  
  1966.       default:
  1967.                break;
  1968.       };
  1969.    return( (MRESULT) WinDefWindowProc ( hWnd, ulMsg, mp1, mp2 )  );
  1970. }
  1971.  
  1972. /*****************************************************************************
  1973. * Change the color of the selected segment.                                  *
  1974. *                                                                            *
  1975. * 1   Set the drawing mode to retain                                         *
  1976. * 2   Get the clipping region for the segment                                *
  1977. * 3   Set the edit mode to replace                                           *
  1978. * 4   Open the segment for editing                                           *
  1979. * 5   Position element pointer at the label for setting color                *
  1980. * 6   Increment the element pointer to the actual element that sets color    *
  1981. * 7   Replace element with new color                                         *
  1982. * 8   Close the segment                                                      *
  1983. * 9   Reset the drawing mode to draw and retain                              *
  1984. * 10  Set the clipping region and save old clipping region                   *
  1985. * 11  Draw the entire chain since other segments may cross the clipping      *
  1986. *     region                                                                 *
  1987. * 12  Reset the clipping region                                              *
  1988. * 13  Destroy the clipping regaion                                           *
  1989. * 14  Validate the window since the screen is now valid                      *
  1990. *                                                                            *
  1991. *****************************************************************************/
  1992. BOOL ChangeColor ( PMYWINDOWDATA pMyWindowData, LONG NewColor )
  1993.    {
  1994.    HRGN hrgn;
  1995.    HRGN hrgnold;
  1996.  
  1997.    GpiSetDrawingMode     ( pMyWindowData->hps, DM_RETAIN );
  1998.    hrgn = CreateClipRect ( pMyWindowData, 1 );
  1999.    GpiSetEditMode    ( pMyWindowData->hps, SEGEM_REPLACE );
  2000.    GpiOpenSegment    ( pMyWindowData->hps, pMyWindowData->SegmentHits[0].Segment );
  2001.    GpiSetElementPointerAtLabel ( pMyWindowData->hps, LABEL_BEGIN_COLOR );
  2002.    GpiOffsetElementPointer   ( pMyWindowData->hps, 1L );
  2003.    GpiSetColor       ( pMyWindowData->hps, NewColor );
  2004.    GpiCloseSegment   ( pMyWindowData->hps );
  2005.    GpiSetDrawingMode ( pMyWindowData->hps, DM_DRAWANDRETAIN );
  2006.    GpiSetClipRegion  ( pMyWindowData->hps, hrgn, &hrgnold );
  2007.    GpiDrawChain      ( pMyWindowData->hps );
  2008.    GpiSetClipRegion  ( pMyWindowData->hps, hrgnold, NULL );
  2009.    GpiDestroyRegion  ( pMyWindowData->hps, hrgn );
  2010.    WinValidateRect   ( pMyWindowData->MyWindow, (PRECTL) NULL, TRUE );
  2011.    return ( TRUE );
  2012.    }
  2013.  
  2014. /*****************************************************************************
  2015. * Calculate the clipping region for updating the window.                     *
  2016. *                                                                            *
  2017. * 1   Turn on the colletion of boundary data                                 *
  2018. * 2   Turn off the displaying of the updates while we collect the boundary   *
  2019. *     data                                                                   *
  2020. * 3   Draw each of the selected segments, with display off, to get the       *
  2021. *     boundary data for the segment                                          *
  2022. * 4   Add the boundary for this segment to the boundary data for all of the  *
  2023. *     segments being updated                                                 *
  2024. * 5   Increment the size of the bounding rectangle since the clipping region *
  2025. *     is an inclusive/exclusive rectangle                                    *
  2026. * 6   create and return the calculated clipping region                       *
  2027. *                                                                            *
  2028. *****************************************************************************/
  2029. HRGN CreateClipRect ( PMYWINDOWDATA  pMyWindowData, SHORT NumSegments )
  2030. {
  2031.    SHORT i;
  2032.    RECTL TmpBoundary1;
  2033.    RECTL TmpBoundary2;
  2034.  
  2035.    TmpBoundary2.xLeft   = 0;
  2036.    TmpBoundary2.xRight  = 0;
  2037.    TmpBoundary2.yTop    = 0;
  2038.    TmpBoundary2.yBottom = 0;
  2039.  
  2040.    GpiSetDrawControl    ( pMyWindowData->hps, DCTL_BOUNDARY, DCTL_ON );
  2041.    GpiSetDrawControl    ( pMyWindowData->hps, DCTL_DISPLAY, DCTL_OFF );
  2042.    for ( i=0; i<NumSegments; i++)
  2043.       {
  2044.       GpiDrawSegment       ( pMyWindowData->hps, pMyWindowData->SegmentHits[i].Segment );
  2045.       GpiQueryBoundaryData ( pMyWindowData->hps, &TmpBoundary1 );
  2046.       WinUnionRect         ( pMyWindowData->hab, &pMyWindowData->Boundary, &TmpBoundary1, &TmpBoundary2 );
  2047.       TmpBoundary2 = pMyWindowData->Boundary;
  2048.       };
  2049.    pMyWindowData->Boundary.xRight++;
  2050.    pMyWindowData->Boundary.yTop++;
  2051.    GpiSetDrawControl    ( pMyWindowData->hps, DCTL_DISPLAY, DCTL_ON );
  2052.    GpiSetDrawControl    ( pMyWindowData->hps, DCTL_BOUNDARY, DCTL_OFF );
  2053.    GpiConvert           ( pMyWindowData->hps, CVTC_MODEL, CVTC_DEVICE, 2L, (PPOINTL) &pMyWindowData->Boundary );
  2054.    pMyWindowData->Boundary.xRight++;
  2055.    pMyWindowData->Boundary.yTop++;
  2056.    return ( GpiCreateRegion ( pMyWindowData->hps, 1L, &pMyWindowData->Boundary ) );
  2057. }
  2058.  
  2059. /*****************************************************************************
  2060. * Create the ink color value set control on left side of the window          *
  2061. *****************************************************************************/
  2062. HWND CreateInkControls ( HWND hWnd )
  2063. {
  2064.    int      i;
  2065.    HWND     hValueSet;
  2066.    ULONG    ulValueSetStyles;
  2067.    VSCDATA  vscdata;
  2068.    RECTL    rcl;
  2069.  
  2070.    WinQueryWindowRect ( hWnd, &rcl );
  2071.  
  2072.    vscdata.cbSize        = sizeof (VSCDATA);
  2073.    vscdata.usRowCount    = 16;
  2074.    vscdata.usColumnCount = 1;
  2075.  
  2076.    ulValueSetStyles = VS_COLORINDEX |
  2077.                       VS_ITEMBORDER |
  2078.                       VS_BORDER;
  2079.  
  2080.    hValueSet = WinCreateWindow ( hWnd,
  2081.                                  WC_VALUESET,
  2082.                                  "",
  2083.                                  ulValueSetStyles,
  2084.                                  0, 0,
  2085.                                  25, rcl.yTop,
  2086.                                  hWnd,
  2087.                                  HWND_TOP,
  2088.                                  ID_VALUE_SET_INK,
  2089.                                  &vscdata,
  2090.                                  NULL );
  2091.    for (i=0; i<16; i++)
  2092.    {
  2093.       WinSendMsg ( hValueSet,
  2094.                    VM_SETITEM,
  2095.                    MPFROM2SHORT ( i+1, 1 ),
  2096.                    MPFROMLONG   ( InkColor[i] ) );
  2097.    };
  2098.  
  2099.    WinSendMsg ( hValueSet,
  2100.                 VM_SELECTITEM,
  2101.                 MPFROM2SHORT ( 1, 1 ),
  2102.                 NULL );
  2103.  
  2104.    WinShowWindow ( hValueSet, TRUE );
  2105.    return ( hValueSet );
  2106. }
  2107.  
  2108. /*****************************************************************************
  2109. * Dialog procedure for displaying help                                       *
  2110. *****************************************************************************/
  2111. MRESULT APIENTRY InkEditHelp (  HWND     hWnd,
  2112.                                 ULONG    ulMsg,
  2113.                                 MPARAM   mp1,
  2114.                                 MPARAM   mp2   )
  2115. {
  2116.    switch ( ulMsg )
  2117.       {
  2118.       case WM_COMMAND:
  2119.            switch ( SHORT1FROMMP(mp1) )
  2120.                {
  2121.                case  DID_CANCEL:
  2122.                      WinDismissDlg ( hWnd, FALSE );
  2123.                      return( (MRESULT) TRUE);
  2124.                      break;
  2125.  
  2126.                default:
  2127.                      break;
  2128.                };
  2129.            return((MRESULT) TRUE);
  2130.            break;
  2131.  
  2132.       default:
  2133.                break;
  2134.       };
  2135.    return( (MRESULT) WinDefDlgProc ( hWnd, ulMsg, mp1, mp2 ) );
  2136. }
  2137.  
  2138.