home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / viscobv6.zip / vac22os2 / ibmcobol / samples / toolkit / wps / wpstutor / showdesc.c < prev    next >
C/C++ Source or Header  |  1996-11-19  |  40KB  |  889 lines

  1. /*************************************************************************
  2. *
  3. *  File Name  : SHOWDESC.C
  4. *
  5. *  Description: Show Method Description Sample Program
  6. *
  7. *               This program displays the names and descriptions for Workplace
  8. *               Shell methods in a multiline entry field window.  This sample
  9. *               program is invoked by the WPSTUTOR.DLL Workplace Shell class.
  10. *               For every method that is invoked in that class, information is
  11. *               sent to this program (via a named pipe) that indicates the
  12. *               method name and description to be displayed.
  13. *
  14. *
  15. *  Copyright (C) 1993 IBM Corporation
  16. *
  17. *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  18. *      sample code created by IBM Corporation. This sample code is not
  19. *      part of any standard or IBM product and is provided to you solely
  20. *      for  the purpose of assisting you in the development of your
  21. *      applications.  The code is provided "AS IS", without
  22. *      warranty of any kind.  IBM shall not be liable for any damages
  23. *      arising out of your use of the sample code, even if they have been
  24. *      advised of the possibility of such damages.                                                    *
  25. *
  26. ************************************************************************/
  27.  
  28. /*-----------------------------------------------------------------------------
  29. *    INCLUDE FILES
  30. *----------------------------------------------------------------------------*/
  31. #define INCL_DOS
  32. #define INCL_ERRORS
  33. #define INCL_WINCURSORS
  34. #define INCL_WINFRAMEMGR
  35. #define INCL_WINHELP
  36. #define INCL_WINMLE
  37. #define INCL_WINSTDFILE
  38. #define INCL_WINSWITCHLIST
  39. #define INCL_WINSYS
  40. #define INCL_WINWINDOWMGR
  41. #define INCL_WINMENUS
  42.  
  43. #include <os2.h>
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <stdlib.h>
  47. #include "showdesc.h"
  48.  
  49. /*-----------------------------------------------------------------------------
  50. *    DEFINES
  51. *----------------------------------------------------------------------------*/
  52. #define RETURN_SUCCESS      0            /* Indicates successful program     */
  53.                                          /*   execution                      */
  54. #define RETURN_ERROR        1            /* Indicates unsuccessful program   */
  55.                                          /*   execution                      */
  56.  
  57. /*-----------------------------------------------------------------------------
  58. *    GLOBAL DATA
  59. *----------------------------------------------------------------------------*/
  60. HWND hwndMainFrame;                 /* Main frame window handle              */
  61. HWND hwndMain;                      /* Main client window handle             */
  62. HWND hwndMLE;                       /* Multiline entry-field window handle   */
  63.  
  64. HAB hab;                            /* Anchor block for the process          */
  65. HMQ hmq;                            /* Handle to the process' message queue  */
  66.  
  67. CHAR szAppName[MAXNAMEL];           /* Application name buffer               */
  68.  
  69. LONG lClrDefaultForeground = CLR_BLACK;
  70.                                     /* Foreground color for MLE window text  */
  71. LONG lClrDefaultBackground = CLR_WHITE;
  72.                                     /* Background color for MLE window text  */
  73.  
  74. IPT iptOffset = 0;                  /* MLE insert position that represents   */
  75.                                     /*    the point at which the method name */
  76.                                     /*    and description text is to be      */
  77.                                     /*    inserted into the MLE              */
  78.  
  79.  
  80. /******************************************************************************
  81. *
  82. *  Name:        main
  83. *
  84. *  Description: Entry point of program.
  85. *
  86. *               This function initializes the required PM resources in order
  87. *               to run the 'Show Method Description' program.
  88. *
  89. *  Parameters:  NONE
  90. *
  91. *  Returns:     RETURN_SUCCESS - Program execution completed successfully
  92. *               RETURN_ERROR   - Error occurred during execution
  93. *
  94. ******************************************************************************/
  95. int main (VOID)
  96. {
  97.    QMSG      qmsg;             /* Message structure used to get/dispatch     */
  98.                                /*   messages                                 */
  99.    ULONG     ulCtlData;        /* Frame window creation flags                */
  100.    SWCNTRL   SwitchControls;   /* Switch data for a new Window List entry    */
  101.    PID       pid;              /* Process ID of the thread that created the  */
  102.                                /*   frame window                             */
  103.    TID       tid;              /* Thread ID of the thread that created the   */
  104.                                /*   frame window                             */
  105.  
  106.    /*--------------------------------------------------------------------------
  107.    *    Obtain an anchor block for the PM program.  The program ends
  108.    *    unsuccessfully if an anchor block cannot be obtained.
  109.    *-------------------------------------------------------------------------*/
  110.    hab = WinInitialize(0);
  111.    if(!hab)
  112.    {
  113.       WinAlarm(HWND_DESKTOP, WA_ERROR);
  114.       return(RETURN_ERROR);
  115.    }
  116.  
  117.    /*--------------------------------------------------------------------------
  118.    *    Obtain a message queue for the PM program.  The program ends
  119.    *    unsuccessfully if a message queue cannot be obtained.
  120.    *-------------------------------------------------------------------------*/
  121.    hmq = WinCreateMsgQueue(hab, 0);
  122.    if(!hmq)
  123.    {
  124.       WinAlarm(HWND_DESKTOP, WA_ERROR);
  125.       WinTerminate(hab);
  126.       return(RETURN_ERROR);
  127.    }
  128.  
  129.    /*--------------------------------------------------------------------------
  130.    *    Set up the exit list processing for the program, get the application's
  131.    *    name, and register the window class with PM.  The program ends
  132.    *    unsuccessfully if this initialization fails.
  133.    *-------------------------------------------------------------------------*/
  134.    if ( !Init() )
  135.    {
  136.       MessageBox(HWND_DESKTOP, IDMSG_INITFAILED, MB_OK | MB_ERROR, TRUE);
  137.       return(RETURN_ERROR);
  138.    }
  139.  
  140.    /*--------------------------------------------------------------------------
  141.    *    NOTE:  Program clean up is handled by the DosExitList processing from
  142.    *    this point forward.
  143.    *-------------------------------------------------------------------------*/
  144.  
  145.    /*--------------------------------------------------------------------------
  146.    *    Create the frame and client windows.
  147.    *-------------------------------------------------------------------------*/
  148.    ulCtlData = FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX | FCF_SIZEBORDER |
  149.                FCF_ICON | FCF_SHELLPOSITION | FCF_MENU | FCF_ACCELTABLE;
  150.  
  151.    hwndMainFrame = WinCreateStdWindow(
  152.       HWND_DESKTOP,                           /* Parent-window handle        */
  153.       0,                                      /* Frame-window style          */
  154.       (PVOID)&ulCtlData,                      /* Frame-creation flags        */
  155.       (PSZ)szAppName,                         /* Client-window class name    */
  156.       (PSZ)szAppName,                         /* Title-bar text              */
  157.       0,                                      /* Client-window style         */
  158.       (HMODULE)NULL,                          /* Resource identifier         */
  159.       IDR_MAIN,                               /* Frame-window identifier     */
  160.       (PHWND)&hwndMain);                      /* Client-window handle        */
  161.  
  162.    /*--------------------------------------------------------------------------
  163.    *    We'll position the window based on the location stored from previous
  164.    *    program executions.  NOTE: If there is no stored location, the window
  165.    *    position will be determined by the shell due to the FCF_SHELLPOSITION
  166.    *    frame creation flag.
  167.    *-------------------------------------------------------------------------*/
  168.    WinRestoreWindowPos(szAppName, szAppName, hwndMainFrame);
  169.  
  170.    /*--------------------------------------------------------------------------
  171.    *    Add the 'Show Method Description' program to the Window List.
  172.    *-------------------------------------------------------------------------*/
  173.    WinQueryWindowProcess(hwndMainFrame, &pid, &tid);
  174.  
  175.    SwitchControls.hwnd = hwndMainFrame;
  176.    SwitchControls.hwndIcon = 0;
  177.    SwitchControls.hprog = NULLHANDLE;
  178.    SwitchControls.idProcess = pid;
  179.    SwitchControls.idSession = NULLHANDLE;
  180.    SwitchControls.uchVisibility = SWL_VISIBLE;
  181.    SwitchControls.fbJump = SWL_JUMPABLE;
  182.    strcpy(SwitchControls.szSwtitle, szAppName);
  183.    SwitchControls.bProgType = SSF_TYPE_PM;
  184.  
  185.    WinAddSwitchEntry(&SwitchControls);
  186.  
  187.    /*--------------------------------------------------------------------------
  188.    *    Process the get/dispatch message loop.
  189.    *-------------------------------------------------------------------------*/
  190.    while(WinGetMsg(hab, (PQMSG)&qmsg, 0, 0, 0))
  191.        WinDispatchMsg(hab, (PQMSG)&qmsg);
  192.  
  193.    /*--------------------------------------------------------------------------
  194.    *    The program has completed successfully.
  195.    *-------------------------------------------------------------------------*/
  196.    return(RETURN_SUCCESS);
  197. }
  198.  
  199.  
  200. /******************************************************************************
  201. *
  202. *  Name:        MainWndProc
  203. *
  204. *  Description: Window procedure for the main client window.
  205. *
  206. *               This function processes the messages sent to the 'Show
  207. *               Method Description' client window.
  208. *
  209. *  Parameters:  hwnd - Window handle to which message is addressed
  210. *               msg  - Message type
  211. *               mp1  - First message parameter
  212. *               mp2  - Second message parameter
  213. *
  214. *  Returns:     Return values are based on the message processed.
  215. *
  216. ******************************************************************************/
  217. MRESULT EXPENTRY MainWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  218. {
  219.  
  220.    /*--------------------------------------------------------------------------
  221.    *    Process the message that caused the window procedure to be invoked.
  222.    *-------------------------------------------------------------------------*/
  223.    switch(msg)
  224.    {
  225.       case WM_CREATE:
  226.          /*--------------------------------------------------------------------
  227.          *    Initialize the PM window by creating the MLE window and creating
  228.          *    the thread that communicates with WPSTUTOR.DLL.
  229.          *-------------------------------------------------------------------*/
  230.          return(InitMainWindow(hwnd, mp1, mp2));
  231.          break;
  232.  
  233.       case WM_PAINT:
  234.       {
  235.          RECTL rclUpdate;        /* Rectangle to be painted                  */
  236.          HPS   hps;              /* Presentation space handle                */
  237.  
  238.          /*--------------------------------------------------------------------
  239.          *    Repaint the window to be updated.
  240.          *-------------------------------------------------------------------*/
  241.          hps = WinBeginPaint(hwnd, NULLHANDLE, (PRECTL)&rclUpdate);
  242.          WinFillRect(hps, (PRECTL)&rclUpdate, SYSCLR_WINDOW);
  243.          WinEndPaint(hps);
  244.          break;
  245.       }
  246.  
  247.       case WM_SIZE:
  248.          /*--------------------------------------------------------------------
  249.          *    Re-size the MLE to be the same width and height as the client
  250.          *    window.
  251.          *-------------------------------------------------------------------*/
  252.          WinSetWindowPos(hwndMLE, HWND_TOP, 0, 0, SHORT1FROMMP(mp2),
  253.                          SHORT2FROMMP(mp2), SWP_SIZE);
  254.          break;
  255.  
  256.       case WM_INITMENU:
  257.       {
  258.          /*--------------------------------------------------------------------
  259.          *    Process the menu to be activated as necessary.
  260.          *-------------------------------------------------------------------*/
  261.          switch(SHORT1FROMMP(mp1))
  262.          {
  263.             case IDM_EDIT:
  264.             {
  265.                /*--------------------------------------------------------------
  266.                *    Enable and disable the menu items in the "Edit" menu as
  267.                *    appropriate.
  268.                *-------------------------------------------------------------*/
  269.                BOOL    bEnable;   /* Flag indicating if a menu item should   */
  270.                                   /*   enabled or not                        */
  271.                MRESULT mr1,       /* Result of a WinSendMsg call             */
  272.                        mr2;       /* Result of a WinSendMsg call             */
  273.                IPT     iptText;   /* Length of the text currently in the MLE */
  274.  
  275.  
  276.                /*--------------------------------------------------------------
  277.                *    Determine the minimum and maximum insertion points of
  278.                *    selection.  If there is text selected, enable the 'Copy'
  279.                *    and 'Clear' menu items.  If no text is selected, disable
  280.                *    the items.
  281.                *-------------------------------------------------------------*/
  282.                mr1 = WinSendMsg(hwndMLE, MLM_QUERYSEL,
  283.                                  MPFROMSHORT(MLFQS_MINSEL), NULL);
  284.  
  285.                mr2 = WinSendMsg(hwndMLE, MLM_QUERYSEL,
  286.                                  MPFROMSHORT(MLFQS_MAXSEL), NULL);
  287.  
  288.                if (mr1 != mr2)
  289.                   bEnable = TRUE;
  290.                else
  291.                   bEnable = FALSE;
  292.  
  293.                WinEnableMenuItem(HWNDFROMMP(mp2), IDM_EDITCOPY, bEnable);
  294.                WinEnableMenuItem(HWNDFROMMP(mp2), IDM_EDITCLEAR, bEnable);
  295.  
  296.                iptText = (IPT) WinSendMsg(hwndMLE, MLM_QUERYTEXTLENGTH, NULL,
  297.                                           NULL);
  298.  
  299.                /*--------------------------------------------------------------
  300.                *    Determine if there is any text in the MLE.  If there is,
  301.                *    enable the 'Clear All' menu item.  Otherwise, disable the
  302.                *    item.
  303.                *-------------------------------------------------------------*/
  304.                if ( iptText != 0 )
  305.                   bEnable = TRUE;
  306.                else
  307.                   bEnable = FALSE;
  308.  
  309.                WinEnableMenuItem(HWNDFROMMP(mp2), IDM_EDITCLEARALL, bEnable);
  310.  
  311.                break;
  312.             }
  313.  
  314.             default:
  315.                 break;
  316.          }
  317.          break;
  318.       }
  319.  
  320.       case WM_COMMAND:
  321.       {
  322.          /*--------------------------------------------------------------------
  323.          *    Process the command selected by the user.
  324.          *-------------------------------------------------------------------*/
  325.          switch ( SHORT1FROMMP(mp1) )
  326.          {
  327.             case IDM_EDITCLEAR:
  328.             {
  329.                /*--------------------------------------------------------------
  330.                *    Remove the selected text from the MLE.
  331.                *-------------------------------------------------------------*/
  332.                WinSendMsg(hwndMLE, MLM_CLEAR, NULL, NULL);
  333.                break;
  334.             }
  335.  
  336.             case IDM_EDITCLEARALL:
  337.             {
  338.                /*--------------------------------------------------------------
  339.                *    Remove all text from the MLE.
  340.                *
  341.                *    Disable redrawing of the MLE so the text doesn't "flash"
  342.                *    when the MLE is cleared.
  343.                *-------------------------------------------------------------*/
  344.                WinSendMsg(hwndMLE, MLM_DISABLEREFRESH, NULL, NULL);
  345.  
  346.                /*--------------------------------------------------------------
  347.                *    Clear the MLE by selecting all of the text and clearing it.
  348.                *-------------------------------------------------------------*/
  349.                WinSendMsg(hwndMLE, MLM_SETSEL, MPFROMSHORT(NULL),
  350.                           (MPARAM) WinSendMsg(hwndMLE, MLM_QUERYTEXTLENGTH,
  351.                                               NULL, NULL));
  352.  
  353.                WinSendMsg(hwndMLE, MLM_CLEAR, NULL, NULL);
  354.  
  355.                /*--------------------------------------------------------------
  356.                *    Reset the insertion point used to display the method names
  357.                *    and descriptions in the MLE.
  358.                *-------------------------------------------------------------*/
  359.                iptOffset = 0;
  360.  
  361.                /*--------------------------------------------------------------
  362.                *    Reset the changed flag for the MLE.
  363.                *-------------------------------------------------------------*/
  364.                WinSendMsg(hwndMLE, MLM_SETCHANGED, MPFROMSHORT(FALSE), NULL);
  365.  
  366.                /*--------------------------------------------------------------
  367.                *    Enable redrawing of the MLE.
  368.                *-------------------------------------------------------------*/
  369.                WinSendMsg(hwndMLE, MLM_ENABLEREFRESH, NULL, NULL);
  370.                break;
  371.             }
  372.  
  373.             case IDM_EDITCOPY:
  374.             {
  375.                /*--------------------------------------------------------------
  376.                *    Copy the selected text to the clipboard.
  377.                *-------------------------------------------------------------*/
  378.                WinSendMsg(hwndMLE, MLM_COPY, NULL, NULL);
  379.                break;
  380.             }
  381.  
  382.             default :
  383.             {
  384.                break;
  385.             }
  386.          }
  387.          break;
  388.       }
  389.  
  390.       case IDM_SHOW_METHOD:
  391.       {
  392.          /*--------------------------------------------------------------------
  393.          *    Information was sent from WPSTUTOR.DLL to this program.  This
  394.          *    data represents a method for which the name and description is
  395.          *    to be displayed.
  396.          *-------------------------------------------------------------------*/
  397.          ShowMethodDescription(LONGFROMMP(mp1));
  398.  
  399.          break;
  400.       }
  401.  
  402.       case WM_CLOSE:
  403.       {
  404.          /*--------------------------------------------------------------------
  405.          *    This message is sent to a frame window to indicate that the
  406.          *    window is being closed by the user.
  407.          *
  408.          *    Store the window position for the next time around and close the
  409.          *    window.
  410.          *-------------------------------------------------------------------*/
  411.          WinStoreWindowPos(szAppName, szAppName, hwndMainFrame);
  412.          WinPostMsg(hwnd, WM_QUIT, (MPARAM)0, (MPARAM)0);
  413.          break;
  414.       }
  415.  
  416.       default:
  417.          /*--------------------------------------------------------------------
  418.          *    We're not processing any of the messages that get this far.
  419.          *    We'll tell the system to process these messages by calling
  420.          *    WinDefWindowProc.
  421.          *-------------------------------------------------------------------*/
  422.          return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  423.          break;
  424.  
  425.    }
  426.  
  427.    /*--------------------------------------------------------------------------
  428.    *    All window procedures should return '0' as the default.
  429.    *-------------------------------------------------------------------------*/
  430.    return (MRESULT)0;
  431. }
  432.  
  433. /******************************************************************************
  434. *
  435. *  Name:        MessageBox
  436. *
  437. *  Description: This function displays a warning message box with a specified
  438. *               message that is retrieved from the message table.  This
  439. *               function is called when an error that the user should know
  440. *               about occurs.
  441. *
  442. *
  443. *  Parameters:  hwndOwner - Window handle of the owner of the message box
  444. *               idMsg     - ID of message to be retrieved from resource file
  445. *               fsStyle   - Message box style
  446. *               fBeep     - Flag to sound alarm
  447. *
  448. *  Returns:     SHORT - See WinMessageBox return codes for more information.
  449. *
  450. ******************************************************************************/
  451.  
  452. SHORT MessageBox(HWND hwndOwner, SHORT idMsg, SHORT fsStyle, BOOL fBeep)
  453. {
  454.    CHAR szText[MESSAGELEN];
  455.    CHAR szTitle[MESSAGELEN];
  456.    PSZ  pszTitle = NULL;
  457.  
  458.    /*--------------------------------------------------------------------------
  459.    *    If we can't load the message from the message table, beep for the user.
  460.    *-------------------------------------------------------------------------*/
  461.    if ( !WinLoadMessage(hab, (HMODULE)NULL, idMsg, MESSAGELEN, (PSZ)szText) )
  462.    {
  463.       WinAlarm(HWND_DESKTOP, WA_ERROR);
  464.       return MBID_ERROR;
  465.    }
  466.  
  467.    /*--------------------------------------------------------------------------
  468.    *    If the caller wants a beep, then beep.
  469.    *-------------------------------------------------------------------------*/
  470.    if ( fBeep )
  471.       WinAlarm(HWND_DESKTOP, WA_ERROR);
  472.  
  473.    /*--------------------------------------------------------------------------
  474.    *    Load the title of the message box from the string table.
  475.    *-------------------------------------------------------------------------*/
  476.    if ( (fsStyle & MB_WARNING)
  477.        && WinLoadString(hab, (HMODULE)0, IDS_WARNING, MESSAGELEN, szTitle) )
  478.    {
  479.          pszTitle = szTitle;
  480.    }
  481.    else
  482.       pszTitle = NULL;
  483.  
  484.    /*--------------------------------------------------------------------------
  485.    *    Display the message box for the user.
  486.    *-------------------------------------------------------------------------*/
  487.    return(WinMessageBox(HWND_DESKTOP, hwndOwner, szText, pszTitle,
  488.           IDD_MSGBOX, fsStyle));
  489. }
  490.  
  491. /******************************************************************************
  492. *
  493. *  Name:        Init
  494. *
  495. *  Description: This function performs initialization functions, including
  496. *               setting up exit list processing, obtaining the name of the
  497. *               application to be started, and registering the main client's
  498. *               window class.
  499. *
  500. *  Parameters:  NONE
  501. *
  502. *  Returns:     TRUE  - Initialization is successful
  503. *               FALSE - Error occurred during initialization.
  504. *
  505. ******************************************************************************/
  506.  
  507. BOOL Init( VOID )
  508. {
  509.     /*-------------------------------------------------------------------------
  510.     *    Add 'ExitProc' to the exit list to handle exit processing.  If there
  511.     *    is an error, then terminate the process since there have not been any
  512.     *    resources allocated yet.
  513.     *------------------------------------------------------------------------*/
  514.     if ( DosExitList(EXLST_ADD, (PFNEXITLIST)ExitProc) )
  515.     {
  516.        MessageBox(HWND_DESKTOP,
  517.                   IDMSG_CANNOTLOADEXITLIST,
  518.                   MB_OK | MB_ERROR,
  519.                   TRUE);
  520.  
  521.        return(FALSE);
  522.     }
  523.  
  524.     /*-------------------------------------------------------------------------
  525.     *    Load the application's name from the resource file.
  526.     *------------------------------------------------------------------------*/
  527.     if ( !WinLoadString(hab, (HMODULE)0, IDS_APPNAME, MAXNAMEL, szAppName) )
  528.     {
  529.        return FALSE;
  530.     }
  531.  
  532.     /*-------------------------------------------------------------------------
  533.     *    Register the main client window class
  534.     *------------------------------------------------------------------------*/
  535.     if ( !WinRegisterClass(hab,
  536.                            (PSZ)szAppName,
  537.                            (PFNWP)MainWndProc,
  538.                            CS_SIZEREDRAW | CS_CLIPCHILDREN,
  539.                            0) )
  540.     {
  541.        return FALSE;
  542.     }
  543.  
  544.     return TRUE;
  545. }
  546.  
  547. /******************************************************************************
  548. *
  549. *  Name:        InitMainWindow
  550. *
  551. *  Description: This function performs the initialization required to create
  552. *               the main window.
  553. *
  554. *  Parameters:  hwnd - Client window handle
  555. *               mp1 - First message parameter
  556. *               mp2 - Second message parameter
  557. *
  558. *  Returns:     TRUE  - Window initialization failed.
  559. *               FALSE - Window initialization is successful.
  560. *
  561. ******************************************************************************/
  562.  
  563. MRESULT InitMainWindow( HWND hwnd, MPARAM mp1, MPARAM mp2 )
  564. {
  565.     RECTL     rcl;        /* Window rectangle used to determine the size     */
  566.                           /*   of the new MLE                                */
  567.     TID       ThreadID;   /* Thread ID for the thread that communicates with */
  568.                           /*   WSPTUT.DLL                                    */
  569.  
  570.     /*-------------------------------------------------------------------------
  571.     *    Create a multiline entry-field (MLE) window to be the same size as
  572.     *    the client.  The MLE is used to display the method names and
  573.     *    descriptions.
  574.     *------------------------------------------------------------------------*/
  575.     WinQueryWindowRect(hwnd, (PRECTL)&rcl);
  576.  
  577.     hwndMLE = WinCreateWindow(
  578.        hwnd,                           /* Parent-window handle               */
  579.        WC_MLE,                         /* Registered-class name              */
  580.        (PSZ)NULL,                      /* Window text                        */
  581.        MLS_READONLY | MLS_VSCROLL |    /* Window style                       */
  582.          MLS_WORDWRAP | WS_VISIBLE,
  583.        rcl.xLeft,                      /* X-coordinate of the window position*/
  584.        rcl.yBottom,                    /* Y-coordinate of the window position*/
  585.        rcl.xRight,                     /* Width of window                    */
  586.        rcl.yTop,                       /* Height of window                   */
  587.        hwnd,                           /* Owner-window handle                */
  588.        HWND_TOP,                       /* Sibling-window handle              */
  589.        ID_MLE,                         /* Window identifier                  */
  590.        NULL,                           /* Pointer to control data            */
  591.        NULL);                          /* Window handle                      */
  592.  
  593.     if (!hwndMLE)
  594.         return (MRESULT)TRUE;
  595.  
  596.     /*-------------------------------------------------------------------------
  597.     *    Set the foreground and background colors for the MLE window.
  598.     *------------------------------------------------------------------------*/
  599.     WinSendMsg(hwndMLE, MLM_SETTEXTCOLOR, MPFROMLONG(lClrDefaultForeground),
  600.                NULL);
  601.     WinSendMsg(hwndMLE, MLM_SETBACKCOLOR, MPFROMLONG(lClrDefaultBackground),
  602.                NULL);
  603.  
  604.     /*-------------------------------------------------------------------------
  605.     *    Reset the undo state of the MLE.
  606.     *------------------------------------------------------------------------*/
  607.     WinSendMsg(hwndMLE, MLM_RESETUNDO, NULL, NULL);
  608.  
  609.     /*-------------------------------------------------------------------------
  610.     *    Set the import/export format for the MLE to use LF for line
  611.     *    delineation.  This format guarantees that any text imported into the
  612.     *    MLE in this format can be recovered in exactly the same form on
  613.     *    export.
  614.     *------------------------------------------------------------------------*/
  615.     WinSendMsg(hwndMLE, MLM_FORMAT, MPFROMSHORT(MLFIE_NOTRANS), NULL);
  616.  
  617.     /*-------------------------------------------------------------------------
  618.     *    Reset the MLE changed flag.
  619.     *------------------------------------------------------------------------*/
  620.     WinSendMsg(hwndMLE, MLM_SETCHANGED, MPFROMSHORT((BOOL)FALSE), NULL);
  621.  
  622.     /*-------------------------------------------------------------------------
  623.     *    Create the thread used to communicate with WPSTUTOR.DLL via a named
  624.     *    pipe.
  625.     *------------------------------------------------------------------------*/
  626.     DosCreateThread(&ThreadID, (PFNTHREAD)MonitorMethodQueue, 0L, 0L,
  627.                     STACKSIZE);
  628.  
  629.     /*-------------------------------------------------------------------------
  630.     *    Return FALSE to continue window creation and TRUE to abort it.
  631.     *------------------------------------------------------------------------*/
  632.     return (MRESULT)FALSE;
  633.  
  634.     /*-------------------------------------------------------------------------
  635.     *    This routine currently doesn't use the mp1 and mp2 parameters so
  636.     *    it is referenced here to prevent an 'Unreferenced Parameter'
  637.     *    warning at compile time.
  638.     *------------------------------------------------------------------------*/
  639.     mp1;
  640.     mp2;
  641. }
  642.  
  643. /******************************************************************************
  644. *
  645. *  Name:        ExitProc
  646. *
  647. *  Description: This function cleans up program resources when the
  648. *               application terminates.
  649. *
  650. *  Parameters:  usTermCode - Program termination code
  651. *
  652. *  Returns:     NONE
  653. *
  654. ******************************************************************************/
  655.  
  656. VOID APIENTRY ExitProc(USHORT usTermCode)
  657. {
  658.     /*-------------------------------------------------------------------------
  659.     *    Destory the main frame window if it exists.
  660.     *------------------------------------------------------------------------*/
  661.     if (WinIsWindow(hab, hwndMainFrame))
  662.        WinDestroyWindow(hwndMainFrame);
  663.  
  664.     /*-------------------------------------------------------------------------
  665.     *    Any other system resources used should be freed here.
  666.     *------------------------------------------------------------------------*/
  667.  
  668.     WinDestroyMsgQueue(hmq);
  669.     WinTerminate(hab);
  670.  
  671.     /*-------------------------------------------------------------------------
  672.     *    Complete termination of the program.
  673.     *------------------------------------------------------------------------*/
  674.     DosExitList(EXLST_EXIT, (PFNEXITLIST)ExitProc);
  675.  
  676.     /*-------------------------------------------------------------------------
  677.     *    This routine currently doesn't use the usTermCode parameter so
  678.     *    it is referenced here to prevent an 'Unreferenced Parameter'
  679.     *    warning at compile time.
  680.     *------------------------------------------------------------------------*/
  681.     usTermCode;
  682. }
  683.  
  684. /******************************************************************************
  685. *
  686. *  Name:   ShowMethodDescription
  687. *
  688. *  Description: This function builds a string to be displayed in the MLE that
  689. *               has the following format:
  690. *
  691. *                  <method name><separator><method description><break>
  692. *
  693. *               The pieces of the string are obtained from the message table.
  694. *               This string is appended to the application's MLE.
  695. *
  696. *  Parameters:  ulMethodID - ID that indicates the method name and description
  697. *                            to be displayed
  698. *
  699. *  Returns:     TRUE  - Successful execution.
  700. *               FALSE - Error occurred during processing.
  701. *
  702. ******************************************************************************/
  703.  
  704. MRESULT ShowMethodDescription(ULONG ulMethodID)
  705. {
  706.     ULONG ulNumBytes;                        /* Number of bytes appended to  */
  707.                                              /*   the MLE window             */
  708.     CHAR  szMethodDescription[METHODLENGTH]; /* Method description to be     */
  709.                                              /*   displayed                  */
  710.     CHAR  szMethodName[TITLELENGTH +
  711.                        TITLESEPARATORLEN +
  712.                        METHODLENGTH +
  713.                        (2 * HARD_BREAK_LENGTH)];
  714.                                              /* String to be appended to the */
  715.                                              /*   MLE window                 */
  716.     CHAR  szMethodSep[TITLESEPARATORLEN];    /* Buffer for text used to      */
  717.                                              /*   separate method name and   */
  718.                                              /*   description                */
  719.     CHAR  szHardBreak[HARD_BREAK_LENGTH];    /* Buffer for text used to      */
  720.                                              /*   separate method            */
  721.                                              /*   descriptions               */
  722.  
  723.     /*-------------------------------------------------------------------------
  724.     *    Disable redrawing of the MLE so the text doesn't "flash" when the MLE
  725.     *    is updated.
  726.     *------------------------------------------------------------------------*/
  727.     WinSendMsg(hwndMLE, MLM_DISABLEREFRESH, NULL, NULL);
  728.  
  729.     /*-------------------------------------------------------------------------
  730.     *    Get the name of the method to be displayed based on the data sent
  731.     *    from WPSTUTOR.DLL.  If the method name is not found, load an
  732.     *    "Unidentified Method" text string.
  733.     *------------------------------------------------------------------------*/
  734.     if ( !WinLoadMessage(hab, (HMODULE)0, (ulMethodID), TITLELENGTH,
  735.                          szMethodName) )
  736.     {
  737.        WinLoadMessage(hab, (HMODULE)0, IDM_UNIDENTIFIED_METHOD, TITLELENGTH,
  738.                       szMethodName);
  739.     }
  740.  
  741.     /*-------------------------------------------------------------------------
  742.     *    Load the text used to separate the method name and its description,
  743.     *    and append that text to the method name buffer.
  744.     *------------------------------------------------------------------------*/
  745.     if ( !WinLoadString(hab, (HMODULE)0, IDS_TITLEBARSEPARATOR,
  746.                         TITLESEPARATORLEN, szMethodSep) )
  747.     {
  748.        return FALSE;
  749.     }
  750.  
  751.     strcat(szMethodName, szMethodSep);
  752.  
  753.     /*-------------------------------------------------------------------------
  754.     *    Get the name of the description to be displayed.  If the method name
  755.     *    is not found, load an "There is no description available for this
  756.     *    method."  text string.  Append that text to the method name buffer.
  757.     *------------------------------------------------------------------------*/
  758.     if ( !WinLoadMessage(hab, (HMODULE)0, (ulMethodID + 1), METHODLENGTH,
  759.                          szMethodDescription) )
  760.     {
  761.         WinLoadMessage(hab, (HMODULE)0, IDM_UNIDENTIFIED_METHOD_MSG,
  762.                        METHODLENGTH, szMethodDescription);
  763.     }
  764.  
  765.     strcat(szMethodName, szMethodDescription);
  766.  
  767.     /*-------------------------------------------------------------------------
  768.     *    Load the text used to separate the method descriptions, and append it
  769.     *    to the method name buffer.
  770.     *------------------------------------------------------------------------*/
  771.     if ( !WinLoadString(hab, (HMODULE)0, IDS_HARD_BREAK, HARD_BREAK_LENGTH,
  772.                         szHardBreak) )
  773.     {
  774.        return FALSE;
  775.     }
  776.  
  777.     strcat(szMethodName, szHardBreak);
  778.     strcat(szMethodName, " ");
  779.     strcat(szMethodName, szHardBreak);
  780.  
  781.     /*-------------------------------------------------------------------------
  782.     *   Set the transfer buffer for the MLE to be the method name buffer.
  783.     *------------------------------------------------------------------------*/
  784.     (BOOL) WinSendMsg(hwndMLE, MLM_SETIMPORTEXPORT,
  785.                       MPFROMP((PBYTE)szMethodName),
  786.                       MPFROMSHORT(strlen(szMethodName)));
  787.  
  788.     /*-------------------------------------------------------------------------
  789.     *    Import the text using the insertion point offset we're tracking.
  790.     *    If none of the information was set into the MLE, exit the function.
  791.     *------------------------------------------------------------------------*/
  792.     ulNumBytes = (ULONG) WinSendMsg(hwndMLE, MLM_IMPORT, MPFROMP(&iptOffset),
  793.                                     MPFROMSHORT(strlen(szMethodName)));
  794.  
  795.     if ( !ulNumBytes )
  796.     {
  797.        return FALSE;
  798.     }
  799.  
  800.     /*-------------------------------------------------------------------------
  801.     *    Update the insertion point offset by the number of bytes that were
  802.     *    added to the MLE.
  803.     *------------------------------------------------------------------------*/
  804.     iptOffset = iptOffset + ulNumBytes + 1;
  805.  
  806.     /*--------------------------------------------------------------
  807.     *    Reset the changed flag for the MLE.
  808.     *-------------------------------------------------------------*/
  809.     WinSendMsg(hwndMLE, MLM_SETCHANGED, MPFROMSHORT(FALSE), NULL);
  810.  
  811.     /*-------------------------------------------------------------------------
  812.     *    Enable redrawing of the MLE.
  813.     *------------------------------------------------------------------------*/
  814.     WinSendMsg(hwndMLE, MLM_ENABLEREFRESH, NULL, NULL);
  815.  
  816.     /*-------------------------------------------------------------------------
  817.     *    Make the main frame window visible so the user can see that the MLE
  818.     *    has been updated.
  819.     *------------------------------------------------------------------------*/
  820.     WinShowWindow(hwndMainFrame, TRUE);
  821.  
  822.     return (MRESULT)TRUE;
  823. }
  824.  
  825. /******************************************************************************
  826. *
  827. *  Name:        MonitorMethodQueue
  828. *
  829. *  Description: This function is started as a thread.  This thread monitors the
  830. *               named pipe used to communicate with the WPSTutorial Object Class
  831. *               (WPSTUTOR.DLL).  After the pipe is opened, the function
  832. *               continually waits for a method ID from the object class.
  833. *               When an ID is sent via the named pipe, a message is posted to
  834. *               the application's client window so that the corresponding
  835. *               method's name and description will be displayed to the user.
  836. *
  837. *  Parameters:  NONE
  838. *
  839. *  Returns:     NONE
  840. *
  841. ******************************************************************************/
  842.  
  843. VOID MonitorMethodQueue(VOID)
  844. {
  845.    HPIPE       hNPipe;           /* Named pipe handle                        */
  846.    ULONG       ulActionTaken;    /* Describes action taken by DosOpen        */
  847.    ULONG       ulMethodID;       /* ID representing WPS method information   */
  848.                                  /*   to be displayed                        */
  849.    ULONG       ulBytesRead;      /* Number of bytes read off the named pipe  */
  850.    APIRET      rc;               /* Return code from DosXXX function         */
  851.  
  852.    /*--------------------------------------------------------------------------
  853.    *    Open the named pipe used to communicate with WPSTUTOR.DLL.
  854.    *-------------------------------------------------------------------------*/
  855.    rc = DosOpen(PIPE_NAME,
  856.                 &hNPipe,
  857.                 &ulActionTaken,
  858.                 0,
  859.                 FILE_NORMAL,
  860.                 OPEN_ACTION_OPEN_IF_EXISTS,
  861.                 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE,
  862.                 (PEAOP2)NULL);
  863.  
  864.    /*--------------------------------------------------------------------------
  865.    *    We'll continue to read method IDs from the named pipe and pass them
  866.    *    directly to the window procedure.
  867.    *-------------------------------------------------------------------------*/
  868.    while (!rc)
  869.    {
  870.       /*-----------------------------------------------------------------------
  871.       *    Get the ID of the method description to be displayed.
  872.       *----------------------------------------------------------------------*/
  873.       rc = DosRead(hNPipe,
  874.                    &ulMethodID,
  875.                    sizeof(ulMethodID),
  876.                    &ulBytesRead);
  877.  
  878.       if ( !rc )
  879.       {
  880.          /*--------------------------------------------------------------------
  881.          *    We were able to read something from the named pipe, so we'll pass
  882.          *    the information to the window procedure.
  883.          *-------------------------------------------------------------------*/
  884.          WinPostMsg(hwndMain, IDM_SHOW_METHOD, MPFROMLONG(ulMethodID),
  885.                     (MPARAM)NULL);
  886.       }
  887.    }
  888. }
  889.