#	SID	@(#)prog.txt	3.3 - 95/11/10

Introduction


     This chapter deals largely with programming issues in the RAD
     environment.  It assumes an understanding of general
     programming concepts.


SPL Programming


     The Smart Programming Language (SPL) is a sophisticated,
     Pascal-like language.  SPL is a feature of SmartWare; in fact,
     RAD itself is written in SPL.

     SPL provides a structured, procedural means of controlling
     almost every detail of the SmartWare software package.  Any
     action which can be performed directly from SmartWare can
     also be included in an SPL program.  Standard programming
     language features such as function definitions, looping,
     branching, and input/output may be combined in SPL with any
     of the commands found in each of the SmartWare modules.  This
     powerful combination allows you to incorporate all of the high
     level database, spreadsheet, word processor and communication
     features into your programs.  This is a significant departure
     from usual programming concepts; but once mastered, SPL becomes
     an effective systems development tool.

     Functions may also be written in SPL that can be used in
     calculated cells or fields in the spreadsheet and database.  This
     feature adds yet another level of flexibility to the system.

     In general terms, the following list of features is delivered by
     the Programming Language:

          A structured programming language
          Remember mode for beginners
          Global, local and public variables and arrays
          Pointers
          Function libraries
          DOS/Unix compatible code
          Token based compile for fast interpretation
          Easy-to-use editor, help text and compiler
          Debugging tools (trace, quiet mode, single-step)
          Access to hundreds of formulas
          Additions to native SmartWare menus
          KEYS command passing keystrokes directly to
          SmartWare
          Sophisticated error handling
          Text file access, binary data and low level interaction
          Cross platform graphics commands
          SQL access
          DDE access (Windows)

     For complete details on the how to use the programming
     language refer to the Project Processing manual.  For complete
     details on formulas (expressions) and available functions, refer
     to the Formula Reference manual.

     Note: while SPL is not an Object Oriented language, these
     programming techniques can be used through pointers and
     callbacks (see the Sample application).


RAD SPL Programming


     Because so much of a RAD application is generated
     automatically by the Developer System, the role that programs
     play is quite unique.  Programs are usually only used to create
     data processing routines, special commands, complicated
     reports, and customized user interfaces.

     A RAD App automatically handles interaction with the end user,
     taking them through the menu structure as it responds to their
     key strokes.  A large number of actions, such as adding and
     deleting information, queries, graphing, and reports, are also
     handled without the requirement of a program.

     When non-standard functionality is required, a program may be
     executed.  This can be easily done by creating a new command
     with a program executing action or modifying an existing
     command and assigning it a program executing action.

     The standard end user environment can be modified.  The source
     code for functions that draw menus and command lists, and the
     code that responds to user keystrokes is provided in the DEV
     directory.  This will allow you to develop applications with your
     own look-and-feel.

     Almost all of the functions that a RAD App is comprised of are
     available for programmers to use.  Refer to Appendix A in the
     Developer manual for a list of these functions.


