home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / TOOLKIT / CREXX / PMREXX / PMREXX.C next >
C/C++ Source or Header  |  1994-11-17  |  85KB  |  1,412 lines

  1. /* static char *SCCSID = "@(#)pmrexx.c    6.3 91/12/24";                      */
  2. /*********************  START OF SPECIFICATIONS  ******************************/
  3. /*                                                                            */
  4. /*   SOURCE FILE NAME:  pmrexx.c                                              */
  5. /*                                                                            */
  6. /*   DESCRIPTIVE NAME:  PM host environment for REXX command files.           */
  7. /*                                                                            */
  8. /*      Provide a means to execute REXX command files from within a           */
  9. /*      PM environment, allowing the REXX/DM bindings to be used.             */
  10. /*                                                                            */
  11. /*   COPYRIGHT:         IBM Corporation 1991                                  */
  12. /*                                                                            */
  13. /*   STATUS:            Version 2.00                                          */
  14. /*                                                                            */
  15. /*   FUNCTION:                                                                */
  16. /*           This program provides a Presentation Manager Shell for           */
  17. /*      REXX programs.                                                        */
  18. /*                                                                            */
  19. /*                                                                            */
  20. /*   NOTES:                                                                   */
  21. /*      DEPENDENCIES:                                                         */
  22. /*          This function has dependencies on the following                   */
  23. /*      files for compilation.                                                */
  24. /*          pmrexx.h   - Definitions necessary for the resource               */
  25. /*                       file compilation.                                    */
  26. /*          pmrexxio.h - typedefs and prototypes necessary for use of         */
  27. /*                       the REXX I/O shell dll.                              */
  28. /*          The C runtime multi-threaded header files                         */
  29. /*          See README.C in \TOOLKT12\C for a list and description of the     */
  30. /*          system files that are needed.                                     */
  31. /*                                                                            */
  32. /*  EXECUTION INSTRUCTIONS:                                                   */
  33. /*          The PMREXX program is executed by specifying the                  */
  34. /*      PMREXX program with arguments corresponding to the name               */
  35. /*      of the REXX procedure file, followed by any arguments to              */
  36. /*      the REXX procedure. For example, from a command line:                 */
  37. /*          PMREXX REXXTRY say 'Hi'                                           */
  38. /*      would call PMREXX to execute the REXX procedure file                  */
  39. /*      "REXXTRY.CMD" with arguments of "say 'Hi'" being passed to            */
  40. /*      the procedure. For the same effect from the start programs            */
  41. /*      list, add PMREXX.EXE as the program (specify a path if it             */
  42. /*      is not in the system path) and "REXXTRY say 'Hi'" as the              */
  43. /*      parameters to be passed.                                              */
  44. /*                                                                            */
  45. /*  EXPECTED OUTPUT:                                                          */
  46. /*          The REXX procedure file will be executed with all                 */
  47. /*      output directed into PM windows.                                      */
  48. /*                                                                            */
  49. /*  PROCEDURES:                                                               */
  50. /*    main:           Main entry point                                        */
  51. /*    CallRexx:       Interface to the Rexx interpreter                       */
  52. /*    CheckRexxFile:  Validate program as a Rexx file                         */
  53. /*    PMRexxSubProc:  Subclass winproc of Rexx I/O window                     */
  54. /*    PMRXCmds:       Routine to process subclassed WM_COMMAND messages       */
  55. /*    SelectFile:     Put up a file selection dialog                          */
  56. /*    getstring:      Retrieve a module resource string                       */
  57. /*    init_routine:   Rexx initialization exit                                */
  58. /*    SetOption:      Enable/Disable a menu option                            */
  59. /*    SetCheckMark:   Check/Uncheck a menu option                             */
  60. /*    SysErrorBoxM:   Display message box with a system error message         */
  61. /*    CuaLogoDlgProc: Display About help                                      */
  62. /*    SysErrorBox:    Display message in a message box                        */
  63. /*                                                                            */
  64. /***********************  END OF SPECIFICATIONS  ******************************/
  65. #include <malloc.h>
  66. #include <process.h>
  67. #include <stddef.h>
  68. #include <stdio.h>
  69. #include <stdlib.h>
  70. #include <string.h>
  71.  
  72. /* Define the sections of the OS/2 header files that we need.                 */
  73.  
  74. #define  INCL_RXSYSEXIT                /* REXX system exits                   */
  75. #define  INCL_RXARI                    /* REXX Asynchronous Request Interface */
  76. #define  INCL_DOSERRORS                /* OS/2 errors                         */
  77. #define  INCL_DOSMODULEMGR             /* OS/2 module support                 */
  78. #define  INCL_DOSPROCESS               /* Process and thread support          */
  79. #define  INCL_DOSSEMAPHORES            /* Semaphores                          */
  80. #define  INCL_DOSQUEUES                /* Queues                              */
  81. #define  INCL_DOSMISC                  /* Miscellaneous doscalls              */
  82. #define  INCL_DOSNLS                   /* NLS (code page) support             */
  83. #define  INCL_GPILCIDS                 /* Physical and logical fonts with     */
  84.                                        /* lcids                               */
  85. #define  INCL_GPIPRIMITIVES            /* Drawing primitives and primitive    */
  86.                                        /* attributes                          */
  87. #define  INCL_WINCOUNTRY               /* Code page support                   */
  88. #define  INCL_WINDIALOGS               /* Dialog boxes                        */
  89. #define  INCL_WINENTRYFIELDS           /* Entry fields                        */
  90. #define  INCL_WINFRAMEMGR              /* Frame manager                       */
  91. #define  INCL_WINHELP                  /* Help manager definitions            */
  92. #define  INCL_WININPUT                 /* Mouse and keyboard input            */
  93. #define  INCL_WINMESSAGEMGR            /* Message management                  */
  94. #define  INCL_WINSHELLDATA             /* Profile calls                       */
  95. #define  INCL_WINSWITCHLIST            /* Task list calls                     */
  96. #define  INCL_WINTIMER                 /* Timer routines                      */
  97. #define  INCL_WINWINDOWMGR             /* General window management           */
  98. #define  INCL_WINMENUS                 /* Menu controls                       */
  99. #define  INCL_WINMLE                   /* Multiple line edit fields           */
  100. #define  INCL_WINPOINTERS              /* Mouse pointers                      */
  101. #define  INCL_WINSTDFILE               /* Standard File dialog                */
  102. #define  INCL_WINACCELERATORS          /* Accelerator APIs                    */
  103. #include <os2.h>
  104. #include <rexxsaa.h>                   /* Include the REXX header file        */
  105. #include "pmrexxio.h"
  106. #include "pmrexx.h"
  107.  
  108. /******************************************************************************/
  109. /*               G L O B A L    V A R I A B L E   S E C T I O N               */
  110. /******************************************************************************/
  111.  
  112. HAB     hab;                           /* Anchor block handle                 */
  113. PFNWP   SuperProc;                     /* Superclass window proc              */
  114. HWND    hwndClient;                    /* Client Window handle                */
  115. HWND    hwndFrame;                     /* Frame Window handle                 */
  116. ULONG   rexx_tid;                      /* ThreadIDs of the REXX thread        */
  117. PID     proc_id;                       /* process ID for PMREXX               */
  118. CHAR    pgmtitle[TITLE_SIZE+FNAME_SIZE+10];/* Holds title for title bar       */
  119. CHAR    procname[FNAME_SIZE];          /* Name of procedure to run            */
  120. RXSTRING rxargv;                       /* Structure to pass parameters to REXX*/
  121. BOOL    trace = FALSE;                 /* Flag to indicate if user gave a /T  */
  122. INT     ProcRC;                        /* process return code                 */
  123. CHAR    pszFileName[FNAME_SIZE];       /* buffer to hold filename             */
  124.  
  125. /* exit_list is a list of the system exits PMREXX register's with REXX        */
  126.  
  127. static RXSYSEXIT exit_list[] =  {
  128.     { PMRXIO_EXIT,   RXSIO },
  129.     { "PMREXXINIT",  RXINI },
  130.     { NULL,          RXENDLST }};
  131.  
  132. /************************** START OF SPECIFICATIONS ***************************/
  133. /*                                                                            */
  134. /*   SUBROUTINE NAME: main                                                    */
  135. /*                                                                            */
  136. /*   DESCRIPTIVE NAME:                                                        */
  137. /*               Execute the PMREXX program.                                  */
  138. /*                                                                            */
  139. /*   FUNCTION:                                                                */
  140. /*               This is the main entry point to the program. It sets up      */
  141. /*               the window, executes the message loop, and cleans up         */
  142. /*               on termination (exit from the message loop).                 */
  143. /*                                                                            */
  144. /*   NOTES:                                                                   */
  145. /*                                                                            */
  146. /*   ENTRY POINT:                                                             */
  147. /*      LINKAGE:  main(LONG  argc, CHAR *argv[])                              */
  148. /*                                                                            */
  149. /*   INPUT:                                                                   */
  150. /*      argc and argv are the standard C argument structures passed           */
  151. /*      in to a program.                                                      */
  152. /*                                                                            */
  153. /*   EXIT-NORMAL:                                                             */
  154. /*       Exit with return code 0.                                             */
  155. /*                                                                            */
  156. /*   EXIT-ERROR:                                                              */
  157. /*       If unable to register the window class, exit rc=1.                   */
  158. /*       If no procedure name was specified, exit with rc=3.                  */
  159. /*       If window was not displayed, exit with return code from the REXX     */
  160. /*         procedure.                                                         */
  161. /*       Otherwise: exit rc=0.                                                */
  162. /*                                                                            */
  163. /*   EFFECTS:                                                                 */
  164. /*       Executes the REXX procedure specified as the first argument with the */
  165. /*       input and output coming from/going to a PM window.                   */
  166. /*                                                                            */
  167. /*   INTERNAL REFERENCES:                                                     */
  168. /*      ROUTINES:                                                             */
  169. /*       CheckRexxFile  - See if the file starts with a comment line          */
  170. /*       getstring      - To obtain the title bar name and window name.       */
  171. /*                                                                            */
  172. /*   EXTERNAL REFERENCES:                                                     */
  173. /*      ROUTINES:                                                             */
  174. /*       DosExit                     WinInitialize                            */
  175. /*       DosGetInfoBlocks            WinMessageBox                            */
  176. /*       DosGetCp                    WinPostMessage                           */
  177. /*       WinAddSwitchEntry           WinQueryWindowProcess                    */
  178. /*       WinAlarm                    WinRemoveSwitchEntry                     */
  179. /*       WinCreateMsgQueue           WinSetCp                                 */
  180. /*       WinSubclassWindow           WinSetWindowText                         */
  181. /*       WinDestroyMsgQueue          WinTerminate                             */
  182. /*       WinSendMsg                  WinUpdateWindow                          */
  183. /*       WinDispatchMsg              WinWindowFromID                          */
  184. /*       WinGetMessage                                                        */
  185. /*                                                                            */
  186. /**************************** END OF SPECIFICATIONS ***************************/
  187.  
  188. void main(LONG argc, CHAR *argv[])
  189. {
  190.   HMQ      hmq;                        /* Message Queue handle                */
  191.   QMSG     qmsg;                       /* Message structure                   */
  192.   LONG     argnum = 1;                 /* Counter for looking at arguments    */
  193.   PUCHAR   trueargs;                   /* Pointer for actual argument string  */
  194.   HSWITCH  hswPMRexx = NULLHANDLE;     /* Handle to task list entry           */
  195.   SWCNTRL  swlEntry;                   /* Structure for task list entry       */
  196.   ULONG    idThread;                   /* Holds id of this thread             */
  197.   ULONG    CpSize;                     /* Size of returned code page info     */
  198.   PTIB     tib;                        /* thread block pointer                */
  199.   PPIB     pib;                        /* process block pointer               */
  200.   ULONG    CodePage;                   /* Code page we are running in         */
  201.    /* We set the creation flags to be the standard window frame flags         */
  202.    /*    but without scroll bars and without a task list entry.               */
  203.   ULONG    flCreate = FCF_STANDARD&~(FCF_VERTSCROLL|FCF_HORZSCROLL);
  204.  
  205.    /* We want the original arguments to pass to REXX, not the mangled         */
  206.    /*    version we get from C.                                               */
  207.  
  208.   DosGetInfoBlocks(&tib, &pib);
  209.   proc_id = pib->pib_ulpid;            /* save process id                     */
  210.   trueargs = pib->pib_pchcmd;          /* point to true argument string       */
  211.  
  212.   pszFileName[0] = '\0';               /* set initial file name               */
  213.  
  214.    /* Set up the PM environment                                               */
  215.   hab = WinInitialize(0);
  216.   hmq = WinCreateMsgQueue(hab, 50);
  217.  
  218.                                        /* Create application msg queue        */
  219.                                        /* Get NLS Info                        */
  220.   DosGetCp(sizeof(CodePage), &CodePage, &CpSize);
  221.   WinSetCp(hmq, (USHORT)CodePage);     /* And set for PM                      */
  222.                                        /* Create Rexx I/O window              */
  223.   hwndFrame = RexxCreateIOWindow(HWND_DESKTOP, &hwndClient);
  224.   SuperProc = WinSubclassWindow(hwndClient, (PFNWP)PMRexxSubProc);
  225.                                        /* now add additional menu items       */
  226.  
  227.                                        /* now load the accelerator table      */
  228.   WinSetAccelTable(hab, WinLoadAccelTable(hab,
  229.       (HMODULE)NULL, RXHOST_WIN), hwndFrame);
  230.  
  231.       /* See if the trace bit is supposed to be turned on                     */
  232.   if (argc > argnum && !stricmp("/t", argv[argnum])) {
  233.  
  234.     trace = TRUE;                      /* Set the trace flag                  */
  235.     argnum++;                          /* If it was, that's an extra arg to   */
  236.                                        /* skip                                */
  237.   }
  238.  
  239.   if (argc <= argnum) {                /* There must at least have been a     */
  240.                                        /* procedure name specified If not,    */
  241.                                        /* alert the user and exit.            */
  242.     WinAlarm(HWND_DESKTOP, WA_ERROR);
  243.     WinMessageBox(HWND_DESKTOP, 
  244.                   NULLHANDLE,
  245.                   getstring(BAD_NUM_PARMS),
  246.                   getstring(RXHA_MSGBOXHDR),
  247.                   1,
  248.                   MB_CANCEL|MB_CUACRITICAL|MB_MOVEABLE);
  249.     WinSetFocus(HWND_DESKTOP, hwndFrame);
  250.     WinPostMsg(hwndFrame, WM_QUIT, (MPARAM)0, (MPARAM)0);
  251.     ProcRC = BAD_NUM_PARMS;
  252.   }
  253.  
  254.   else {                               /* procedure name was specified        */
  255.     PUCHAR format = getstring(RXH_TITLE);
  256.     PUCHAR pgmname = getstring(PROGRAM_NAME);/* Create the window/program     */
  257.                                        /* title                               */
  258.  
  259.     strcpy(procname, argv[argnum]);
  260.     sprintf(pgmtitle, format, pgmname, procname);
  261.  
  262.          /* Check to see if the file starts with a comment or not             */
  263.  
  264.     if (!CheckRexxFile(procname)) {    /* It doesn't start with a comment     */
  265.                                        /* line, so put up a message box saying*/
  266.                                        /* that the procedure file could not be*/
  267.                                        /* found.                              */
  268.       *procname = '\0';
  269.       WinMessageBox(HWND_DESKTOP, 
  270.                     NULLHANDLE, getstring(RXHM_PROC_NOT_FOUND),
  271.                     getstring(RXHA_MSGBOXHDR), 1,
  272.                     MB_CANCEL|MB_CUACRITICAL|MB_MOVEABLE);
  273.       WinSetFocus(HWND_DESKTOP, hwndFrame);
  274.       WinPostMsg(hwndFrame, WM_QUIT, (MPARAM)0, (MPARAM)0);
  275.       ProcRC = PROC_NOT_FOUND;
  276.     }
  277.  
  278.          /* Update the title bar to the newly created name                    */
  279.     WinSetWindowText(WinWindowFromID(hwndFrame,(USHORT)FID_TITLEBAR),
  280.                      pgmtitle);
  281.     free(format);
  282.     free(pgmname);
  283.     argnum++;
  284.  
  285.     if (argnum < argc) {               /* In this section, we obtain the      */
  286.                                        /* arguments to pass to the REXX       */
  287.                                        /* procedure from the original         */
  288.                                        /* arguments as stored in the          */
  289.                                        /* environment segment. We cannot      */
  290.                                        /* accept the *argv[] version, because */
  291.                                        /* the C runtime library will have     */
  292.                                        /* changed things like spacing,        */
  293.                                        /* quotation marks, etc.               */
  294.  
  295.       while (*trueargs++)
  296.         ;                              /* Skip the first argument (the        */
  297.                                        /* command/program name)               */
  298.  
  299.       while (--argnum) {               /* Skip the procedure name and the "/t"*/
  300.                                        /* option, if there                    */
  301.  
  302.         while (' ' == *trueargs) {     /* Skip leading white space            */
  303.           trueargs++;
  304.         }
  305.  
  306.         do {                           /* Then skip the argument              */
  307.  
  308.           if ('"' == *trueargs) {      /* If quote delimited                  */
  309.             trueargs++;                /* skip to matching quote              */
  310.  
  311.             while (*trueargs && '"' != *trueargs++)
  312.               ;
  313.           }
  314.  
  315.           else
  316.             trueargs++;
  317.         }
  318.  
  319.  
  320.         while (' ' != *trueargs);
  321.  
  322.       }
  323.       trueargs++;                      /* Skip next space Set up the remaining*/
  324.                                        /* argument string for passing to the  */
  325.                                        /* REXX procedure.                     */
  326.       rxargv.strptr = (PCHAR)strdup(trueargs);
  327.       rxargv.strlength = strlen(rxargv.strptr);
  328.  
  329.     }
  330.  
  331.     else {                             /* no additional arguments             */
  332.       rxargv.strlength = 0;
  333.       rxargv.strptr = NULL;
  334.     }
  335.  
  336.                                        /* register I/O handler                */
  337.     RexxRegisterExitExe("PMREXXINIT", (PFN)init_routine, NULL);
  338.     DosCreateThread(&rexx_tid, (PFNTHREAD)CallRexx, (ULONG)0, (ULONG)0,
  339.         STACK_SIZE);
  340.   }
  341.  
  342.   WinUpdateWindow(hwndFrame);
  343.  
  344.    /* Get the switch list handle                                              */
  345.  
  346.   WinQueryWindowProcess(hwndFrame, &swlEntry.idProcess, &idThread);
  347.  
  348.   hswPMRexx = WinQuerySwitchHandle(hwndFrame, swlEntry.idProcess);
  349.  
  350.   if (!WinQuerySwitchEntry(hswPMRexx, &swlEntry)) {
  351.  
  352.     strcpy(swlEntry.szSwtitle, pgmtitle);
  353.     WinChangeSwitchEntry(hswPMRexx, &swlEntry);
  354.   }
  355.  
  356.    /* Main message processing loop - get and dispatch messages until          */
  357.    /* WM_QUIT received                                                        */
  358.  
  359.   while (WinGetMsg(hab, &qmsg, (HWND)NULL, 0, 0))
  360.     WinDispatchMsg(hab, &qmsg);
  361.  
  362.                                        /* Delete subclassing                  */
  363.   WinSubclassWindow(hwndClient, (PFNWP)SuperProc);
  364.                                        /* Destroy Rexx I/O window             */
  365.   RexxDestroyIOWindow(hwndFrame);
  366.   DosSuspendThread(rexx_tid);          /* suspend Rexx program                */
  367.                                        /* drop exit handlers                  */
  368.   RexxDeregisterExit("PMREXXINIT", NULL);
  369.   WinDestroyMsgQueue(hmq);
  370.   WinTerminate(hab);
  371.  
  372.    /* Exit the process and return the return code specified by ProcRC         */
  373.  
  374.   DosExit(EXIT_PROCESS, ProcRC);
  375. }
  376.  
  377.  
  378. /************************** START OF SPECIFICATIONS ***************************/
  379. /*                                                                            */
  380. /*   SUBROUTINE NAME: CallRexx                                                */
  381. /*                                                                            */
  382. /*   DESCRIPTIVE NAME:                                                        */
  383. /*               Execute the REXX procedure file via the RexxStart interface. */
  384. /*                                                                            */
  385. /*   FUNCTION:                                                                */
  386. /*               This function is the thread that executes the REXX           */
  387. /*               procedure. It disables the RESTART option and calls the      */
  388. /*               Rexx interpreter.  On return, it reenables the RESTART       */
  389. /*               options, outputs a message box indicating the procedure has  */
  390. /*               ended, and terminates the thread.                            */
  391. /*                                                                            */
  392. /*   NOTES:                                                                   */
  393. /*                                                                            */
  394. /*   ENTRY POINT:                                                             */
  395. /*      LINKAGE:                                                              */
  396. /*          void _stdcall CallRexx(void                                       */
  397. /*                                                                            */
  398. /*   INPUT:                                                                   */
  399. /*       The arguments for the procedure have already been placed in the      */
  400. /*       global variable 'rxargv'.                                            */
  401. /*                                                                            */
  402. /*   EXIT-NORMAL:                                                             */
  403. /*                                                                            */
  404. /*   EXIT-ERROR:                                                              */
  405. /*                                                                            */
  406. /*   EFFECTS:                                                                 */
  407. /*                                                                            */
  408. /*   INTERNAL REFERENCES:                                                     */
  409. /*      ROUTINES:                                                             */
  410. /*       SetCheckMark   - Check/uncheck a menu item                           */
  411. /*       SetOptions     - Enable/disable menu items.                          */
  412. /*                                                                            */
  413. /*   EXTERNAL REFERENCES:                                                     */
  414. /*      ROUTINES:                                                             */
  415. /*                                                                            */
  416. /**************************** END OF SPECIFICATIONS ***************************/
  417.  
  418. void CallRexx(void)
  419. {
  420.   RXSTRING retval;                     /* return value from call to REXXSAA   */
  421.   SHORT    rc;                         /* return code                         */
  422.  
  423.   SetOptions(PMRXA_RESTART, FALSE);    /* Don't allow restart while active    */
  424.   SetOptions(RXIOA_HALT, TRUE);        /* Enable HALT option                  */
  425.                                        /* enable I/O system                   */
  426.   while (!WinPostMsg(hwndClient, REXX_STARTPROC,
  427.       MPFROMLONG(rexx_tid), (MPARAM)0));
  428.     DosSleep(0L);
  429.  
  430.    MAKERXSTRING(retval, NULL, 0);      /* null out RXSTRING                   */
  431.    /* Now start the REXX procedure. Check for a not-found error.           */
  432.    if (PROC_NOT_FOUND == RexxStart((!rxargv.strlength) ? 0 : 1,
  433.                                    (!rxargv.strlength)? NULL : &rxargv,
  434.                                   procname,
  435.                                   NULL,
  436.                                   NULL,
  437.                                   RXCOMMAND,
  438.                                   exit_list,
  439.                                   &rc,
  440.                                   &retval )) {
  441.  
  442.       /* If the procedure was not found, let the window procedure put up   */
  443.       /*   a message box indicating the problem. Set the return code to    */
  444.       /*   exit with.                                                      */
  445.       while (!WinPostMsg(hwndClient, REXX_PROC_NF, NULL, NULL))
  446.          DosSleep(0L);
  447.       ProcRC = PROC_NOT_FOUND;
  448.  
  449.    }
  450.    else {
  451.      DosSleep((ULONG)TIMER_DELAY);
  452.      ProcRC = rc;
  453.   }
  454.                                        /* disable I/O system                  */
  455.   while (!WinPostMsg(hwndClient, REXX_ENDPROC, (MPARAM)0, (MPARAM)0))
  456.     DosSleep(0L);
  457.  
  458.   SetOptions(PMRXA_RESTART, TRUE);     /* Re-enable the re-start option       */
  459.   SetCheckMark(RXIOA_HALT, FALSE);
  460.   SetOptions(RXIOA_HALT, FALSE);       /* Don't allow halt if not active      */
  461.                                        /* display message to user             */
  462.   while (!WinPostMsg(hwndClient, REXX_PROC_ENDED, (MPARAM)0, (MPARAM)0))
  463.     DosSleep(0L);
  464.   DosExit(EXIT_THREAD, 0);             /* end the thread                      */
  465. }
  466.  
  467.  
  468. /************************** START OF SPECIFICATIONS ***************************/
  469. /*                                                                            */
  470. /*   SUBROUTINE NAME:  CheckRexxFile                                          */
  471. /*                                                                            */
  472. /*   DESCRIPTIVE NAME:                                                        */
  473. /*              Verify that this is a REXX procedure file.                    */
  474. /*                                                                            */
  475. /*   FUNCTION:  This function will check that the file starts with a comment  */
  476. /*              line to verify that it is a REXX procedure file.              */
  477. /*                                                                            */
  478. /*   NOTES:                                                                   */
  479. /*                                                                            */
  480. /*   ENTRY POINT:                                                             */
  481. /*      LINKAGE:                                                              */
  482. /*            ULONG  CheckRexxFile(PUCHAR procname)                           */
  483. /*                                                                            */
  484. /*   INPUT:                                                                   */
  485. /*       procname - ptr to an asciiz string containing the filename to run    */
  486. /*                                                                            */
  487. /*   EXIT-NORMAL:                                                             */
  488. /*       returns TRUE if the file starts with a comment line                  */
  489. /*                                                                            */
  490. /*   EXIT-ERROR:                                                              */
  491. /*       returns FALSE otherwise                                              */
  492. /*                                                                            */
  493. /*   EFFECTS:                                                                 */
  494. /*                                                                            */
  495. /*   INTERNAL REFERENCES:                                                     */
  496. /*      ROUTINES:                                                             */
  497. /*                                                                            */
  498. /*   EXTERNAL REFERENCES:                                                     */
  499. /*      ROUTINES:                                                             */
  500. /*        DosSearchPath                                                       */
  501. /**************************** END OF SPECIFICATIONS ***************************/
  502.  
  503. ULONG  CheckRexxFile(PUCHAR procname)
  504. {
  505.   CHAR fullname[FNAME_SIZE];           /* buffer for fully qualified path     */
  506.   CHAR tempname[FNAME_SIZE];           /* holds name to search for            */
  507.   FILE *fptr = NULL;                   /* ptr to file                         */
  508.   CHAR *pathchar,*colon;               /* ptr to '\' and ':'                  */
  509.   CHAR buff[10];                       /* holds input line from file          */
  510.   ULONG  i;                            /* counter variable                    */
  511.  
  512.   strcpy(tempname, procname);          /* copy name to temp holder            */
  513.  
  514.   for (i = 0; i < 2 && !fptr; i++) {   /* loop through twice                  */
  515.  
  516.     if (!(fptr = fopen(tempname, "r"))) {/* couldn't open the file            */
  517.       pathchar = getstring(BACKPATH_DELIMETER);/* load in '\' and             */
  518.       colon = getstring(DRIVE_DELIMETER);/* ':'                               */
  519.  
  520.          /* Check to see it they entered a path                               */
  521.  
  522.       if (!strchr(procname, *pathchar) && !strchr(procname, *colon)) {
  523.                                        /* They only entered a filename, so    */
  524.                                        /* search the DPATH for it             */
  525.  
  526.         if (!DosSearchPath(SEARCH_CUR_DIRECTORY|SEARCH_ENVIRONMENT|
  527.             SEARCH_IGNORENETERRS, "PATH", tempname, fullname, sizeof(fullname)
  528.             )) {
  529.           fptr = fopen(fullname, "r"); /* Try and open the file               */
  530.         }
  531.       }
  532.     }
  533.  
  534.       /* If we still haven't found it stick on a .CMD, and try again          */
  535.  
  536.     if (!fptr) {
  537.       strcat(tempname, ".cmd");
  538.     }
  539.   }
  540.  
  541.   if (fptr) {                          /* We found it                         */
  542.     fgets(buff, 10, fptr);             /* read in the first line              */
  543.  
  544.       /* Check if the first two characters are a comment                      */
  545.  
  546.     if (*buff == '/' && *(buff+1) == '*') {
  547.  
  548.          /* It's OK, so copy whatever name we found to procname               */
  549.  
  550.       strcpy(procname, tempname);
  551.       fclose(fptr);                    /* Close the file                      */
  552.       return  TRUE;                    /* Indicate success                    */
  553.     }
  554.  
  555.     fclose(fptr);                      /* Close the file                      */
  556.   }
  557.   return  FALSE;                       /* Indicate failure                    */
  558. }
  559.  
  560. /************************** START OF SPECIFICATIONS ***************************/
  561. /*                                                                            */
  562. /*   SUBROUTINE NAME: PMRexxSubProc                                           */
  563. /*                                                                            */
  564. /*   DESCRIPTIVE NAME:                                                        */
  565. /*               Subclass handler for PMREXX I/O window.                      */
  566. /*                                                                            */
  567. /*   FUNCTION:                                                                */
  568. /*               This procedure handles all messages over and above the       */
  569. /*               ones handled by the main PMREXX window.                      */
  570. /*               are:                                                         */
  571. /*       REXX_PROC_NF   - Puts up a message box indicating that the REXX      */
  572. /*                        procedure was not found.                            */
  573. /*       REXX_PROC_ENDED- Puts up a message box indicating to the user that   */
  574. /*                        the REXX procedure has terminated.                  */
  575. /*       RXHB_MSGBOX    - Puts up a message box with the requested message.   */
  576. /*       WM_SAVEAPPLICATION - Save the current font and window information    */
  577. /*                                                                            */
  578. /*   NOTES:                                                                   */
  579. /*                                                                            */
  580. /*   ENTRY POINT:                                                             */
  581. /*      LINKAGE:                                                              */
  582. /*               Standard window procedure linkage is followed.               */
  583. /*                                                                            */
  584. /*   INPUT:                                                                   */
  585. /*               Standard window procedure inputs are passed in.              */
  586. /*                                                                            */
  587. /*   INTERNAL REFERENCES:                                                     */
  588. /*      ROUTINES:                                                             */
  589. /*       getstring      - Retrieve a string resource                          */
  590. /*       PMRXCmds       - This routine processes the various WM_COMMAND       */
  591. /*                        messages.                                           */
  592. /*       SetCheckMark   - Check/uncheck a menu item                           */
  593. /*       SysErrorBoxM   - SysErrorBox with added user control                 */
  594. /*       ProcessSaveQuit - Interface to the Save/Quit dialog                  */
  595. /*                                                                            */
  596. /*                                                                            */
  597. /*   EXTERNAL REFERENCES:                                                     */
  598. /*      ROUTINES:                                                             */
  599. /*       DosReleaseMutexSem                WinMessageBox                      */
  600. /*       DosRequestMutexSem                WinPostMsg                         */
  601. /*       WinSendMsg                        WinQueryWindow                     */
  602. /*       WinSetFocus                       WinQueryWindowPos                  */
  603. /*       WinWindowFromID                                                      */
  604. /*                                                                            */
  605. /**************************** END OF SPECIFICATIONS ***************************/
  606.  
  607. MRESULT EXPENTRY PMRexxSubProc(HWND hwnd, ULONG msg, MPARAM mp1,
  608.                               MPARAM mp2)
  609. {
  610.  
  611.     switch (msg) {
  612.  
  613.       case  WM_COMMAND :
  614.                                        /* All WM_COMMAND processed in PMRXCmds*/
  615.         return (PMRXCmds(hwnd, mp1, mp2));
  616.         break;
  617.  
  618.       case  WM_CHAR :
  619.  
  620.          /* Check for a valid (complete) key message.                         */
  621.  
  622.         if (!(SHORT1FROMMP(mp1)&KC_KEYUP) &&
  623.             (SHORT1FROMMP(mp1)&KC_VIRTUALKEY) ) {
  624.  
  625.           switch (SHORT2FROMMP(mp2)) {
  626.             case  VK_BREAK :           /* For a break key, set the halt       */
  627.                                        /* procedure indicator.                */
  628.               WinSendMsg(hwnd, WM_COMMAND, MPFROMSHORT(RXIOA_HALT), (MPARAM)0);
  629.               break;
  630.  
  631.             default  :
  632.               break;
  633.           }                            /* endswitch                           */
  634.         }
  635.         break;
  636.  
  637.       case  DOS_ERROR :
  638.  
  639.          /* Place the information on the base system error into a message     */
  640.          /*   box.                                                            */
  641.  
  642.         SysErrorBoxM(hwnd, SHORT1FROMMP(mp1), mp2, SHORT2FROMMP(mp1));
  643.         break;
  644.  
  645.       case  REXX_PROC_NF :
  646.  
  647.          /* Tell the user that REXX could not find the procedure, and then    */
  648.          /*    exit.                                                          */
  649.  
  650.         WinAlarm(HWND_DESKTOP, WA_ERROR);
  651.         WinSendMsg(hwndClient, RXHB_MSGBOX,
  652.             MPFROM2SHORT(RXHM_PROC_NOT_FOUND, RXHA_MSGBOXHDR),
  653.             MPFROMLONG(MB_CANCEL|MB_CUACRITICAL|MB_MOVEABLE));
  654.         WinPostMsg(hwndClient, WM_CLOSE, (MPARAM)0, (MPARAM)0);
  655.         break;
  656.  
  657.       case  REXX_PROC_ENDED :
  658.  
  659.          /* Tell the user that the procedure has completed processing.        */
  660.  
  661.         WinSendMsg(hwndClient, RXHB_MSGBOX,
  662.             MPFROM2SHORT(RXHM_PROC_ENDED, PROGRAM_NAME),
  663.             MPFROMLONG(MB_OK|MB_INFORMATION|MB_MOVEABLE));
  664.         break;
  665.  
  666.       case  RXHB_MSGBOX : {            /* Put up a message box. The mp1       */
  667.                                        /* parameter has the resource ids for  */
  668.                                        /* the message and the title.          */
  669.           USHORT msgid = SHORT1FROMMP(mp1);
  670.           PUCHAR header = getstring(SHORT2FROMMP(mp1));
  671.           PUCHAR content = getstring(SHORT1FROMMP(mp1));/* If we are          */
  672.                                        /* displaying the ended message, set   */
  673.                                        /* the owner to the desktop so we don't*/
  674.                                        /* steal the focus back from other     */
  675.                                        /* apps.                               */
  676.  
  677.           LONG  rc = WinMessageBox(HWND_DESKTOP,
  678.               (RXHM_PROC_ENDED == msgid?HWND_DESKTOP: hwnd),
  679.               content, header, msgid, SHORT1FROMMP(mp2));
  680.           free(header);
  681.           free(content);
  682.           return  MPFROMSHORT(rc);
  683.         }
  684.         break;
  685.  
  686.       case  WM_CLOSE :
  687.  
  688.          /* Check to see if the window needs to be saved, but only if the     */
  689.          /* user has entered a filename, otherwise just exit.                 */
  690.  
  691.         if ((!strlen(pszFileName)) || ProcessSaveQuit(hwnd)) {
  692.           WinSendMsg(hwndClient, WM_SAVEAPPLICATION, NULL, NULL);
  693.           WinPostMsg( hwndFrame, WM_QUIT, 0L, 0L );
  694.           return (MRESULT)(FALSE);
  695.         }
  696.  
  697.         else {                         /* Don't Close if Cancel on            */
  698.                                        /* ProcessSaveQuit                     */
  699.           return (MRESULT)(TRUE);
  700.         }
  701.         break;
  702.  
  703.       default  :
  704.         break;
  705.     }
  706.     return (*SuperProc)(hwnd, msg, mp1, mp2);
  707. }
  708.  
  709. /************************** START OF SPECIFICATIONS ***************************/
  710. /*                                                                            */
  711. /*   SUBROUTINE NAME: PMRXCmds                                                */
  712. /*                                                                            */
  713. /*   DESCRIPTIVE NAME:                                                        */
  714. /*               Process WM_COMMAND messages for the window procedure.        */
  715. /*                                                                            */
  716. /*   FUNCTION:                                                                */
  717. /*               This routine processes all the WM_COMMAND messages that have */
  718. /*               are handled by the Subclassed window.  Messages handled are: */
  719. /*                                                                            */
  720. /*       PMRXA_RESTART  - This requests that the REXX procedure be re-run.    */
  721. /*                        This command is only valid if the previous instance */
  722. /*                        of the procedure has ended.                         */
  723. /*       PMRXA_EXIT     - This is a request to close the application.         */
  724. /*       PMRXA_SAVEAS   - Save the MLE to the same file as last time.         */
  725. /*       PMRXA_SAVE     - Present the user with a dialog to select a file for */
  726. /*                        saving the MLE.                                     */
  727. /*       PMRXA_ABOUT    - Present the About dialog.                           */
  728. /*                                                                            */
  729. /*   NOTES:                                                                   */
  730. /*                                                                            */
  731. /*   ENTRY POINT:                                                             */
  732. /*      LINKAGE:                                                              */
  733. /*       MRESULT PMRXCmds(HWND hwnd, MPARAM mp1, MPARAM MP2)                  */
  734. /*                                                                            */
  735. /*   INPUT:                                                                   */
  736. /*       hwnd           - The window handle of the window that received the   */
  737. /*                        command.                                            */
  738. /*       mp1            - The first parameter of the WM_COMMAND message.      */
  739. /*       mp2            - The second parameter of the WM_COMMAND message.     */
  740. /*                                                                            */
  741. /*   EXIT-NORMAL:                                                             */
  742. /*       returns TRUE if the file was saved successfully or user response     */
  743. /*       from SAVEAS dialog.                                                  */
  744. /*   EXIT-ERROR:                                                              */
  745. /*       returns FALSE if the file was not saved successfully.                */
  746. /*                                                                            */
  747. /*   EFFECTS:                                                                 */
  748. /*                                                                            */
  749. /*   INTERNAL REFERENCES:                                                     */
  750. /*      ROUTINES:                                                             */
  751. /*       getstring      - Retrieve a string resource                          */
  752. /*       SelectFile     - Interface to the file selection dialog              */
  753. /*       SetCheckMark   - Check/uncheck a menu item                           */
  754. /*       WriteFile      - Write the data from the MLE into a file             */
  755. /*                                                                            */
  756. /*                                                                            */
  757. /*   EXTERNAL REFERENCES:                                                     */
  758. /*      ROUTINES:                                                             */
  759. /*       WinAlarm                       WinPostMessage                        */
  760. /*       WinSendMsg                     WinLoadString                         */
  761. /*       WinDlgBox                      WinWindowFromID                       */
  762. /*                                                                            */
  763. /**************************** END OF SPECIFICATIONS ***************************/
  764.  
  765. MRESULT PMRXCmds(HWND hwnd, MPARAM mp1, MPARAM mp2)
  766. {
  767.     CHAR pszFMask[FNAME_SIZE];         /* buffer to hold mask for wildcard    */
  768.                                        /* searches                            */
  769.     CHAR pszTitle[TITLE_SIZE];         /* text for Save As title bar          */
  770.     CHAR pszFName[FNAME_SIZE];         /* buffer for formatted filename       */
  771.     CHAR Temp = '\0';                  /* temporary character                 */
  772.     ULONG  UserResponse;               /* holds user response from Save As    */
  773.                                        /* dialog                              */
  774.  
  775.  
  776.     switch (LOUSHORT(mp1)) {
  777.  
  778.       /************************************************************************/
  779.       /* Rerun the program                                                    */
  780.       /************************************************************************/
  781.  
  782.       case  PMRXA_RESTART :
  783.  
  784.          /* Restart the REXX procedure.                                       */
  785.         DosCreateThread(&rexx_tid, (PFNTHREAD)CallRexx, (ULONG)0, (ULONG)0,
  786.             STACK_SIZE);
  787.  
  788.         break;
  789.  
  790.       /************************************************************************/
  791.       /* Shutdown and get out                                                 */
  792.       /************************************************************************/
  793.  
  794.       case PMRXA_EXIT:
  795.  
  796.          WinPostMsg( hwnd, WM_CLOSE, 0L, 0L );
  797.          break;
  798.  
  799.       /************************************************************************/
  800.       /* Save the file according to user file specification                   */
  801.       /************************************************************************/
  802.  
  803.       case  PMRXA_SAVE :
  804.  
  805.         WinSendMsg(WinWindowFromID(hwnd, (USHORT)MLE_WNDW),
  806.             MLM_RESETUNDO, (MPARAM)0, (MPARAM)0);
  807.  
  808.         if (!strlen(pszFileName)) {    /* User hasn't added a filename  */
  809.                                        /* yet, so put up the Save As dialog   */
  810.           WinSendMsg(hwnd, WM_COMMAND, MPFROMSHORT(PMRXA_SAVEAS), (MPARAM)0);
  811.         }
  812.  
  813.         else {                         /* We have the filename, so just write */
  814.                                        /* it out.                             */
  815.  
  816.           if (WriteFile(hab, hwnd, pszFileName, procname, FALSE)) {
  817.             WinSendMsg(WinWindowFromID(hwnd, (USHORT)MLE_WNDW),
  818.                        MLM_SETCHANGED, MPFROMSHORT(FALSE), (MPARAM)0);
  819.             return (MRESULT)(TRUE);
  820.           }
  821.  
  822.           else {
  823.             return (MRESULT)(FALSE);
  824.           }
  825.         }
  826.         break;
  827.  
  828.       /************************************************************************/
  829.       /* Bring up the Save As dialog to get the filename                      */
  830.       /************************************************************************/
  831.  
  832.       case  PMRXA_SAVEAS :
  833.         WinLoadString(hab, (HMODULE)NULL, PMRXHB_SAVETITLE,
  834.             sizeof(pszTitle), pszTitle);
  835.         WinLoadString(hab, (HMODULE)NULL, PMRXHB_FILEMASK,
  836.             sizeof(pszFMask), pszFMask);
  837.         *pszFName = '\0';
  838.  
  839.         if (ESCAPE != (UserResponse = SelectFile( pszTitle,
  840.             pszFMask, pszFName))) {
  841.  
  842.           if (WriteFile(hab, hwnd, pszFName, procname, TRUE)) {
  843.             WinSendMsg(WinWindowFromID(hwnd, (USHORT)MLE_WNDW),
  844.                        MLM_SETCHANGED, MPFROMSHORT(FALSE), NULL);
  845.             strcpy(pszFileName, pszFName);
  846.           }
  847.         }
  848.         WinSendMsg(WinWindowFromID(hwnd, (USHORT)MLE_WNDW),
  849.                    MLM_RESETUNDO, (MPARAM)0, (MPARAM)0);
  850.         return (MRESULT)(UserResponse);
  851.         break;
  852.  
  853.       /************************************************************************/
  854.       /* Display the About dialog.                                            */
  855.       /************************************************************************/
  856.  
  857.       case  PMRXA_ABOUT :
  858.  
  859.         WinDlgBox(HWND_DESKTOP, hwndFrame, (PFNWP)CuaLogoDlgProc,
  860.                   (HMODULE)NULL, PMREXX_CUALOGO, (PSZ)NULL);
  861.         break;
  862.  
  863.  
  864.       /************************************************************************/
  865.       /* Option not handled here, pass on to default win proc                 */
  866.       /************************************************************************/
  867.  
  868.       default  :
  869.         return (*SuperProc)(hwnd, WM_COMMAND, mp1, mp2);
  870.     }
  871. }
  872.  
  873. /************************** START OF SPECIFICATIONS ***************************/
  874. /*                                                                            */
  875. /*   SUBROUTINE NAME: SelectFile                                              */
  876. /*                                                                            */
  877. /*   DESCRIPTIVE NAME: Bring up Select File dialog procedure.                 */
  878. /*                                                                            */
  879. /*   FUNCTION:                                                                */
  880. /*               This routine sets up the file structure before calling the   */
  881. /*               file selection dialog.                                       */
  882. /*                                                                            */
  883. /*   NOTES:                                                                   */
  884. /*                                                                            */
  885. /*   ENTRY POINT:                                                             */
  886. /*      LINKAGE: ULONG  SelectFile                                            */
  887. /*                                                                            */
  888. /*   INPUT:                                                                   */
  889. /*      PSZ pszTitle - current title text                                     */
  890. /*      PSZ pszFileMask - file mask to search for                             */
  891. /*      PSZ pszFName - filename (returned)                                    */
  892. /*                                                                            */
  893. /*   EXIT-NORMAL:                                                             */
  894. /*      Returns ENTER or ESCAPE                                               */
  895. /*                                                                            */
  896. /*   EXIT-ERROR:                                                              */
  897. /*      None.                                                                 */
  898. /*                                                                            */
  899. /*   EFFECTS:                                                                 */
  900. /*                                                                            */
  901. /*   INTERNAL REFERENCES:                                                     */
  902. /*      ROUTINES:                                                             */
  903. /*        getstring                                                           */
  904. /*                                                                            */
  905. /*   EXTERNAL REFERENCES:                                                     */
  906. /*      ROUTINES:                                                             */
  907. /*        WinFileDlg                                                          */
  908. /*                                                                            */
  909. /**************************** END OF SPECIFICATIONS ***************************/
  910.  
  911.   ULONG  SelectFile(PSZ pszTitle, PSZ pszFileMask, PSZ pszFName) {
  912.     BOOL     fSuccess = FALSE;
  913.     HWND     hwndDlg;                  /* file dialog handle                  */
  914.     FILEDLG  fdl;                      /* open/saveas dialog data             */
  915.     PSZ      pszDefaultDrive = NULL ;
  916.     static   PSZ   ppszDefaultDriveList[] = { NULL } ;
  917.     PSZ      pszDefaultEAType = NULL ;
  918.     static   PSZ   ppszDefaultEATypeList[] = { NULL } ;
  919.  
  920.  
  921.   fdl.pfnDlgProc     = NULL;
  922.   fdl.cbSize         = sizeof(FILEDLG);
  923.   fdl.fl             = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG ;
  924.   fdl.ulUser         = 0L ;
  925.   fdl.lReturn        = 0L;
  926.   fdl.lSRC           = FDS_SUCCESSFUL ;
  927.   fdl.hMod           = (HMODULE)NULL ;
  928.   fdl.usDlgId        = 0 ;
  929.   fdl.x              = 0 ;
  930.   fdl.y              = 0 ;
  931.   fdl.pszIDrive      = pszDefaultDrive ;
  932.   fdl.papszIDriveList= (PAPSZ) ppszDefaultDriveList ;
  933.   fdl.pszIType       = pszDefaultEAType ;
  934.   fdl.papszITypeList = (PAPSZ) ppszDefaultEATypeList ;
  935.   fdl.pszOKButton    = NULL;
  936.  
  937.   strcpy(fdl.szFullFile, pszFileMask);
  938.   fdl.pszTitle = pszTitle;
  939.  
  940.   /* Call the Standard Open/SaveAs Dialog Procedure. */
  941.  
  942.   hwndDlg = WinFileDlg(HWND_DESKTOP, hwndClient, &fdl);
  943.  
  944.   /* Check which button was selected. */
  945.  
  946.   switch ((SHORT)fdl.lReturn) {
  947.  
  948.     case DID_OK_PB:
  949.       strcpy(pszFName, fdl.szFullFile);
  950.       fSuccess = TRUE;
  951.       break;
  952.  
  953.     case DID_CANCEL_PB:
  954.       fSuccess = FALSE;
  955.       break ;
  956.   }
  957.  
  958.   return fSuccess;
  959. }
  960.  
  961. /************************** START OF SPECIFICATIONS ***************************/
  962. /*                                                                            */
  963. /*   SUBROUTINE NAME: getstring                                               */
  964. /*                                                                            */
  965. /*   DESCRIPTIVE NAME:                                                        */
  966. /*               Allocate memory for, and obtain a string resource.           */
  967. /*                                                                            */
  968. /*   FUNCTION:                                                                */
  969. /*               This function gets a string resource from the                */
  970. /*               program file. It accepts as input, the resource ID           */
  971. /*               of the string to get, and returns a far pointer to           */
  972. /*               the string in allocated storage. The caller should           */
  973. /*               free the storage (via free()) when done with the             */
  974. /*               string.                                                      */
  975. /*                                                                            */
  976. /*   NOTES:                                                                   */
  977. /*                                                                            */
  978. /*   ENTRY POINT:                                                             */
  979. /*      LINKAGE:  getstring(ULONG  string_name)                               */
  980. /*                                                                            */
  981. /*   INPUT:                                                                   */
  982. /*      string_name - The resource ID that identifies the string in the       */
  983. /*                    resource file.                                          */
  984. /*                                                                            */
  985. /*   EXIT-NORMAL:                                                             */
  986. /*      Returns a pointer to the string.                                      */
  987. /*                                                                            */
  988. /*   EXIT-ERROR:                                                              */
  989. /*      Returns a null pointer.  Use WinGetLastError to find the cause.       */
  990. /*                                                                            */
  991. /*   EFFECTS:                                                                 */
  992. /*      Assumptions made include:                                             */
  993. /*          The maximum width string to be obtained is MAXWIDTH-1 characters. */
  994. /*          MAXWIDTH is defined in file PMREXX.H.                             */
  995. /*                                                                            */
  996. /*   INTERNAL REFERENCES:                                                     */
  997. /*      ROUTINES:                                                             */
  998. /*                                                                            */
  999. /*   EXTERNAL REFERENCES:                                                     */
  1000. /*      ROUTINES:                                                             */
  1001. /*       WinLoadString                                                        */
  1002. /*                                                                            */
  1003. /**************************** END OF SPECIFICATIONS ***************************/
  1004.  
  1005. PUCHAR getstring(ULONG  string_name)
  1006. {
  1007.   UCHAR buffer[MAXWIDTH];
  1008.   ULONG chars;
  1009.  
  1010.   buffer[0] = '\0';
  1011.   /* Get the message into our local buffer, then make a copy to return.      */
  1012.  
  1013.   chars = WinLoadString(hab, (HMODULE)NULL, 
  1014.       (ULONG)string_name, MAXWIDTH, buffer);
  1015.   return  strdup(buffer);
  1016. }
  1017.  
  1018. /************************** START OF SPECIFICATIONS ***************************/
  1019. /*                                                                            */
  1020. /*   SUBROUTINE NAME: init_routine                                            */
  1021. /*                                                                            */
  1022. /*   DESCRIPTIVE NAME:                                                        */
  1023. /*               Process the REXX Initialization exit                         */
  1024. /*                                                                            */
  1025. /*   FUNCTION:                                                                */
  1026. /*               This function has been registered to handle the RXINI exit.  */
  1027. /*               for the REXX procedure. This issues a call to RexxSetTrace   */
  1028. /*               to turn on tracing if it has been requested from the onset.  */
  1029. /*                                                                            */
  1030. /*   NOTES:                                                                   */
  1031. /*                                                                            */
  1032. /*   ENTRY POINT:                                                             */
  1033. /*      LINKAGE:                                                              */
  1034. /*          LONG  init_routine( LONG  exitno, LONG  subfunc, PUCHAR parmblock)*/
  1035. /*                                                                            */
  1036. /*   INPUT:                                                                   */
  1037. /*       The arguments are defined by the REXX interface specifications.      */
  1038. /*                                                                            */
  1039. /*   INTERNAL REFERENCES:                                                     */
  1040. /*      ROUTINES:                                                             */
  1041. /*                                                                            */
  1042. /*   EXTERNAL REFERENCES:                                                     */
  1043. /*      ROUTINES:                                                             */
  1044. /*        RexxSetTrace                                                        */
  1045. /*                                                                            */
  1046. /**************************** END OF SPECIFICATIONS ***************************/
  1047.  
  1048. LONG  init_routine(LONG  exitno, LONG  subfunc, PUCHAR parmblock)
  1049. {
  1050.   if (trace)                           /* tracing at start?                   */
  1051.     RexxSetTrace(proc_id, rexx_tid);   /* turn it on now                      */
  1052.   return RXEXIT_HANDLED;               /* return with no errors               */
  1053. }
  1054.  
  1055. /************************** START OF SPECIFICATIONS ***************************/
  1056. /*                                                                            */
  1057. /*   SUBROUTINE NAME: SetOptions                                              */
  1058. /*                                                                            */
  1059. /*   DESCRIPTIVE NAME:                                                        */
  1060. /*               Enable/disable menu items.                                   */
  1061. /*                                                                            */
  1062. /*   FUNCTION:                                                                */
  1063. /*               This function is called to individually enable or disable a  */
  1064. /*               particular item in the menu structure.                       */
  1065. /*                                                                            */
  1066. /*   NOTES:                                                                   */
  1067. /*                                                                            */
  1068. /*   ENTRY POINT:                                                             */
  1069. /*      LINKAGE:                                                              */
  1070. /*          void SetOptions( ULONG  item, BOOL option )                       */
  1071. /*                                                                            */
  1072. /*   INPUT:                                                                   */
  1073. /*       item           - The id of the item to enable/disable                */
  1074. /*       option         - TRUE to enable the option, FALSE to disable.        */
  1075. /*                                                                            */
  1076. /*   EXIT-NORMAL:                                                             */
  1077. /*                                                                            */
  1078. /*   EXIT-ERROR:                                                              */
  1079. /*                                                                            */
  1080. /*   EFFECTS:                                                                 */
  1081. /*                                                                            */
  1082. /*   INTERNAL REFERENCES:                                                     */
  1083. /*      ROUTINES:                                                             */
  1084. /*                                                                            */
  1085. /*   EXTERNAL REFERENCES:                                                     */
  1086. /*      ROUTINES:                                                             */
  1087. /*       DosSleep                                                             */
  1088. /*       WinPostMsg                                                           */
  1089. /*       WinWindowFromID                                                      */
  1090. /*                                                                            */
  1091. /**************************** END OF SPECIFICATIONS ***************************/
  1092.  
  1093. void SetOptions(ULONG item,BOOL option)
  1094. {
  1095.  
  1096.    /* This call may be issued from a non-PM thread. So we have to use Post    */
  1097.    /*   instead of Send. If the Post fails, give the window procedure a       */
  1098.    /*   chance to empty the message queue and try again.                      */
  1099.  
  1100.   while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
  1101.       MM_SETITEMATTR, MPFROM2SHORT(item, TRUE),
  1102.       MPFROM2SHORT(MIA_DISABLED, option? ~MIA_DISABLED:MIA_DISABLED))) {
  1103.     DosSleep(0L);                      /* This give the window thread a chance*/
  1104.                                        /* to run                              */
  1105.   }
  1106. }
  1107.  
  1108.  
  1109. /************************** START OF SPECIFICATIONS ***************************/
  1110. /*                                                                            */
  1111. /*   SUBROUTINE NAME: SetCheckMark                                            */
  1112. /*                                                                            */
  1113. /*   DESCRIPTIVE NAME:                                                        */
  1114. /*               Check/Uncheck menu items.                                    */
  1115. /*                                                                            */
  1116. /*   FUNCTION:                                                                */
  1117. /*               This function is called to place a check mark next to, or    */
  1118. /*               remove a check mark from a particular item in the menu       */
  1119. /*               structure.                                                   */
  1120. /*                                                                            */
  1121. /*   NOTES:                                                                   */
  1122. /*                                                                            */
  1123. /*   ENTRY POINT:                                                             */
  1124. /*      LINKAGE:                                                              */
  1125. /*          void SetCheckMark( ULONG item, BOOL option )                      */
  1126. /*                                                                            */
  1127. /*   INPUT:                                                                   */
  1128. /*       item           - The id of the item to check/uncheck.                */
  1129. /*       option         - TRUE to check the item, FALSE to uncheck.           */
  1130. /*                                                                            */
  1131. /*   EXIT-NORMAL:                                                             */
  1132. /*                                                                            */
  1133. /*   EXIT-ERROR:                                                              */
  1134. /*                                                                            */
  1135. /*   EFFECTS:                                                                 */
  1136. /*                                                                            */
  1137. /*   INTERNAL REFERENCES:                                                     */
  1138. /*      ROUTINES:                                                             */
  1139. /*                                                                            */
  1140. /*   EXTERNAL REFERENCES:                                                     */
  1141. /*      ROUTINES:                                                             */
  1142. /*       DosSleep                                                             */
  1143. /*       WinPostMsg                                                           */
  1144. /*       WinWindowFromID                                                      */
  1145. /**************************** END OF SPECIFICATIONS ***************************/
  1146.  
  1147. void SetCheckMark(ULONG item,BOOL option)
  1148. {
  1149.  
  1150.    /* This call may be issued from a non-PM thread. So we have to use Post    */
  1151.    /*   instead of Send. If the Post fails, give the window procedure a       */
  1152.    /*   chance to empty the message queue and try again.                      */
  1153.  
  1154.   while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
  1155.       MM_SETITEMATTR, MPFROM2SHORT(item, TRUE), MPFROM2SHORT(MIA_CHECKED,
  1156.       option?MIA_CHECKED:~MIA_CHECKED))) {
  1157.     DosSleep(0L);                      /* This give the window thread a chance*/
  1158.                                        /* to run                              */
  1159.   }
  1160. }
  1161.  
  1162. /************************** START OF SPECIFICATIONS ***************************/
  1163. /*                                                                            */
  1164. /*   SUBROUTINE NAME:  SysErrorBoxM                                           */
  1165. /*                                                                            */
  1166. /*   DESCRIPTIVE NAME: System Error Box with Message                          */
  1167. /*                                                                            */
  1168. /*   FUNCTION:                                                                */
  1169. /*               Pop up a window with the error information for a base        */
  1170. /*               system error, along with an added user control.              */
  1171. /*                                                                            */
  1172. /*   NOTES:                                                                   */
  1173. /*                                                                            */
  1174. /*   ENTRY POINT:                                                             */
  1175. /*      LINKAGE:                                                              */
  1176. /*          ULONG  SysErrorBoxM(HWND hwndOwner, ULONG  errorcd,               */
  1177. /*                              PSZ message, ULONG  fsStyle )                 */
  1178. /*                                                                            */
  1179. /*   INPUT:                                                                   */
  1180. /*       hwndOwner  -  Owners window handle                                   */
  1181. /*       errorcd    -  Error code                                             */
  1182. /*       message    -  User provided message                                  */
  1183. /*       fsStyle    -  Style flags                                            */
  1184. /*                                                                            */
  1185. /*   EXIT-NORMAL:                                                             */
  1186. /*       returns ID of button pushed.                                         */
  1187. /*                                                                            */
  1188. /*   EXIT-ERROR:                                                              */
  1189. /*                                                                            */
  1190. /*   EFFECTS:                                                                 */
  1191. /*                                                                            */
  1192. /*   INTERNAL REFERENCES:                                                     */
  1193. /*      ROUTINES:                                                             */
  1194. /*                                                                            */
  1195. /*   EXTERNAL REFERENCES:                                                     */
  1196. /*      ROUTINES:                                                             */
  1197. /*       WinMessageBox                                                        */
  1198. /*       DosGetMessage                                                        */
  1199. /*                                                                            */
  1200. /**************************** END OF SPECIFICATIONS ***************************/
  1201.  
  1202. ULONG  SysErrorBoxM(HWND hwndOwner,ULONG  errorcd,PSZ message,ULONG  fsStyle)
  1203. {
  1204.   CHAR *szErrMsg;                      /* Buffer to hold message returned     */
  1205.   CHAR szErrTitle[80];                 /* Buffer to hold title for message box*/
  1206.   ULONG  cbMsg = ONE_K-1;              /* Length of message buffer            */
  1207.   ULONG  rc;                           /* return code variable                */
  1208.   CHAR *msgfile;                       /* Holds name of message file          */
  1209.   CHAR *errformat;                     /* Holds format string for title       */
  1210.  
  1211.  
  1212.   if (!(szErrMsg = malloc(ONE_K)))
  1213.     return 0;                          /* If we couldn't get space, just      */
  1214.                                        /* return                              */
  1215.   errformat = getstring(SYS_ERROR_TEXT);/* Get the format string for msg      */
  1216.   msgfile = getstring(MSG_FILE);       /* Get name of system message file     */
  1217.   sprintf(szErrTitle, errformat, errorcd);
  1218.  
  1219.                                        /* retrieve message with DosGetMessage */
  1220.   rc = DosGetMessage(NULL,             /* pointer to table of character       */
  1221.                                        /* pointers                            */
  1222.                      0,                /* number of pointers in table         */
  1223.                      szErrMsg,         /* pointer to buffer for return message*/
  1224.                      cbMsg+1,          /* length of buffer                    */
  1225.                      errorcd,          /* message number to retrieve          */
  1226.                      msgfile,          /* name of file containing message     */
  1227.                      &cbMsg);          /* length of returned message          */
  1228.  
  1229.   free(errformat);                     /* release string memory               */
  1230.   free(msgfile);
  1231.   szErrMsg[cbMsg] = '\0';              /* terminate message with a NULL       */
  1232.  
  1233.    /************************************************************************
  1234.    * Since the message returned may have imbedded carraige returns and/or  *
  1235.    * linefeeds we must remove them.                                        *
  1236.    ************************************************************************/
  1237.   while (--cbMsg) {
  1238.  
  1239.     if (szErrMsg[cbMsg] == '\n'|szErrMsg[cbMsg] == '\r') {
  1240.       szErrMsg[cbMsg] = ' ';
  1241.     }
  1242.   }
  1243.                                        /* add "user" message to system one    */
  1244.   if (message) {
  1245.     strcat(szErrMsg, "\n");
  1246.     strcat(szErrMsg, message);
  1247.   }
  1248.                                        /* Pop up a Message box                */
  1249.   rc = WinMessageBox(HWND_DESKTOP, hwndOwner, szErrMsg, szErrTitle, 0, fsStyle);
  1250.  
  1251.    /* Free the message buffer, and return.                                    */
  1252.  
  1253.   free(szErrMsg);
  1254.   return  rc;
  1255. }
  1256.  
  1257. /************************** START OF SPECIFICATIONS ***************************/
  1258. /*                                                                            */
  1259. /*   SUBROUTINE NAME: CuaLogoDlgProc                                          */
  1260. /*                                                                            */
  1261. /*   DESCRIPTIVE NAME: Logo Dialog Procedure                                  */
  1262. /*                                                                            */
  1263. /*   FUNCTION:                                                                */
  1264. /*               This routine is the dialog procedure for diaply of the       */
  1265. /*               About dialog.                                                */
  1266. /*                                                                            */
  1267. /*   NOTES:                                                                   */
  1268. /*                                                                            */
  1269. /*   ENTRY POINT:                                                             */
  1270. /*      LINKAGE: Standard Dialog procedure interface.                         */
  1271. /*                                                                            */
  1272. /*   INPUT: Standard Dialog procedure interface.                              */
  1273. /*                                                                            */
  1274. /*   EXIT-NORMAL:                                                             */
  1275. /*                                                                            */
  1276. /*   EXIT-ERROR:                                                              */
  1277. /*                                                                            */
  1278. /*   EFFECTS:                                                                 */
  1279. /*                                                                            */
  1280. /*   INTERNAL REFERENCES:                                                     */
  1281. /*      ROUTINES:                                                             */
  1282. /*                                                                            */
  1283. /*   EXTERNAL REFERENCES:                                                     */
  1284. /*      ROUTINES:                                                             */
  1285. /*        WinDefDlgProc                                                       */
  1286. /*        WinDismissDlg                                                       */
  1287. /*                                                                            */
  1288. /**************************** END OF SPECIFICATIONS ***************************/
  1289.  
  1290. MRESULT EXPENTRY CuaLogoDlgProc(HWND hdlg, ULONG msg, MPARAM mp1,
  1291.                                MPARAM mp2)
  1292. {
  1293.     switch (msg) {
  1294.       case  WM_COMMAND :
  1295.  
  1296.         if (ID_OK == LOUSHORT(mp1)) {
  1297.           WinDismissDlg(hdlg, TRUE);
  1298.         }
  1299.     }
  1300.     return  WinDefDlgProc(hdlg, msg, mp1, mp2);
  1301. }
  1302.  
  1303. /************************** START OF SPECIFICATIONS ***************************/
  1304. /*                                                                            */
  1305. /*   SUBROUTINE NAME:  SysErrorBox                                            */
  1306. /*                                                                            */
  1307. /*   DESCRIPTIVE NAME: System Error Box                                       */
  1308. /*                                                                            */
  1309. /*   FUNCTION:                                                                */
  1310. /*               Pop up a window with the error information for a base        */
  1311. /*               system error.                                                */
  1312. /*                                                                            */
  1313. /*   NOTES:                                                                   */
  1314. /*                                                                            */
  1315. /*   ENTRY POINT:                                                             */
  1316. /*      LINKAGE:                                                              */
  1317. /*          ULONG  SysErrorBox(HWND hwnd, ULONG  errorcd, PSZ message)        */
  1318. /*                                                                            */
  1319. /*   INPUT:                                                                   */
  1320. /*       hwndOwner  -  Owners window handle                                   */
  1321. /*       errorcd    -  Error code                                             */
  1322. /*       message    -  User provided message                                  */
  1323. /*                                                                            */
  1324. /*   EXIT-NORMAL:                                                             */
  1325. /*                                                                            */
  1326. /*   EXIT-ERROR:                                                              */
  1327. /*                                                                            */
  1328. /*   EFFECTS:                                                                 */
  1329. /*                                                                            */
  1330. /*   INTERNAL REFERENCES:                                                     */
  1331. /*      ROUTINES:                                                             */
  1332. /*                                                                            */
  1333. /*   EXTERNAL REFERENCES:                                                     */
  1334. /*      ROUTINES:                                                             */
  1335. /*       DosSleep                                                             */
  1336. /*       WinPostMsg                                                           */
  1337. /**************************** END OF SPECIFICATIONS ***************************/
  1338.  
  1339. void SysErrorBox(HWND hwnd,ULONG  errorcd,PUCHAR message)
  1340.  
  1341. {
  1342.  
  1343.    /***************************************************************************/
  1344.    /* This call may be issued from a non-PM thread. So we have to use Post    */
  1345.    /*   instead of Send. If the Post fails, give the window procedure a       */
  1346.    /*   chance to empty the message queue and try again.                      */
  1347.    /***************************************************************************/
  1348.  
  1349.   while (!WinPostMsg(hwnd, DOS_ERROR, message,
  1350.        MPFROM2SHORT(errorcd, MB_CANCEL|MB_ICONEXCLAMATION))) {
  1351.     DosSleep(0L);                      /* This give the window thread a chance*/
  1352.                                        /* to run                              */
  1353.   }                                    /* endwhile                            */
  1354. }
  1355.  
  1356. /************************** START OF SPECIFICATIONS ***************************/
  1357. /*                                                                            */
  1358. /*   SUBROUTINE NAME: ProcessSaveQuit                                         */
  1359. /*                                                                            */
  1360. /*   DESCRIPTIVE NAME: Set up call to Save/Quit dialog.                       */
  1361. /*                                                                            */
  1362. /*   FUNCTION:                                                                */
  1363. /*               Checks to see if the output in the MLE has changed since the */
  1364. /*               last save, and if so brings up the Save/Quit dialog.         */
  1365. /*                                                                            */
  1366. /*   NOTES:                                                                   */
  1367. /*                                                                            */
  1368. /*   ENTRY POINT:                                                             */
  1369. /*      LINKAGE: ULONG  ProcessSaveQuit                                       */
  1370. /*                                                                            */
  1371. /*   INPUT:                                                                   */
  1372. /*      HWND hWnd - window handle                                             */
  1373. /*                                                                            */
  1374. /*   EXIT-NORMAL:                                                             */
  1375. /*      Returns TRUE if processed correctly                                   */
  1376. /*                                                                            */
  1377. /*   EXIT-ERROR:                                                              */
  1378. /*      Returns FALSE otherwise                                               */
  1379. /*                                                                            */
  1380. /*   EFFECTS:                                                                 */
  1381. /*                                                                            */
  1382. /*   INTERNAL REFERENCES:                                                     */
  1383. /*      ROUTINES:                                                             */
  1384. /*       SaveQuit - Bring up Save/Quit/Cancel Dialog                          */
  1385. /*                                                                            */
  1386. /*   EXTERNAL REFERENCES:                                                     */
  1387. /*      ROUTINES:                                                             */
  1388. /*       WinDestroyWindow                                                     */
  1389. /*       WinInvalidateRect                                                    */
  1390. /*       WinQueryWindowULong                                                  */
  1391. /*       WinSendMsg                                                           */
  1392. /*       WinWindowFromID                                                      */
  1393. /*                                                                            */
  1394. /**************************** END OF SPECIFICATIONS ***************************/
  1395.  
  1396.   ULONG  ProcessSaveQuit(HWND hwnd)
  1397.   {
  1398.     HWND hEdit;
  1399.     ULONG  usRetVal;
  1400.  
  1401.     hEdit = WinWindowFromID(hwnd, MLE_WNDW);
  1402.  
  1403.     if (WinSendMsg(hEdit, MLM_QUERYCHANGED, NULL, NULL)) {
  1404.       usRetVal = (ULONG )SaveQuit(hab, hwnd, pszFileName);
  1405.     }
  1406.     else {
  1407.       usRetVal = 1;
  1408.     }
  1409.  
  1410.     return (usRetVal);
  1411.   }
  1412.