Programmer Overview


     This section attempts to deliver a general impression of how a
     RAD application works.

     The Developer and the programs required to run RAD
     applications are written with SPL.  The Developer provides a
     frame work to house the views, programs etc., which make up
     the end application.  A series of menu files define the
     hierarchical structure of the application.  SPL programs
     delivered with SmartWare (installed in
     \ANGOSS\APSYS\SHELL) display the menus in various
     formats and respond to end user input.

     Most activities done with the Developer menu will automatically
     create or modify menus or edit referenced objects such as
     reports, views, programs, etc.


     Creating a New Application

     The Make-Application program creates a directory structure
     containing a base set of data files, menus and programs.  These
     files are copied from the \ANGOSS\APSYS\DEV\EMPTY
     subdirectory.  Scripts to run the application are automatically
     generated.  Under Windows, items are added to the desktop.
     (This is done by using the DDE SPL commands to talk to the
     program manager.)

     The copied files primarily deliver the 'Management and Utilities'
     section of an application.   Briefly, the features already built
     into a RAD application are:

          - User database, for setting up individuals.
          - User mode maintenance for establishing who can
            do what.
          - Activity log for auditing end user activity.
          - File structure maintenance for presenting datafile
            relationships.
          - Information Sets for organizing data access.
          - Language Maintenance for translating applications.
          - Archiving for removing old information from the
            system.
          - Procedures and Job Streams for defining batch
            processing jobs or corporate procedures.
          - Batch Update and Process Log for tracking the
            running of data processing routines.
          - System defaults for defining and changing global
            defaults or preferences.
          - Automatic end user documentation generation,
            which combines the menus, help text, screen shots,
            etc. into a SmartWare WP document.
          - Menu Hierarchy Diagram, which delivers a road
            map spreadsheet of the application.

     The actual compiled SPL programs relating to these features are
     installed in the \ANGOSS\APSYS\SHELL directory and are not
     copied.  The menus and empty data files pertaining to the above
     features are copied.


     Start Up

     To begin loading a RAD application, the project file start.rf3 is
     executed.  If the program is present in the home directory of the
     application, that version is executed.  Otherwise, the version
     provided in the \ANGOSS\APSYS\SHELL directory is used.
     The source, start.pf3, is installed in the
     \ANGOSS\APSYS\DEV directory.

     The startup program performs the following tasks:

          - Sets various public variables.
          - Loads project processing libraries.
          - Loads the dv_info datafile.
          - Executes the login program.
          - Initiates the first menu of the application.


     Running

     Each menu of a RAD application is stored in a separate file in
     the SYSTEM\MENUS subdirectory.  Internally, these menus are
     accessed and maintained by the mnu_ series of functions.  To
     examine the contents of a menu file, use the developer command
     MODIFY MENU EDITOR.

     A stack of menus is maintained while running an application.  It
     can be examined by looking at the public array $$sn[], (menu
     Short Name) - ##lev indicates the current level.

     To load a new menu the function push() is used.  When push is
     run the read_header() function is in turn called which opens the
     menu, reads it into memory, and then closes the file.  The menu
     is also processed.  The processing includes deleting unused
     choices (controlled by usermode maintenance), adjusting colors,
     and adding extensions, such as key fields.  Also, if running the
     application in character mode, the menu is flattened and sorted
     to obtain a command list.

     The push function also:

          - Ensures that the appropriate SmartWare module is
            active
          - Calls module specific loading functions which load
            related, views, documents or spreadsheets.
          - Activates SPL libraries bound to the menu.

     Once the push has completed, the menu is displayed with the
     menu project files (menu1.pf3 to menu6.pf3) or with the
     get_com() function which assumes an active view, document or
     spreadsheet.  Note that source code for displaying menus is
     provided so that developers may modify how a menu looks.

     Once a user selects a choice from a menu it is acted upon by the
     do_choice() function.  (do_choice() is reached by the
     menu("dochoice") call suggested in the documentation for
     previous versions).

     The do_choice() function operates on three key public variables:
     $$act (action),  $$obj (object), and $$fct (function or
     parameters).  These three variables contain all the information
     and/or references required to execute a menu selection.  The
     action indicates what to do and the object indicates who it is
     done to.  For example, if the action is x (meaning eXecute) the
     program specified by the object is run.  If the action is m
     (meaning Menu), the object contains the name of the menu file
     which is to be loaded.  The $$fct variable is a general purpose
     information holder which can affect the execution.  For example,
     the program executed by the x action, can use $$fct to decide
     what it has been called to do.



     Summary

     The intent of the Developer is to make the job of developing
     applications faster and easier.  It provides an excellent
     environment for building applications by:

          - automatically delivering features that are useful in
            real life situations.
          - providing an environment where programmers can
            easily integrate their own programs into the
            application.
          - being flexible enough to accommodate all
            situations.
          - reducing the amount of code that needs to be
            written.



Accessing SmartWare


     Sometimes it may be necessary to move between a RAD
     application and SmartWare.  This can be achieved by invoking
     the Developer System with Ctrl A and then selecting the
     Utilities Database (or other module) commands or by pressing
     the Ctrl Z key combination.

     When using the Ctrl Z combination, a prompt will appear
     asking if you want to Cancel or Suspend execution.  Pressing the
     escape key will ignore the Ctrl Z and program control will
     continue as though the Cancel/Suspend was not invoked.

     Providing that you have remained in the same module, pressing
     F8 will return control to the RAD App place that you were prior
     to suspending.  You should be aware of the consequences of
     certain actions while suspended before pressing the F8 key.  For
     example, if a file is unloaded, it should be reloaded in the
     appropriate window.

     Select Cancel if you want to access the SmartWare Command
     Line options including the Remember Start and Finish
     commands.  Unlike suspend however, you must re-enter the
     application by executing one of two programs: MENU (located
     in the home directory) or RESTART (located in the shell
     directory).  If the cancel occurred in the Database module, you
     can re-enter by executing the MENU SPL program which will
     return you to the Main Menu.  Otherwise, you can re-enter by
     executing the RESTART SPL program which will return you to
     the menu you were on prior to the cancel.

     If a Ctrl Z is issued during a utilities restructure, query, or
     sequential find, then the option to cancel or resume the operation
     will occur.  Selecting Cancel will terminate the process and
     Resume will continue it.  Neither option will pass to control to
     the SmartWare Command Line.

     NOTE: In all cases, if you have moved to a different module
     while at the SmartWare Command Line, you will need to return
     to the database module and execute the START SPL program
     which is usually in the home directory of the system.


     End User Access to SmartWare

     To provide SmartWare access to the end user, insert the
     SUSPEND_APP function into your program.  Refer to Appendix
     A for more information.


Custom Commands


     To create a customized command, select the Developer's Insert
     Program Exit command sequence. This will create an access
     point to an non-audited program.

     While not required, it may be a good idea to enter a value for
     the Function (sometimes called Parameter) in the Insert Execute
     dialog box.  If this function/parameter uniquely identifies the
     menu item, then the program can be called from multiple places
     in the application.  This works because the function/parameter
     value is placed in the $$fct variable which can then be inspected
     in the program with an IF or CASE statement to determine
     which task to invoke.

     To modify the functionality of a standard command such as Enter
     or Update, an SPL program has to be written to handle it and the
     action of the menu item must be changed so that the program is
     run when the user selects the item.  To do this in graphical mode,
     start the Developer, select Modify, select the item and, if
     required, select Item_Information.  In character mode, first
     highlight the item, start the Developer, and select
     Item_Information.  This presents the Menu Information dialog
     box:

          In the Object text box, enter the name of the SPL
          program which is to handle the customized
          functionality.

          In the Action text box, enter or select an x action (the
          execute action).

          In the Function/Parameter text box, enter a unique
          identifier.

     Sometimes it is desirable to modify the Return command so that
     a special task is carried out when the user exits the current
     menu or view.  Do this in the same way as described above but be
     certain that the last line executed by the program reads POP().
     The POP() function returns the user to the previous menu - in
     essence, it adds the RT (return) action to the end of your
     program.

     The following table illustrates the Menu Information
     (description, action, object and function/parameter) of each item
     on a sample customized view menu.  This view menu leaves the
     Browse, Find and Print options unaltered while the Delete,
     Enter, Update and Return commands have been customized as
     described above.


     Sample Customized View Menu - Menu Information

        Description Action Object Function/Parameter

        Browse browse
        Delete x custom delete
        Enter x custom enter
        Find find
        Print m oep
        Update x custom update
        Return x custom return



     The custom.pf3 program handles the four customized
     commands.

          'Program Name: custom.pf3

          EXTERNAL $$fct
          EXTERNAL pop()

          MAIN
           IF $$fct == "delete"
            <commands>
           ELSEIF $$fct == "enter"
            <commands>
           ELSEIF $$fct == "update"
            <commands>
           ELSEIF $$fct == "return"
            <commands>
            pop()
           END IF
          END MAIN



Processing Routines


Audited Programs


     RAD applications have special support for processing routines
     and batch updates.  These types of SPL programs are called
     audited programs.  Any SPL program created in this fashion will
     automatically have the following characteristics:

     *  An input screen with the same name
     *  Job streaming capabilities
     *  Automatic recording in the Process Log
     *  Automatic filing of error/audit report and input screen

     The input screen is provided to allow users to supply
     information to the program.  These are usually parameters that
     specify how the task is to be carried out.

     Each time a user invokes an audited program, the date, time and
     User ID is recorded in the Process Log.  Any errors or other
     types of messages produced by the program are stored in a
     message file for later viewing.  Data entered into the start up
     input screen is also retained, so that it may be reviewed at a
     later time.


     To create an audited SPL program, invoke the Developer and
     select the command sequence Insert Program Audited.  Fill in
     the Insert Audited dialog box text fields and create both the
     program and input screen.


     Input Screen

     The input-screen should contain a brief description of the
     process and should ask the end user any information that is
     required for the program to run correctly.  This information can
     be gathered using the input screen's Table or Input-Item options.
     Store answers in variables.

     For more information on Input Screens, refer to the SmartWare
     Project Processing manual.



     Program

     The Developer automatically generates all the lines of code
     required to handle the Auditing and Job Streaming features.
     Your code should be inserted into this generated program at the
     point indicated by the comment:


          ' ADD PROCESS HERE

     Since this comment is in the middle of the MAIN function, it's a
     good idea to simply declare and define your own main process
     function and call it from there:

          ' ADD PROCESS HERE
           my_function()

     To access variables on the input-screen, they must be declared as
     PUBLIC in the program. To give these variables default values
     or to set them to null strings ("") before the input screen is
     loaded, add the assignments after the following line:

          if $$task=="input" or $$task=="both"

     For example, the variables $input1 and $input2 are assigned null
     values before the input screen is loaded:

          if $$task=="input" or $$task=="both"
           $input1 = ""
           $input2 = ""
           #proc_num=start_aud($inputscr)

     Notice the function named rec_message(1) at the end of the
     program.  Call this function whenever a message should be
     entered into the error/audit report.


     The following example contains a function that validates the
     information on an invoice before it is processed.

        FUNCTION process_invoice()
         IF check_inv()
          ...process invoice
          rec_message( "PROCESSED: Invoice #" & STR(#inv) )
         ELSE
          rec_message( "- Error occurred on: Invoice #" & STR(#inv) )
         END IF
        END FUNCTION

        FUNCTION check_inv()
         DATA GOTO VIEW "customer.vws"
         DATA FIND [Customer #] EQUAL STR([inv.cust]) OPTIONS "g"
         IF [Customer #] <> [inv.cust]
          rec_message( "ERROR: Invalid customer #" & STR([inv.cust] )
          RETURN 0
         END IF
         ...
         RETURN 1
        END FUNCTION


     Messages generated by audited programs can be viewed or
     printed after the routine has finished.  You may access the error
     report at a later date via the Process and Batch Update Log on
     the System Management Menu.


Changing Modules


     If you want to jump outside of the database module during an
     audited project you must take certain steps to ensure proper
     execution.  These steps also ensure that a job stream will
     continue to run.

     In the initial audited project, you must add the following
     external reference:

          EXTERNAL module_call()


     Then, when you want to jump to the other module, insert the
     following line:

          module_call(1,"ssbatch")

     The above example calls the spreadsheet and executes the
     project file "ssbatch.rf1".  For more details on module_call()
     refer to Appendix A.  The following sample project file is
     executed in the destination module.


          EXTERNAL ##mhnd module_call()
          FWRITE ##mhnd FROM "In destination module" ' Write message to log
          module_call(3,"batchret") ' Return to DB

     The module_call() function is executed when execution resumes
     in the database.  The actions performed are the normal actions
     performed when terminating an audited project:

          EXTERNAL $$advr $$clm $$dirsep
          EXTERNAL ##cpstep          ' Current procedure/job stream step #
          EXTERNAL ##mhnd            ' Message file handle
          EXTERNAL ##process_curnum  ' Currently running batch/process #
          EXTERNAL complete_log(2) errorrep(1) get_path()
          PUBLIC rec_message(1)

          MAIN
          LOCAL #proc_num
           #proc_num = ##process_curnum
           rec_message("Now, I've made it back to the DB")
           rec_message("END OF REPORT")
           FCLOSE ##mhnd
           complete_log(#proc_num,"<any comments>")
           IF ##cpstep = 0 ' Job Stream is NOT running
            errorrep(get_path("proclog")|"proclog"|\
                 $$dirsep|str(#proc_num)|".err")
           END IF
           $$clm=str(#proc_num)
           EXECUTE $$advr|"restart" IN-MEMORY
          END MAIN

          FUNCTION rec_message($mess)
             FWRITE ##mhnd FROM $mess
          END FUNCTION


Calling an Application from a Program


     It is possible to execute an application menu selection from
     within a program, just as if a user had actually chosen that item
     from the menu system.  To do this, you must specify the action,
     object and function/parameter values, in the same way that it is
     specified in the menu system (these values can be found on the
     Menu Information dialog box).

     To specify these values, set the public variables $$act, $$obj
     and $$fct to text strings containing the required information and
     invoke the RAD interpreter function, menu().  For example:

          ...
          $$act = "sv"   'Action = spreadsheet view
          $$obj = "disctab"  'Name of SS View = DISCTAB
          $$fct = ""   'No Function needed for an SS View
          menu( "dochoice" ) 'The "dochoice" parameter is needed
          ...

     Notice the syntax of the function call to menu().  The parameter,
     dochoice, is required to instruct RAD to execute the command
     specified by $$act, $$obj and $$fct.  Other parameter settings
     will cause the menu() function to have quite a different effect -
     refer to Appendix A for details.



Libraries



Application Libraries


     The Developer allows you to create libraries of application
     functions which can then be accessed from any of your SPL
     programs.  These functions can also be accessed from within
     calculated fields or cells providing that they do not have any

     module specific commands.  Place all of your library functions
     for each SmartWare module in a separate SPL program named
     applib.rf? or applibhu.rf?, where the ? is the number for the
     resident module.  Declare all functions as PUBLIC in these
     libraries.

     While the reason for two application libraries is originally
     historical, they can be used to help organize functions.

     Each time a module is initiated, the RAD application will check
     to see if the appropriate APPLIB program exists, loads it, and
     makes its public functions available.  Whenever a library is
     loaded, the MAIN section is executed.  You may leave this
     section blank by writing MAIN followed immediately by END
     MAIN.  However, you may choose to place a function here
     which will be called each time that module is initiated.

     Use the Developer's Utilities Remember Application_Library
     command series to modify an application library.

     Notes:

          The copyright message can be changed by setting the
          $$dev_name variable in the application library (You
          must declare the variable as public and issue a
          LOCK-SYSTEM statement on it).

          Any System Default variables used in application
          libraries must be declared as PUBLIC.  This is due to
          the order of initialization process.


Menu Libraries


     Programs can be bound to menus.  A program of this type,
     known as a menu library,  is loaded when the menu is accessed
     and remains loaded until the user backs up from the menu.

     Libraries are bound to menus through the Menu_Characteristics
     dialog box.


Programs On Non Modular Specific Menus


     Some menus do not have a specific module assigned to them.
     These menus show NO CHANGE as the module.  Because any
     module can be active when the menu is displayed, special
     considerations exist when executing programs.

     The x action executes the SPL program in the current module.
     For example, when the spreadsheet module is active, an .rf1 will
     be executed but, when the data base module is active, an .rf3
     will be executed.

     Module specific versions of the x action exist so that a RAD App
     will automatically switch modules when required.  The following
     table shows the module specific execution actions:

          Spreadsheet  x1
          Word Processor  x2
          Database  x3
          Communications  x4


Loading/Unloading Programs


     Occasionally, there is a need to enhance the view loading
     procedures - some applications require a series of spreadsheets
     or documents, others require input from the end-user to
     determine the path or file name of the view.

     For this to work, two areas are affected:

          Program_(Loading/Unloading)

          To create or modify the program, move to the
          navigation menu that calls the view.  In character mode,
          highlight the item that leads to the view, invoke the
          Developer, and issue the command sequence Modify
          Program_(Loading/Unloading).  In graphics mode,
          select the Developer's Modify command, highlight the
          item that leads to the view, and select
          Program_(Loading/Unloading).

          Information Screen

          The above step automatically places the loading
          program's name into the view's Information screen.
          However, to remove a loading program,  go to the
          spreadsheet, document or data view whose loading
          process you wish to remove and modify the view's
          Information screen.  One of the fields on this screen
          specifies the loading/unloading program.  Delete the
          SPL program name of the custom loader from this field.
          Note: this does not delete the program from disk.

     The loading/unloading program is executed when the view is
     invoked.  Note that the standard loading sequence may also be
     executed after the custom loading program is complete.  During
     the loading sequence, the RAD App will set $$fct to "loading"
     before executing the custom loading program.  The program can
     then set the $$fct variable to:

          "abort" The standard load process is not
                    performed.
          "standard" The usual loading process is
                    perfomed when the custom program
                    is done.

     The standard loading procedure will not malfunction if a view
     loaded by the custom program has already been loaded.  Thus
     the custom loading program may be used to override the default
     path settings, located on the dv_info record and in the .ssi and
     .wpi files.

     With spreadsheet and document views, the custom loading
     program can completely override the default files which would
     normally be loaded.  However, when a data view is invoked, the
     view whose name appears on the dv_info record MUST be
     loaded but the normal path may be altered.


     Loading and Unloading Program - Database Example

     The following example simply displays a message before
     performing the usual load procedure.

        EXTERNAL $$fct

        MAIN
         IF $$fct == "loading"
          MESSAGE "Display this message before loading"
          $$fct = "standard"
         ELSEIF $$fct == "unload"
          $$fct = "standard"
         END IF
        END MAIN



Event Handling Functions


     Advanced developers can completely control the application
     screen by attaching an event handling function to a menu.

     An event handling function is called each time a user presses a
     key, uses the mouse or selects a menu item.  The event can be
     ignored, causing the RAD App to behave normally or, the event
     can be handled, allowing the program to produce the desired
     response.

     To attach an event handling function, invoke the developer
     system while running the application at the appropriate menu.
     Select the Modify Menu Characteristics command. Within the
     Menu Information dialogue box, enter a function name in the
     "Event handling function" field.

     Next, create the specified function and ensure that it is active
     when the menu is loaded.  The function can be placed in one of
     the application libraries to make it available at any time. The
     function can also be put in a separate library which can be bound
     to the menu.

     Parameters

     An Event handling function must have the following parameters:

          #key                The event id as
                              returned by
                              INEVENT.

          #mnu                The menu id of
                              the selected
                              choice when #key
                              is {MenuSelect}.

          #choice             The choice
                              number of the
                              selected choice
                              when #key is
                              {MenuSelect}.

          #mode               Will be true. This
                              indicates that the
                              menu is a RAD
                              application menu.

          $data1, $data2      Contains general
                              data about the
                              menu.
                              Application
                              menus do not use
                              these parameters
                              except in the
                              spreadsheet where
                              $data1 is equal to
                              the edit area
                              string.


     Return Value

     An event handling function must return 0, 1 or 2.

          return 0            The RAD App
                              will deal with the
                              event in the usual
                              way.  This is
                              generally used for
                              any event that is
                              not handled in the
                              function.


          return 1            The RAD App
                              will not take
                              further action in
                              response to the
                              event.

          return 2            This special
                              return value tells
                              the RAD App that
                              the current menu
                              is terminating.  It
                              is appropriate to
                              use this return if
                              you have called
                              the push() or
                              pop() functions.

     Events

     Events passed in the #key parameter are keystrokes, mouse
     actions, and menu activities as returned by the INEVENT
     function.  All events can be represented with the {} constants.
     Keystrokes take the form of {F10}, {Space}, {left} {A}, etc.
     Examples of mouse events are {LeftUp}, {MouseMoved}, etc.

     Two menu related events are {MenuInit} and {MenuSelect}.
     {MenuInit} occurs when a menu is initialized and should trigger
     the initial screen paint.  {MenuSelect} occurs when the user has
     selected a command.  In most situations, you will not need to
     intercept {MenuSelect} events. When you do, the #mnu and
     #choice parameters can be used in the mnu_info() function to
     obtain information about the selected menu choice.


     Example

     The following example displays a hello message when F8 is
     pressed and displays "Bye Bye" when  the user exits the menu.


        EXTERNAL display_message() pop()
        PUBLIC eg_event()
        GLOBAL byebye()


        FUNCTION eg_event( #key, #mnu, #choice, #mode, $data1, $data2 )
         IF #key = {F8}
          display_message( "Hello", "", 4 )
          return 1 'AN EVENT WE HAVE HANDLED
         ELSEIF #key={esc} OR #key={f10}
          byebye()
          return 2 'MENU TERMINATING
         ELSEIF #key = {MenuSelect}
          IF mnu_info( #mnu, #choice, 1, 1, MNU_ACT ) == "rt"
           'MENU ITEM WAS RT (RETURN)
           byebye()
           return 2 ' MENU TERMINATING
          END IF
         END IF
         RETURN 0 'AN EVENT WE DON'T CARE ABOUT
        END FUNCTION

        FUNCTION byebye()
         display_message( "Bye Bye", "", 4 )
         pop() 'RETURN TO PREVIOUS APPLICATION MENU
        END FUNCTION



     For a more advanced example refer to the sample application
     shipped with ANGOSS.  The Sales selection uses the
     GRAPHICS commands to paint the screen.  The normal screen
     display and navigation commands are completely replaced.



Navigation Menu Programs


     ANGOSS ships the navigation menu source code so that you can
     customize any of the menu styles (Plain Box, Look Ahead,
     Cascading, etc.) or develop your own.

     To affect all your RAD Apps, install the new menu program(s)
     in the ANGOSS Shell directory.  Alternatively, installing the
     programs in the home directory of the RAD App will affect only
     that application.


     The source code is installed in the ANGOSS DEV directory.
     The file names are:

          menu1.pf3  Plain Box Style menus
          menu2.pf3  Look Ahead menus
          menu3.pf3  Cascading menus
          menu6.pf3  Graphical menus

     Note that a custom program menu5.pf3 can be created.  This
     will allow administrators to easily switch users back to the
     original menu style - the active menu style can be modified by
     usermode (or in the angoss.cfg file).  Menu mode 5 is intended
     for developer customizations.


Running Other Software and Switching Modules


     The ability to store the user's current position within the menu
     structure makes it possible to exit the RAD App altogether, run
     another application, and then return to the exact position within
     the RAD App.

     SmartWare's BIGOS and TOOLS OS commands can be used to
     run a DOS or Unix command while keeping RAD Apps active.



Other Software Packages


     If you need to run a third party application package from within
     your application,
     there are two fundamental approaches.  The fastest and easiest to

     use is the OS window. Or, you can use the RAD App's
     capability to exit completely, run the third party application
     and then reload the application.

     OS Window

     An OS window can be invoked through OS_Call or by the
     BIGOS command in SPL.  Unfortunately, depending on your
     memory mode, you can not always guarantee that there will be
     enough memory.  Under Unix, the OS window is the preferred
     choice.

     In Windows, BIGOS opens a DOS box - to create a Windows
     process, use the SPL function, PROCESS_CREATE.

     In DOS, the BIG OS command will free as much low memory as
     possible by writing it out to disk before shelling out.  Under
     tight memory configuration, this command may be
     problematic.

     Temporary Exit - DOS Only

     As an alternative to the DOS window, you can temporarily leave
     the RAD App, run the desired application and then return.  This
     approach is slow, but will guarantee that you have enough
     memory and called programs can use expanded and extended
     memory.

     The temp_exit() function allows you to easily exit and re-enter
     the application.  This function actually calls another function
     that saves the end-users position within the application, and
     sets a reentry flag.  Note that the ANGIIUSR environment variable
     must specify the user's ID.

     The temp_exit() function executes a script file named osapl.bat,
     which must be located in the user's work directory.  This batch
     file is responsible for starting the external application, as it
     would be started from the DOS prompt.


     One method of invoking a batch file is to copy the file to
     osapl.bat prior to calling temp_exit().  The example presented
     below uses this method to invoke a CAD/CAM software
     package:

          TOOLS FILE COPY "cadcam.bat" TO $$workdir|"osapl.bat"
          temp_exit()


     If the script needs to vary according to the current record or
     other variables, you can use the FWRITE statement to actually
     create each line of the script file before calling exit function.
     The following example creates a batch file containing the single
     line, dispdiag -X, where X is a parameter which specifies a
     hypothetical subassembly identification code:

          FOPEN $$workdir|"osapl.bat" AS ##wrkhnd OPTIONS RW_MODE
          FSEEK ##wrkhnd 0
          FWRITE ##wrkhnd FROM "dispdiag -"|[Subassembly ID]
          FCLOSE ##wrkhnd
          temp_exit()

     The exit function sets a flag, and then returns control to the
     operating system.  Here, the start-up batch file, which is used
     to start the application, continues to execute where it left off
     when the RAD App took control.  It is this batch file which
     handles the details of running the osapl.bat file, as well as,
     returning control to the RAD App when the external application
     terminates.  RAD Apps automatically detect the presence of the
     files which store the location information and uses them to
     return the user to the location from which the external
     application was called.


Changing Modules


     If it is necessary that a different SmartWare module be invoked
     from within a project file, use the module_call() function.  The
     following example assumes that you are moving from the
     database to the spreadsheet.

          EXTERNAL module_call()

          module_call( 1, "readgraf" )

     The first parameter in module_call is the module number
     (1=spreadsheet, 2=word processor, 3=data base,
     4=communications).  The second parameter is the project file to
     execute in the destination module.


     The SEND command may also be used.  For example:

          EXTERNAL module_call()
          EXTERNAL $$advr

          module_call( -1, "readgraf" )
          DATA SEND SPREADSHEET ROW-FORMAT "[f001;f002]" \
           PROJECT-FILE $$advr|"ppmodch.rf3"


     Note that the module number -1 tells the module_call function to
     suppress the module change.  Also note that the SPL program
     ppmodch.rf3 is executed, which will in turn execute readgraf.

     Function libraries will be automatically activated in the
     destination module.  You may call an application menu if
     required.  For example:

          menu_call( "summary" )

     The above command will load the "summary" menu, where the
     end user can carry on with application activity.  This sequence
     may be used to allow an end user to view data that was just sent
     to the spreadsheet.  For more information refer to the
     menu_call() function listed in Appendix A.

     When you want to return to the original module, use the
     module_return() function.  For example:

          EXTERNAL module_return()
          module_return()

     This command will cause the original module to be invoked.

     Note: If changing modules during a processing routine, special
     steps must be taken.  Refer to the section titled "Changing
     Modules During a Processing Routine" for details.


Customizing Login and Start Programs


     The source code files for the LOGIN and START programs are
     included in the Developer System directory.  These may be
     altered in order to customize the start up or login process.  If
     files by these names are found by the RAD App in the home
     directory of the application, they will be executed in place of
     versions found in the Shell directory ($$advr).  Copy one or both
     of these files into the home directory and then modify the copies,
     if you intend to customize these processes.

     WARNING: Customizing the START and LOAD SPL
     programs could make upgrading to a new version of RAD a
     difficult process.


Passwords on Data Files


     It is a common requirement to allow access to files only when
     running an application.

     Under normal circumstances, a knowledgeable end user can start
     the database and manually load application data files, thus
     by-passing the security and protection of the application.  In
     many situations, this is not a problem.

     To stop uncontrolled access to files, you can attach passwords to
     them.  The application can be programmed to invisibly supply
     the password when required.

     Custom-views, data files, documents and worksheets can all
     have passwords attached to them.  Usually, when a file has a
     password, the data is also encrypted.

     To use a password protection scheme, attach passwords to the
     files and create a function in your application library which
     perform all file loading and supply the required passwords.



     Attaching Passwords

     To attach a password, follow these steps:

          Load the view

          If you are running the application, access the
          SmartWare module with the Developer's Utilities
          command.

          Use the File Password command and attach a new
          password.


     Alternatively, for data files and views, use the File Structure
     Maintenance, Tools, Password command.

     In the database, you can attach passwords to custom views,
     standard views and data files. For maximum security, protect
     each one. If you attach a password to a data file, you may decide
     to encrypt the data.


     Programming the Application to Supply Passwords

     Once passwords have been attached, the application must be
     modified.  A function in the application library will be called
     each time a file is loaded.  It is the responsibility of this
     function to load the file and, if appropriate, use the Keys
     command to supply the password.

     To install this change, follow these steps.

          Access the application library, through the Developer.

          Read in the password code segment provided in the
          DEV directory (For example, in the program editor: Alt
          F3, \angoss\apsys\dev\password.pf3). If you already
          have functions in the library, rearrange the code that
          was read in.

          Next, customize the new loading function to calculate
          the appropriate passwords and make any other
          customizations.



