home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PASCAL / PULL70.ZIP / PULL70.DOC < prev    next >
Text File  |  1993-06-21  |  182KB  |  4,492 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.                            MULTI-LEVEL PULL-DOWN MENUS
  19.                                   USER'S GUIDE
  20.  
  21.                                    Version 7.0
  22.                                   June 21, 1993
  23.  
  24.  
  25.                Copyright (C) 1988,1993 Eagle Performance Software
  26.                               All Rights Reserved.
  27.  
  28.  
  29.  
  30.                                _______                     
  31.                           ____|__     |               (tm) 
  32.                        --|       |    |------------------- 
  33.                          |   ____|__  |  Association of    
  34.                          |  |       |_|  Shareware         
  35.                          |__|   o   |    Professionals     
  36.                        -----|   |   |--------------------- 
  37.                             |___|___|    MEMBER            
  38.  
  39.  
  40.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  41.  
  42.  
  43.  
  44.                        T A B L E   O F   C O N T E N T S
  45.  
  46.         1. INTRODUCTION  . . . . . . . . . . . . . . . . . . . . . 4
  47.              Features .  . . . . . . . . . . . . . . . . . . . . . 4
  48.              Using the Manuals . . . . . . . . . . . . . . . . . . 4
  49.              Licensing . . . . . . . . . . . . . . . . . . . . . . 5
  50.              Customer Service  . . . . . . . . . . . . . . . . . . 5
  51.              ASP . . . . . . . . . . . . . . . . . . . . . . . . . 6
  52.  
  53.         2. GETTING STARTED . . . . . . . . . . . . . . . . . . . . 7
  54.              Distribution Files  . . . . . . . . . . . . . . . . . 7
  55.              Demonstration . . . . . . . . . . . . . . . . . . . . 7
  56.  
  57.         3. PROGRAMMING MENUS . . . . . . . . . . . . . . . . . . . 11
  58.              Using the Shell . . . . . . . . . . . . . . . . . . . 11
  59.              Menu Modes  . . . . . . . . . . . . . . . . . . . . . 11
  60.              Line Modes  . . . . . . . . . . . . . . . . . . . . . 14
  61.              HiLite Control  . . . . . . . . . . . . . . . . . . . 16
  62.              Adding Lines  . . . . . . . . . . . . . . . . . . . . 16
  63.              Adding Menus  . . . . . . . . . . . . . . . . . . . . 17
  64.              Adding Submenus . . . . . . . . . . . . . . . . . . . 18
  65.              Help Messages . . . . . . . . . . . . . . . . . . . . 20
  66.              Help Windows  . . . . . . . . . . . . . . . . . . . . 21
  67.              Default Attributes  . . . . . . . . . . . . . . . . . 23
  68.              Standard Borders  . . . . . . . . . . . . . . . . . . 24
  69.              Control Flags . . . . . . . . . . . . . . . . . . . . 25
  70.              Summary . . . . . . . . . . . . . . . . . . . . . . . 27
  71.  
  72.         4. SCREEN DESIGN . . . . . . . . . . . . . . . . . . . . . 28
  73.              Title Line  . . . . . . . . . . . . . . . . . . . . . 28
  74.              Top Line Menu . . . . . . . . . . . . . . . . . . . . 28
  75.              Main Menu Row . . . . . . . . . . . . . . . . . . . . 28
  76.              Submenu Row . . . . . . . . . . . . . . . . . . . . . 29
  77.              Work Windows  . . . . . . . . . . . . . . . . . . . . 29
  78.              Message Line  . . . . . . . . . . . . . . . . . . . . 29
  79.              Help Windows  . . . . . . . . . . . . . . . . . . . . 30
  80.              Start-Up Menu . . . . . . . . . . . . . . . . . . . . 30
  81.              Overriding Defaults . . . . . . . . . . . . . . . . . 31
  82.              Summary . . . . . . . . . . . . . . . . . . . . . . . 32
  83.  
  84.         5. DATA WINDOWS  . . . . . . . . . . . . . . . . . . . . . 33
  85.              Data Window Parts . . . . . . . . . . . . . . . . . . 33
  86.              Data Window Record  . . . . . . . . . . . . . . . . . 33
  87.              Data Window Variable  . . . . . . . . . . . . . . . . 34
  88.              Fields  . . . . . . . . . . . . . . . . . . . . . . . 35
  89.              Titles  . . . . . . . . . . . . . . . . . . . . . . . 36
  90.              Editing Keys  . . . . . . . . . . . . . . . . . . . . 37
  91.              Key Sets  . . . . . . . . . . . . . . . . . . . . . . 38
  92.              Key Translation . . . . . . . . . . . . . . . . . . . 38
  93.              Range Checking  . . . . . . . . . . . . . . . . . . . 39
  94.              Help Messages . . . . . . . . . . . . . . . . . . . . 41
  95.              Help Windows  . . . . . . . . . . . . . . . . . . . . 41
  96.              Default Attributes and Border . . . . . . . . . . . . 41
  97.              Default Location  . . . . . . . . . . . . . . . . . . 42
  98.  
  99.  
  100.                                        2
  101.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  102.  
  103.  
  104.              Summary . . . . . . . . . . . . . . . . . . . . . . . 42
  105.  
  106.         6. DATA ENTRY  . . . . . . . . . . . . . . . . . . . . . . 43
  107.              Data Entry vs. Data Windows . . . . . . . . . . . . . 43
  108.              Data Entry Record . . . . . . . . . . . . . . . . . . 43
  109.              Adding Entries  . . . . . . . . . . . . . . . . . . . 44
  110.              Displaying Fields . . . . . . . . . . . . . . . . . . 44
  111.              Sequential Entry  . . . . . . . . . . . . . . . . . . 45
  112.              Edit Mode . . . . . . . . . . . . . . . . . . . . . . 47
  113.              Field Attributes  . . . . . . . . . . . . . . . . . . 48
  114.              Single Entry  . . . . . . . . . . . . . . . . . . . . 48
  115.              Summary . . . . . . . . . . . . . . . . . . . . . . . 48
  116.  
  117.         7. WORK WINDOWS  . . . . . . . . . . . . . . . . . . . . . 49
  118.              Making Steps  . . . . . . . . . . . . . . . . . . . . 49
  119.              Reading the Keyboard  . . . . . . . . . . . . . . . . 50
  120.              Multi-Level Windows . . . . . . . . . . . . . . . . . 52
  121.              Managing Winddows . . . . . . . . . . . . . . . . . . 53
  122.  
  123.         8. USER WINDOWS  . . . . . . . . . . . . . . . . . . . . . 55
  124.              Pull-Down Directory . . . . . . . . . . . . . . . . . 55
  125.              Interface . . . . . . . . . . . . . . . . . . . . . . 56
  126.  
  127.         9. CONDITIONAL COMPILATION . . . . . . . . . . . . . . . . 58
  128.              Define Symbols  . . . . . . . . . . . . . . . . . . . 58
  129.              Recompiling . . . . . . . . . . . . . . . . . . . . . 58
  130.  
  131.        10. TROUBLE SHOOTING  . . . . . . . . . . . . . . . . . . . 59
  132.              Goof Unit . . . . . . . . . . . . . . . . . . . . . . 59
  133.              Far Addresses . . . . . . . . . . . . . . . . . . . . 59
  134.              Multi-tasking . . . . . . . . . . . . . . . . . . . . 60
  135.              Customer Service  . . . . . . . . . . . . . . . . . . 60
  136.  
  137.         APPENDIX A: Other Products . . . . . . . . . . . . . . . . 61
  138.  
  139.         APPENDIX B: Revision History . . . . . . . . . . . . . . . 71
  140.  
  141.         APPENDIX C: Credits  . . . . . . . . . . . . . . . . . . . 73
  142.  
  143.         APPENDIX D: Glossary . . . . . . . . . . . . . . . . . . . 74
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.                                        3
  162.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  163.  
  164.  
  165.    1.  I N T R O D U C T I O N
  166.  
  167.  
  168.    FEATURES
  169.  
  170.    Welcome to PULL multi-level pull-down menus!
  171.  
  172.    You have just obtained a copy of the highest performance pull-down menu 
  173.    utilities available today for Borland Pascal 7.0 (BP7).  Both novice and 
  174.    professional programmers will appreciate these simple and very powerful 
  175.    utilities that are fully featured and fully configurable.  PULL is ideal 
  176.    for projects that need to be small in size.  It works on any all IBM 
  177.    compatibles, including PS/2 and 3270 PC on any video page or any text mode.  
  178.  
  179.    Here are some of the features you will discover:
  180.  
  181.      - Uses the powerful routines of QWIK and WNDW.
  182.      - Works in DOS or DPMI.
  183.      - Work window(s) and complete interface for menus
  184.      - Pull-down menus with 3 menu modes and 8 line modes
  185.      - Pull-down file directory
  186.      - Highlighted command letters
  187.      - Unlimited levels of submenus
  188.      - Unlimited data entry windows for 9 types of data
  189.      - Data entry for the work window(s)
  190.          Free field entry with either fixed column or flexible   
  191.          column length.
  192.          Full editing capability including insert cursor mode
  193.          Fields are easily selected with the cursor keys
  194.          Automatic NumLock for numerical data entry
  195.          Right or left justification for data entry output
  196.          Error messages for invalid data entries
  197.          Error messages for data entries out of range
  198.      - Automatic sizes and locations for menus 
  199.      - Operation by cursor keys or command keys
  200.      - Pull/Pop between work window and nested submenu(s)
  201.      - Programmable control of pull and pop sequences
  202.      - Context-sensitive help windows
  203.      - Message lines for prompts and processing
  204.      - Writes direct to multi-tasking video buffers (MTVB).
  205.      - Full working shell for user development
  206.  
  207.    PULL has been designed with a fill-in-the-blank concept.  To get your 
  208.    application up and running, you only need to fill in the appropriate 
  209.    records or variables.
  210.  
  211.    BP7 - The units provided in this distributed file only work under Borland 
  212.    Pascal real mode.  However, the source code, provided with registration, 
  213.    also compiles and operates for the DPMI platform.
  214.  
  215.  
  216.    USING THE MANUALS
  217.  
  218.    Disk Based Guides - The manuals for PULL are on disk so that you can 
  219.    conveniently scan for the topic you are seeking.  You can do this with any 
  220.  
  221.  
  222.    Chapter 1, Introduction                                             Page 4
  223.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  224.  
  225.  
  226.    list or search utility with a search function.  You can also make a printed 
  227.    copy.  If you have not already printed this manual, refer to the READ.ME 
  228.    file for instructions.  At the present time, no bound manuals are being 
  229.    offered with registration.
  230.  
  231.    User's Guide - This manual, the one your are reading now, assumes that as a 
  232.    programmer you are already familiar with Borland Pascal 7.0, and that you 
  233.    have a working knowledge of your disk operating system (DOS).  It also 
  234.    assumes that you are familiar with QWIK screen utilities in QWIK71.ZIP and 
  235.    WNDW70A.ZIP.  This manual will provide the basic instructions for creating 
  236.    and managing multi-level pull-down menus.  It also contains a tutorial to 
  237.    guide you step-by-step to create your own application.
  238.  
  239.    Reference Guide - This manual describes in detail all procedures, functions 
  240.    and variables used in PULL.  It is a alphabetically arranged for easy 
  241.    access in a format similar to the Borland reference manuals.  Use this 
  242.    manual when you have become familiar with the basic principles in the 
  243.    User's guide.
  244.  
  245.  
  246.    LICENSING
  247.  
  248.    Registration - These routines and the documentation have been released for 
  249.    distribution as Shareware.  You have been given the chance to sample the 
  250.    full capability of WNDW without risk!  If you find that WNDW is a valuable 
  251.    tool, then you are expected to register.  You will find a reasonable 
  252.    licensing schedule found in LICENSE.ZIP to meet private or commercial 
  253.    needs.  When registering, be sure to specify the version for Borland Pascal    
  254.    (such as TP6 or BP7) you wish to receive.  Please specify your disk size as 
  255.    well.
  256.  
  257.    Source Code - All registered users will receive source code when the signed 
  258.    license agreement is returned with the registration.  All source code 
  259.    compiles under BP7 as well as TP7.  The compiled units in the distributed 
  260.    file were compiled with TP/BP7 and only work under this version.
  261.  
  262.  
  263.    CUSTOMER SERVICE
  264.    If you have questions, comments, or suggestions, the Eagle can be contacted 
  265.    by four means - (1) CompuServe, (2) telephone, (3) The Eagle BBS, or 
  266.    (4) mail.
  267.  
  268.    CompuServe - The most dependable way to contact the Eagle is through Compu-
  269.    Serve.  James (Jim) H. LeMay has written the BP7 version of PULL and can be 
  270.    contacted using CIS mail with the CIS ID of 76011,217.
  271.  
  272.    Telephone - Jim can also be reached by phone at (817) 735-4833 on weekdays 
  273.    from 9:00 a.m. to 5:00 p.m CST.
  274.  
  275.    The Eagle BBS - You can also contact us on our 24-hour BBS at (214) 539- 
  276.    9878, Intel 1200/2400/9600/14400 N81 V.42 MNP5.
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.    Chapter 1, Introduction                                             Page 5
  284.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  285.  
  286.  
  287.    Mail - For registration or problems, please write:
  288.  
  289.        Eagle Performance Software
  290.        6341 Klamath Road
  291.        Ft. Worth, TX 76116-1617
  292.  
  293.    In your written request for resolving problems, be sure to include:
  294.  
  295.      . A diskette with compilable source code of the problem.
  296.      . The Eagle product and version number.
  297.      . The computer make and model.
  298.      . The type of video card, video monitor and keyboard.
  299.  
  300.  
  301.    ASP
  302.  
  303.    PULL is a Shareware program conforming to the standards of the Association 
  304.    of Shareware Professionals (ASP).  You can get more information about ASP 
  305.    by writing to:
  306.     
  307.      Association of Shareware Professionals
  308.      P.O. Box 5786
  309.      Bellevue,WA 98006
  310.  
  311.    This program is produced by a member of the Association of Shareware 
  312.    Professionals (ASP).  ASP wants to make sure that the shareware principle 
  313.    works for you.  If you are unable to resolve a shareware-related problem 
  314.    with an ASP member by contacting the member directly, ASP may be able to 
  315.    help.  The ASP Ombudsman can help you resolve a dispute or problem with an 
  316.    ASP member, but does not provide technical support for member's products.  
  317.    Please werite to:
  318.  
  319.      ASP Ombudsman
  320.      P.O. Box 5786
  321.      Bellevue, WA  98006
  322.  
  323.   or send a CompuServe message via EasyPlex to ASP Ombudsman 70007,3536.
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.    Chapter 1, Introduction                                             Page 6
  345.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  346.  
  347.  
  348.    2.  G E T T I N G   S T A R T E D
  349.  
  350.    This section will acquaint you with the files on distribution disk and show 
  351.    you a couple of demonstrations to quickly see what PULL can accomplish.
  352.  
  353.  
  354.    DISTRIBUTION FILES
  355.  
  356.    In this version, PULL70.ZIP contains:
  357.  
  358.      Read    .me:   Note of printing instructions for manual.
  359.      Pull70  .doc:  This document - a user's guide to PULL.
  360.      PullRef .doc:  PULL Reference Guide document covering each 
  361.                     routine and variable in detail.
  362.      Pull70  .tpu:  This unit has the full power of all of its 
  363.                     capabilities.  Please note that because PULL70.TPU 
  364.                     uses P70-VAR.INC all constants have been assigned.  
  365.                     In order to make any changes in the data 
  366.                     requirements, the complete source code will be 
  367.                     required. 
  368.      Pull70- .pas:  Shows the interface portion of PULL70.
  369.      P70-var .inc:  This file is the actual source code which lists 
  370.                     all of the types, constants, and variables used 
  371.                     for PULL70.TPU.
  372.      PullDefs.inc:  Global include file of conditional defines.
  373.      PullDemo.pas:  Fully functional working demo.
  374.      PullWork.pas:  Procedures for the main work window(s).
  375.      PullStat.pas:  Stats to configure the menus including global 
  376.                     keys.
  377.      PullData.pas:  Data to configure data entry windows and fields.
  378.      PullDir-.pas:  Just interface for PULLDIR.PAS. 
  379.      PullDir .tpu:  Unit for a pull-down file directory.
  380.      PullShel.zip:  Contains shell files to develop your own 
  381.                     application.
  382.      Qwik71  .tpu:  Unit for quick screen writing.
  383.      Strs    .pas:  Unit from QWIK71 for number-to-string conversions.
  384.      Wndw70a .tpu:  Multi-level virtual window unit for PULL.TPU.
  385.      Wutil   .tpu:  Independent utilities unit used in WNDW.TPU.
  386.      Goof    .pas:  Unit to display errors.
  387.      License .zip:  Compressed file containing license agreement and 
  388.                     ordering details.
  389.  
  390.  
  391.    DEMONSTRATION
  392.  
  393.    To get the feeling of the speed and features of PULL, let's run the 
  394.    demonstration program that comes with the utilities.  Do the following 
  395.    steps:
  396.  
  397.      1. Copy QWIK71.TPU to QWIK.TPU.  
  398.      2. Copy WNDW70A.TPU to WNDW.TPU. 
  399.      3. Copy PULL70.TPU to PULL.TPU.
  400.      4. Make, compile and run PULLDEMO.PAS.  (If you get an ERROR 
  401.         15 or 70, then steps 1-3 was not done carefully.)
  402.      5. Follow along in the overview below.
  403.  
  404.  
  405.    Chapter 2, Getting Started                                          Page 7
  406.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  407.  
  408.  
  409.  
  410.    Familiar Environment - You will probably feel right at home with the 
  411.    environment created with PULL as it appears very similar to the IDE.  
  412.    It is interesting to note that PULL was developed with TP3 before TP4 was 
  413.    ever released with an environment.  However, you should find the operation 
  414.    quite similar.  While you are running the demo, let's get familiar with the 
  415.    format and operation of the environment and follow along with this 
  416.    overview:
  417.  
  418.      . Title Line - Row 1 just holds the title of this program.  It is 
  419.        optional.
  420.  
  421.      . Top Line Menu - Row2 has been optionally assigned to be the top 
  422.        line menu.  Press F10 at any time to access it.
  423.  
  424.      . Work Window - For this demo, Rows 4 to 23 has a 20x78 window for 
  425.        the major part of your input/output.  You can also have multi-
  426.        level work windows.
  427.  
  428.      . Main Menu - To access a main menu, press RETURN or a command 
  429.        letter (LTR) while the top line menu is highlighted on any 
  430.        selection.  Or, you can use a combination of the ALT key and a 
  431.        letter, such as Alt-F to get to the File menu.
  432.  
  433.      . Submenu - A submenu is a menu under a Main Menu.  To access a 
  434.        submenu, press RETURN when the HiLite is at a menu line with the 
  435.        solid triangle symbol.  You can see three levels of menus by 
  436.        pressing Alt-A/Tires/Brands.
  437.  
  438.    Local Keys and Letter Commands - While a window is shown, several keys 
  439.    operate for just that window.  These keys can be listed in the message line 
  440.    or they can be assumed to be the command letters highlighted on each menu 
  441.    line.
  442.  
  443.      . Help Windows (F1) - While the Brands menu is still showing, 
  444.        press F1 to get context-sensitive help.  A help window is 
  445.        assigned to every window and menu.
  446.  
  447.      . Keys on Message Line - The bottom line of the CRT, being closest 
  448.        to the keyboard, indicates the available keys that can be used 
  449.        for the current context.  It is also used for help or error 
  450.        messages.  While the help window is displayed, the next key 
  451.        pressed will also pass through as a command.  For instance, press 
  452.        RETURN now and see the help window removed and Firestone will 
  453.        also become flagged.
  454.  
  455.      . Pop and Pull (F2) - F2 is a pop-and-pull key that toggles between 
  456.        the pull-down menus and the work window.  Press F2 twice and you 
  457.        will see that it remembers the last menu that was pulled.
  458.  
  459.      . Command Letters (LTR) - If you wanted to select WeatherGuard on 
  460.        the Brands menu, just type the letter "W" which is highlighted.  
  461.        These letters will work in any menu.
  462.  
  463.      . Cursor Keys - All of the cursor keys like the arrows, Home and 
  464.  
  465.  
  466.    Chapter 2, Getting Started                                          Page 8
  467.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  468.  
  469.  
  470.        End keys, have assigned functions as well as the control-shifted 
  471.        cursor keys.  You can discover what they do by experimenting with 
  472.        them in a menu.
  473.  
  474.      . ESC Key - The ESC key always backs out of the current menu/window.
  475.  
  476.    Global Keys - Extended key combinations can be used to access any part of 
  477.    the program.  In this demo, some have been assigned with the ALT key.  
  478.    Press down ALT for a half second and see the available global keys listed 
  479.    on the message line.
  480.  
  481.      . Directory (Alt-D) - Press Alt-D now to get a directory of your 
  482.        disk.  If you would like to continue testing the directory, press 
  483.        F1 for instructions.
  484.  
  485.      . Exit (Alt-X) -  To exit the program, one alternative is to use 
  486.        Alt-X, but don't do it now.
  487.  
  488.      . Top Line Menu (F10) - As mentioned before, to get to the top line 
  489.        menu, press F10 at any time.
  490.  
  491.    Data Entry Windows - Each menu can additionally pull down a data entry 
  492.    window which is indicated with an ellipsis (...) symbol on the menu line.  
  493.    These windows are fully configurable and have full editing capability.  
  494.    They have a free-field entry concept where a entire string is typed and 
  495.    edited before entering.  Let's try a few fields.
  496.  
  497.      . Data Entry Types - Press Alt-E to see a menu of all the data 
  498.        entry types available.  Press RETURN when the HiLite is at a menu 
  499.        line with an ellipsis (...) symbol.  Pressing RETURN again will 
  500.        exit the window entering the data shown.  You can clear any data 
  501.        entered by pressing ESC which also removes the window.
  502.  
  503.      . Editing - Press "I" while the main menu is still shown and enter 
  504.        a value for the integer.  The virgin entry is highlighted until 
  505.        you press a key.  If you press Delete at this point, the entire 
  506.        entry will be cleared.  The entry has full edit capability using 
  507.        the cursor keys and some familiar WordStar control keys.  Press 
  508.        F1 for a list.  Even the insert mode is indicated with a half-
  509.        block cursor.
  510.  
  511.      . Options - All sorts of options are available for these windows 
  512.        including range checking, fixed and flex fields, character 
  513.        control and translation, automatic NumLock, justification, 
  514.        titles, and attributes.
  515.  
  516.    Work Window Data Entry - The same procedures used for the data entry 
  517.    windows can be used for entering data in the work windows.  In addition, 
  518.    PULL has a smart algorithm that knows where several fields are on the 
  519.    screen.  So moving from field to field with all the cursor keys is 
  520.    intuitive.
  521.  
  522.      . Moving the HiLite - Press F2 to get back to the work window with 
  523.        all of the data entry fields.  One field will be highlighted 
  524.        which means it can be moved to select another field.  All of the 
  525.  
  526.  
  527.    Chapter 2, Getting Started                                          Page 9
  528.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  529.  
  530.  
  531.        cursor keys move the HiLite including the control-shifted keys 
  532.        and the Tab and Shift-Tab keys.  Move the HiLite to the Integer 
  533.        field.
  534.  
  535.      . New Values - To enter a new value for the integer, simply start 
  536.        typing some numbers and the HiLite will change colors.  You can 
  537.        see that only numbers and the sign can be entered.  Press RETURN 
  538.        to enter the new value or press ESC to restore the old value.  
  539.  
  540.      . Editing - To edit the value currently shown in a field, press 
  541.        RETURN or any WordStar control key.
  542.  
  543.    Other Features - There are many other features in the menus which will be 
  544.    covered later including menu and line modes, and direct menu control.  You 
  545.    may continue to discover other features in the demo if you want.  When 
  546.    finished, press Alt-X to quit.
  547.  
  548.    Multi-tasking - This demo is already set to work in multi-tasking 
  549.    environments compatible to DESQview, TaskView, and IBM 3270 PC.
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.    Chapter 2, Getting Started                                          Page 10
  589.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  590.  
  591.  
  592.    3.  P R O G R A M M I N G   M E N U S
  593.  
  594.    This section will get you familiar with the basics of window programming 
  595.    by starting with very basic menus and then taking you step-by-step through 
  596.    the full variety of options and modes available.
  597.  
  598.  
  599.    USING THE SHELL
  600.  
  601.    Shell Program - Let's experiment will PULL by developing our own 
  602.    application to see how powerful it can be.  A shell program, which is a 
  603.    bare bones application, has been provided with PULL in the file 
  604.    PULLSHEL.ZIP.  These files will help you get started for any application.  
  605.    But for now, it can be an excellent learning tool.  To keep these files 
  606.    separate from the PULLDEMO files, create another working directory and 
  607.    unarchive the files in PULLSHEL.ZIP.  The files to be extracted are:
  608.  
  609.      PullShel.pas
  610.      PullData.pas
  611.      PullStat.pas
  612.      PullWork.pas
  613.      PullDefs.inc
  614.  
  615.    In addition, the follow files need to be on you unit path or copied into 
  616.    the same directory:
  617.  
  618.      Qwik.tpu
  619.      Wndw.tpu
  620.      Wutil.tpu
  621.      Strs.pas
  622.      Pull.tpu
  623.      Goof.pas
  624.  
  625.    Running the Shell - To make sure we have everything available, load 
  626.    PULLSHEL.PAS, make, and run the program.  You should be able to operate 
  627.    this program the same as PULLDEMO.PAS.  There are only two menus - First 
  628.    and Quit.  To Quit, you can either use the Quit menu or use the global key 
  629.    Alt-X.
  630.  
  631.    Features Available - The shell has every feature available.  They can be 
  632.    added or eliminated.  However, some code cannot be entirely eliminated or 
  633.    altered unless you are registered with the source code.  But let's continue 
  634.    to see what the program can really do.
  635.  
  636.      
  637.    MENU MODES
  638.  
  639.    In this section, we will delve right into the menus and see how they 
  640.    function and what changes can be made.  PULL has three menu modes for every 
  641.    menu - ExecChoice, SingleChoice, and MultipleChoice.  These modes determine 
  642.    how all the lines in the menu can interact as a whole.
  643.  
  644.    SingleChoice - You probably noticed that the First menu had one flag on it 
  645.    because it was a SingleChoice menu.  One and only one item could be flagged 
  646.    by pressing return on any one line.  Let's examine the data record of menu 
  647.  
  648.  
  649.    Chapter 3, Programming Menus                                        Page 11
  650.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  651.  
  652.  
  653.    and see how it was made to be single choice.
  654.  
  655.      1. Load the file PULLSTAT.PAS into the TP editor.
  656.      2. Set PULLSHEL.PAS to be the Primary file.
  657.      3. Search for "with TopMenu".
  658.      4. See the following code:
  659.  
  660.          GetMainMenu (FirstMenu);
  661.          MenuMode := SingleChoice;        
  662.          SingleFlagLine := 3;
  663.          Title   := '~First';
  664.          Line[1] := '~A line';
  665.          Line[2] := '~B line';
  666.          Line[3] := '~C line';
  667.          Line[4] := '~D line';
  668.          Line[5] := '';              LineMode[5] := Partition;
  669.          Line[6] := 'E~xit';         ProcPtr[6]  := SetQuit;
  670.          DefaultLine := 2;
  671.          DefaultLine := 2;
  672.          MsgLineNum  := ord(MainML);
  673.          HelpWndwNum := ord(MainMenuHW);
  674.          SaveMainMenu;
  675.  
  676.    TopMenu - All these variables are fields in the current menu record called 
  677.    TopMenu.  Notice that MenuMode is set to SingleChoice.  And that's how it 
  678.    is done!  That's all it takes to tell PULL that all items on the menu are 
  679.    single choice.  The program simply takes care of any selection.  So how do 
  680.    you know which line has been selected?  Just get the value of 
  681.    TopMenu.SingleFlagLine.  But also notice that SingleFlagLine has been 
  682.    initially assigned to line 3.  Now you know why the "C line" is flagged 
  683.    when the program first starts.  Setting SingleFlagLine is only needed for 
  684.    the SingleChoice mode.  So how do you make it multiple choice?
  685.  
  686.    MultipleChoice - Let's change MenuMode to MultipleChoice and run the 
  687.    program again.  Do it now.  This time you won't see any flags initially, 
  688.    but each line can be toggled on and off by selecting any line with RETURN.  
  689.    Ok, how do we know which line has been flagged now?  There are several more 
  690.    variables in the menu record other than shown here.  Each Line has an 
  691.    associated boolean variable called Flagged.  For example, if you want to 
  692.    see if Line[3] has been flagged, just test and see if Flagged[3] is true.  
  693.    But suppose we want some of those lines to be initially flagged?
  694.  
  695.    Flags - All the code we have seen is within a procedure called 
  696.    GetUserPullStats which initializes all the menus from InitPull.  The 
  697.    procedure GetMainMenu simply grabs a copy of the current menu record from 
  698.    the heap which happens to be cleared with all zeros at this time.  That 
  699.    means everything is a default value of zero unless we change it.  So, the 
  700.    value of Flagged for each line is false.  Let's see if we can set a couple 
  701.    of lines to be initially true by modifying the code to:
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.    Chapter 3, Programming Menus                                        Page 12
  711.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  712.  
  713.  
  714.      ...
  715.      MenuMode := MultipleChoice;        
  716.      SingleFlagLine := 3;
  717.      Title   := '~First';
  718.      Line[1] := '~A line';  Flagged[1] := true;
  719.      Line[2] := '~B line';  Flagged[2] := true;
  720.      ...
  721.  
  722.    Run the code again and verify that the first two lines are initially 
  723.    flagged.  If they are, then you are already getting the hang of how to 
  724.    program pull-down menus!  PULL is based on a fill-in-the-blank concept 
  725.    where you supply the data and the program takes care of the rest.
  726.  
  727.    Changed Flags - If there are several flags in the menu and just one is 
  728.    changed, how can you know?  Anytime a flag is altered in the menu, the 
  729.    variable "Changed" in the menu record is set to true which gives a quick 
  730.    survey for any action that may be needed.  This value remains true until 
  731.    your application program manually sets it false.
  732.  
  733.    Executing Procedures - But having a simple flag may not be enough for your 
  734.    application.  Suppose you may also want to DO something as well.  So how 
  735.    can we execute a procedure along with the selection?  Again, each line has 
  736.    an associated execution pointer ProcPtr.  Simply assign any valid procedure 
  737.    address to it and it executes it!  Try the following code:
  738.  
  739.      ...
  740.      MenuMode := MultipleChoice;        
  741.      SingleFlagLine := 3;
  742.      Title   := '~First';
  743.      Line[1] := '~A line';  Flagged[1] := true;  ProcPtr[1] := DummyProc;
  744.      Line[2] := '~B line';  Flagged[2] := true;  ProcPtr[2] := DummyProc;
  745.      ...
  746.  
  747.    Run this code and you will find that every time line 1 or 2 is toggled, the 
  748.    message "Processing ..." is displayed briefly on the message line which is 
  749.    all this dummy procedure was supposed to do.  After it is processed, the 
  750.    line is then flagged.  The procedure DummyProc is actually back a few lines 
  751.    in the code just before GetUserPullStats.  This makes it very convenient to 
  752.    have these procedures in the same file, but they don't have to be.  Since 
  753.    the pointer is FAR, these procedures, which have been forced to FAR, can be 
  754.    called from other units as well.
  755.  
  756.    Nil Pointer - So how come procedures were not executed before the pointers 
  757.    were assigned?  Again, all values are zero until changed.  So, the pointer 
  758.    was Nil.  The program simply ignores nil pointers and therefore does not 
  759.    execute anything.
  760.  
  761.    ExecChoice - This mode only executes procedures with ProcPtr and just 
  762.    ignores all flagging.  This is also the default mode.  Let's try this by 
  763.    adding the following braces:
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.    Chapter 3, Programming Menus                                        Page 13
  772.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  773.  
  774.  
  775.      ...
  776.    { MenuMode := MultipleChoice;        
  777.      SingleFlagLine := 3; }
  778.      Title   := '~First';
  779.      Line[1] := '~A line';  Flagged[1] := true;  ProcPtr[1] := DummyProc;
  780.      Line[2] := '~B line';  Flagged[2] := true;  ProcPtr[2] := DummyProc;
  781.      ...
  782.  
  783.    Run it again.  You found that both line 1 and 2 executed the dummy 
  784.    process, but the flags weren't toggled.  ExecChoice just ignores flagging.  
  785.    Flags are usually not useful with ExecChoice mode and they can remain 
  786.    false.  Lines 3 and 4 did absolutely nothing since the pointers were nil.
  787.  
  788.    Default Mode - How come MenuMode was not assigned to ExecChoice and instead 
  789.    was commented out with braces?  We could have if we wanted, but ExecChoice 
  790.    is the default mode with an ordinal value of zero.  So, it saves code to 
  791.    leave it out.
  792.  
  793.      
  794.    LINE MODES
  795.  
  796.    In this section, we will discover how each line in the menu can have one of 
  797.    several different modes and then test each one to see its effect.
  798.  
  799.    Seven Line Modes - Not only does the whole menu have a mode, but each line 
  800.    can have one of eight different modes:
  801.  
  802.      Choice     - permits flagging with Single- or MultipleChoice and 
  803.                   executes the ProcPtr.
  804.      ExecOnly   - executes the ProcPtr without flagging.
  805.      NoChoice   - disabled by the your program.
  806.      Comment    - bypassed by the highlight.
  807.      Partition  - mid-menu horizontal border.
  808.      ToDataWndw - to pull a data entry window.
  809.      ToSubMenu  - to pull next submenu level.
  810.      ToUserWndw - like ExecOnly, and adds a Submenu symbol.
  811.  
  812.    These names are the actual identifiers used in LineModeType.  Each line has 
  813.    an associated line mode saved in the variable LineMode.  For example, to 
  814.    see what mode is on line 3, just check the value of LineMode[3].
  815.  
  816.    Choice - This is the default and, as you would guess, its ordinal value is 
  817.    zero, so we never have to set it.  With this line mode and a menu mode of 
  818.    SingleChoice or MultipleChoice, the line can be flagged like we have seen 
  819.    in the previous examples.  But it is rare that any menu would have only 
  820.    flags.  So, what other alternatives are there?
  821.  
  822.    ExecOnly - Let's suppose that just one of the lines on our First menu 
  823.    should never be flagged, but all the others can.  How can we isolate it?  
  824.    Back to the current example, revise the menu to be MultipleChoice with the 
  825.    following changes:
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.    Chapter 3, Programming Menus                                        Page 14
  833.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  834.  
  835.  
  836.      ...
  837.      MenuMode := MultipleChoice;        
  838.    { SingleFlagLine := 3; }
  839.      Title   := '~First';
  840.      Line[1] := '~A line';  Flagged[1] := true;       ProcPtr[1] := DummyProc;
  841.      Line[2] := '~B line';  LineMode[2] := ExecOnly;  ProcPtr[2] := DummyProc;
  842.      ...
  843.  
  844.    Run it again and see that we can't toggle the flag on line 2 since it was 
  845.    assigned as ExecOnly.  All it does is execute DummyProc even though the 
  846.    menu mode is MultipleChoice.
  847.  
  848.    Comment - Suppose we wanted a title or some type of comment or help message 
  849.    inside the menu itself.  That line should not be considered as a valid 
  850.    choice.  In fact, the line should never be highlighted.  Try changing line 
  851.    3 to the following:
  852.  
  853.      ...
  854.      Line[2] := '~B line';  LineMode[2] := ExecOnly;  ProcPtr[2] := DummyProc;
  855.      Line[3] := '~My comment'; LineMode[3] := Comment;
  856.      ...
  857.  
  858.    Run it and move the HiLite up and down.  You can see that the HiLite passes 
  859.    right over line 3 and never accesses it.  By the way, notice also that the 
  860.    first letter of "My comment" was not highlighted as a command letter.  In 
  861.    fact, the entire line is a different attribute.  Also notice that the menu 
  862.    has automatically increased in width to accommodate the new longest line.
  863.  
  864.    Partition - Sometimes it is easier to understand a menu when it is divided 
  865.    into separate sections.  This can be done with the line mode of Partition.  
  866.    Change LineMode[3] as follows:
  867.  
  868.      ...
  869.      Line[2] := 'B line';  LineMode[2] := ExecOnly;  ProcPtr[2] := DummyProc;
  870.    { Line[3] := 'My comment'; }  LineMode[3] := Partition;
  871.      ...
  872.  
  873.    When you pull down the menu, you will see that line 3 has become an 
  874.    extension of the border with the same style and attribute.  Moving the 
  875.    highlight up and down will also show that the partition is passed over just 
  876.    like a Comment.  Since Line[3] was unecessary and was commented out with 
  877.    braces.
  878.  
  879.    NoChoice - Suppose you want a line to be temporarily unavailable because it 
  880.    didn't apply at a given stage in your program.  You can overwrite the menu 
  881.    record with a line mode of NoChoice which has the same effect as a Comment, 
  882.    except you can enable it again by changing the line mode back to what it 
  883.    was.  The command letter will again become available for that line.  In 
  884.    contrast, Partition and Comment never have a command letter.
  885.  
  886.    Other Line Modes - There are three remaining modes, ToDataWndw, ToSubMenu, 
  887.    and ToUserWndw, which will pull down another level of a menu or a window.  
  888.    These can also be assigned to LineMode which will be covered in more detail 
  889.    later.
  890.  
  891.  
  892.  
  893.    Chapter 3, Programming Menus                                        Page 15
  894.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  895.  
  896.  
  897.  
  898.    HILITE CONTROL
  899.  
  900.    Highlight Line - The menu highlight bar is tracked by a variable called 
  901.    HiLiteLine which is also in TopMenu.  Any time the highlight (also called 
  902.    HiLite) is moved, this value is updated to the current line number and 
  903.    saved.  So, upon re-entering the menu, the HiLite will still be on the same 
  904.    line before as before.
  905.  
  906.    Default Line - The HiLite has to start somewhere.  In our current example, 
  907.    the variable DefaultLine controls the initial line for the HiLite.  When 
  908.    you run it, you can see that the first time the menu is pulled, line 2 is 
  909.    highlighted.  Now move the HiLite down to line 4.  If you exit and re-enter 
  910.    the menu, the HiLite is still on line 4.  So, we know that it always 
  911.    remembers the current line.  But what is the default for DefaultLine?  
  912.    Let's find out.  Comment out the following line:
  913.  
  914.      ...
  915.      Line[4] := '~D line';
  916.      ...
  917.    { DefaultLine := 2; }
  918.      MsgLineNum  := ord(MainML);
  919.      ...
  920.  
  921.    Run the program and you will find that the HiLite starts on line 1 and not 
  922.    zero.  InitPull takes a second look at all menu records and makes sure that 
  923.    all DefaultLines have been set.  If not, it sets DefaultLine to line 1.  
  924.    But suppose we want the HiLite to start on the same line every time the 
  925.    menu is pulled?
  926.  
  927.    Back To Default Line - You can force the HiLite to same initial line by 
  928.    setting BackToDefault to true.  Let's try it on our current example:
  929.  
  930.      ...
  931.      Line[4] := '~D line';
  932.      ...
  933.      DefaultLine := 2;
  934.      BackToDefault := true;
  935.      MsgLineNum  := ord(MainML);
  936.      ...
  937.  
  938.    When you pull-down the menu this time, the default line is 2.  But move the 
  939.    HiLite to line 4 and exit the menu.  When the menu is pulled again, the 
  940.    HiLite goes back to line 2.  Looking at the code, the Quit menu record is a 
  941.    few lines down from the First menu.  There you can see that BackToDefault 
  942.    is set to true for that menu as well which would keep a user from 
  943.    inadvertently exiting the program.
  944.  
  945.  
  946.    ADDING LINES
  947.  
  948.    Adding Lines - To add more lines to a menu is a snap - just add a line.  
  949.    Try the following modification on the First menu.
  950.  
  951.  
  952.  
  953.  
  954.    Chapter 3, Programming Menus                                        Page 16
  955.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  956.  
  957.  
  958.      ...
  959.      Line[4] := '~D line';
  960.      Line[5] := '~E line';   { add this line }
  961.      DefaultLine := 2;
  962.      ...
  963.  
  964.    The program automatically knows how many lines are in the menu so that it 
  965.    is sized correctly and the HiLite knows how far to extend.  How many lines 
  966.    can be added?
  967.  
  968.    Maximum Lines - To control the size of the menu record, the maximum number 
  969.    of lines per menu is set by MaxMenuLines.  Go to a file called P70-VAR.INC 
  970.    and you will find it to be the very first constant in the file and it has 
  971.    been arbitrarily set to 15 lines.  This is one of several configuration 
  972.    constants preset in PULL.  To be able to change these values, you must have 
  973.    the source code to PULL which includes the file P70-VAR.INC.
  974.  
  975.    Maximum Characters - Each menu line is also limited to a maximum length.  
  976.    You can discover this by testing this code:
  977.  
  978.      ...
  979.      Line[4] := '~D line';
  980.      Line[5] := '~E line is longer than 20 characters'; 
  981.      ...
  982.      DefaultLine := 2;
  983.      ...
  984.  
  985.    The menu is only wide enough to accommodate 20 characters which is also 
  986.    preset with the constant MaxCharsPerLine.  Remember to account for the 
  987.    tilde character, too.
  988.  
  989.  
  990.    ADDING MENUS
  991.  
  992.    Now that you are familiar with the scope of a single menu, you can take the 
  993.    next step and learn how to include additional menus.
  994.  
  995.  
  996.    Main Menu Name - The first thing needed is a name for a new main menu.  On 
  997.    the first page of PULLSTAT.PAS, find an enumerated type called 
  998.    MainMenuNames and insert a new name called SecondMenu:
  999.  
  1000.      MainMenuNames = (NoMainMenu,FirstMenu,SecondMenu,QuitMenu);
  1001.  
  1002.    It is important that these names are in order so that InitPull will 
  1003.    arrange them correctly.
  1004.  
  1005.    Main Menu Record - Now the record of SecondMenu can be added.  Between the 
  1006.    FirstMenu and QuitMenu records add the following code:
  1007.  
  1008.      GetMainMenu (SecondMenu);
  1009.      MenuMode := MultipleChoice;        
  1010.      Title   := '~Second';
  1011.      Line[1] := '~A2 line';
  1012.      Line[2] := '~B2 line';
  1013.  
  1014.  
  1015.    Chapter 3, Programming Menus                                        Page 17
  1016.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1017.  
  1018.  
  1019.      Line[3] := '~C2 line';
  1020.      Line[4] := '~D2 line';
  1021.      MsgLineNum  := ord(MainML);
  1022.      HelpWndwNum := ord(MainMenuHW);
  1023.      SaveMainMenu;
  1024.  
  1025.    Now run the program.  You can see that there are now three menus that can 
  1026.    be pulled down.  They are arranged in the order of the MainMenuNames.  Just 
  1027.    for fun, let's reverse the names in MainMenuNames and see what happens:
  1028.  
  1029.      MainMenuNames = (NoMainMenu,SecondMenu,FirstMenu,QuitMenu);
  1030.  
  1031.    When you test this, you will find the two menus in different positions.  
  1032.    This makes rearranging a snap.  We didn't even have to change anything 
  1033.    about the MainMenu records themselves.
  1034.  
  1035.    Title - For a main menu, the title is required.  By default, the first 
  1036.    letter after the tilde (~) is used for command letter when pressing F10.  
  1037.    Press F10 now and then press "S".  This will pull down the SecondMenu.  But 
  1038.    what about the global key Alt-S?  Press F2 to get back to the work window 
  1039.    and try Alt-S.  Nothing happens.
  1040.  
  1041.    Global Key - To assign an extended key combination to this menu, go to the 
  1042.    bottom of the file to the section called Check Global Keys.  In this code, 
  1043.    an assignment can be made for this menu.  Insert the following line into 
  1044.    the code:
  1045.  
  1046.      ...
  1047.      AltF: SetCmdSeq ('F');
  1048.      AltS: SetCmdSeq ('S');   { insert this line }
  1049.      AltQ: SetCmdSeq ('Q');
  1050.      ...
  1051.  
  1052.    This is part of a case statement, so the order is not important.  In 
  1053.    addition, a value must be assigned to the constant AltS.  Back up a few 
  1054.    lines and add:
  1055.  
  1056.      ...
  1057.      AltF = #33;
  1058.      AltS = #31;  { insert this line }
  1059.      AltQ = #45;
  1060.      ...
  1061.  
  1062.    Now run the code and try Alt-S again to find that it now works.  But what 
  1063.    did we just do?  Any time an extended key is pressed at the keyboard, the 
  1064.    program always passes through the procedure called CheckGlobalKeys.  If the 
  1065.    extended keycode matches one in the case statement, the program sets a 
  1066.    sequence of normal key codes that would be pressed just as if pressing F10 
  1067.    and then "S".
  1068.  
  1069.  
  1070.    ADDING SUBMENUS
  1071.  
  1072.    Every menu can pull down another submenu.  This section will show how to 
  1073.    include one.  The method is much the same as with main menus.
  1074.  
  1075.  
  1076.    Chapter 3, Programming Menus                                        Page 18
  1077.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1078.  
  1079.  
  1080.  
  1081.  
  1082.    Submenu Name - Also at the beginning of PULLSTAT.PAS is an enumerated type 
  1083.    called SubMenuNames which looks like:
  1084.  
  1085.      SubMenuNames = (NoSubMenu,MySubMenu);
  1086.  
  1087.    Let's go ahead and use the name MySubMenu.
  1088.  
  1089.    Submenu Record - Just after the main menu record QuitMenu is an area for 
  1090.    submenus.  There is already a record made for MySubMenu and looks like the 
  1091.    following:
  1092.  
  1093.      GetSubMenu (MySubMenu);
  1094.      MenuMode := SingleChoice;
  1095.      SingleFlagLine := 5;
  1096.      Line[1] := '~1 line';
  1097.      Line[2] := '~2 line';
  1098.      Line[3] := '~3 line';
  1099.      Line[4] := '~4 line';
  1100.      MsgLineNum  := ord(SubML);
  1101.      HelpWndwNum := ord(SubMenuHW);
  1102.      SaveSubMenu;
  1103.  
  1104.    It is exactly like the main menu record, except to get and save it, 
  1105.    GetSubMenu and SaveSubMenu are used.  A title is not required for a 
  1106.    submenu as InitPull automatically gives it the name of the parent menu.  
  1107.    Now let's link the submenu to a main menu.
  1108.  
  1109.    Linking Menus - Choose SecondMenu line 2 for the line where MySubMenu is to 
  1110.    be linked.  In the SecondMenu (not the submenu) record, modify line 2 to 
  1111.    the following code:
  1112.  
  1113.      ...
  1114.      Title   := '~Second';
  1115.      Line[1] := '~A2 line';
  1116.      Line[2] := '~B2 line';  LineMode[2] := ToSubMenu;  
  1117.                              LinkNum [2] := ord(MySubMenu);
  1118.      ...
  1119.  
  1120.    Run the code and see that the submenu is pulled down when you press RETURN 
  1121.    on line 2 of SecondMenu.  This is probably simpler than you thought!  You 
  1122.    can also see a solid triangle on this line which indicates the line is 
  1123.    linked to a submenu.  By setting the line mode to ToSubMenu, the program is 
  1124.    prepared to pull-down another menu.  LinkNum identifies the record to be 
  1125.    pulled which is MySubMenu.  LinkNum is a byte type so using Ord is 
  1126.    required.
  1127.  
  1128.    Linking Configuration - The submenus link in a slide-up rather than a 
  1129.    slide-under configuration.  Menus grow vertically as the list expands.  If 
  1130.    the list gets too long, it can slide up when it hits the bottom of the 
  1131.    screen.  This leaves both the main menu and submenu in full view.  In 
  1132.    contrast, the data windows, which are covered later, use the slide-under 
  1133.    configuration.
  1134.  
  1135.  
  1136.  
  1137.    Chapter 3, Programming Menus                                        Page 19
  1138.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1139.  
  1140.  
  1141.    Default Linking Direction - Most Submenu are linked to the main menu in a 
  1142.    right-preferred slide-up arrangement.  When menus get crowded to the right, 
  1143.    InitPull will automatically reverse to the left and sub-menu symbols (solid 
  1144.    triangles) will also appear on the left.  Each subequent Submenu will 
  1145.    continue to link in the same direction as its parent as far as it can.  
  1146.    However, you may prefer that all menus use a slide-under configuration.  
  1147.    You can change this using the global variable DefaultLinkDir.
  1148.  
  1149.    Manual Linking Direction - As long as LinkDir is not specified like in our 
  1150.    example, InitPull will configure it for you.  However, this may not be 
  1151.    preferred in all cases.  To specify it manually, set the value of LinkDir 
  1152.    in that menu record to Left, Right, or Down which forces all submenus to be 
  1153.    linked in that direction.
  1154.  
  1155.    Global Key - Suppose this is a frequently used submenu and we want to 
  1156.    assign an extended key, say Alt-M, to access it.  To do this, it is much 
  1157.    the same as with a main menu, except there is an additional keystroke.  Add 
  1158.    the following line to CheckGlobalKeys:
  1159.  
  1160.      AltM: SetCmdSeq ('SB');
  1161.  
  1162.    and include a value for the constant Alt-M:
  1163.  
  1164.      AltM = #50;  { the Alt-M  extended key code }
  1165.  
  1166.    When you run the program, pressing Alt-M will pull down both SecondMenu and 
  1167.    MySubMenu just as if you had sequentially pressed F10, "S" and "B".
  1168.  
  1169.    SetCmdSeq - PULL saves the sequence of keystrokes for the current menu 
  1170.    level in a global string variable called CmdSeq.  SetCmdSeq compares the 
  1171.    current location of CmdSeq with the new destination and sets two variables 
  1172.    for the shortest path - MoreCmdSeq and PopLevels.  This will be covered 
  1173.    later in detail under the Control Flags section.
  1174.  
  1175.    SubSubmenus - SubSubmenus can be added in just the same way as submenus.  
  1176.    In fact you could nest them as deep as you want.  InitPull expects the 
  1177.    record names in SubMenuNames to be in a certain order so it can properly 
  1178.    locate each one on the CRT.  Just be sure that the order is all Submenus 
  1179.    first, all SubSub-menus second, all SubSubSubmenus third, etc.
  1180.  
  1181.  
  1182.    HELP MESSAGES
  1183.  
  1184.    Each menu has a help message that is displayed on the last line of the CRT 
  1185.    where the application can indicate valid keys and status or error messages.  
  1186.    In this section, you will discover how these messages can be linked to any 
  1187.    menu while it is displayed.
  1188.  
  1189.  
  1190.    Reserved Messages - PULL has already included some predefined messages for 
  1191.    several contexts including those for main menus and submenus.  In 
  1192.    PULLSTAT.PAS, just below the last submenu record, you can find an array of 
  1193.    MsgLines.  The ones reserved for main menus and submenus are MainML and 
  1194.    SubML, respectively:
  1195.  
  1196.  
  1197.  
  1198.    Chapter 3, Programming Menus                                        Page 20
  1199.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1200.  
  1201.  
  1202.      MsgLine[ord(MainML)]:=' ~F1~-help  ~F2~-pop   ~LTR~-cmd  ~ESC~-return  '+
  1203.                     '        ~'^[^Z'~ menus  ~'^X^Y'~-hilight  ~CR~-select';
  1204.      MsgLine[ord(SubML)] :=' ~F1~-help  ~F2~-pop   ~LTR~-cmd  ~ESC~-return  '+
  1205.                            '                  ~'^X^Y'~-hilight  ~CR~-select';
  1206.  
  1207.    The concatenation is just so that it will fit within an 80 column width in 
  1208.    the source code in which the compiler will patch it into a single line 
  1209.    anyway.  The tilde characters turns the highlighting on and off.  Back at 
  1210.    the top of the file, you can find the enumerated type MsgLineNames that 
  1211.    helps identify each message.  All the messages up to HelpML are reserved as 
  1212.    PULL expects them to be in that order.  But new ones can be added.
  1213.  
  1214.    New Messages - To create a new message, just append a name in the 
  1215.    MsgLineNames type and write out your new message.  Let's try it on the Quit 
  1216.    menu by changing MsgLineNum in its menu record as follows:
  1217.  
  1218.      ...
  1219.      Line[2] := '~Quit';      ProcPtr[2] := SetQuit;
  1220.      BackToDefault := true;
  1221.      MsgLineNum := ord(QuitML);
  1222.      ...
  1223.  
  1224.    Then append the name QuitML to the end of MsgLineNames:
  1225.  
  1226.      MsgLineNames = (NoML,WorkML,TopML,AltML,MainML,SubML,DW_ML,DE_ML,
  1227.                      SeqML,HelpML,ProcML,QuitML);
  1228.  
  1229.    And finally, let's create the message itself:
  1230.  
  1231.      MsgLine[ord(QuitML)] := ' Press "Q" if you are sure you want to quit.';
  1232.  
  1233.    Short messages are no problem, because PULL will clear the rest of the 
  1234.    message line.  Run the program now and see that the new message appears 
  1235.    when the Quit menu is pulled.  By now, you are seeing that pull-down menus 
  1236.    can link other menus and messages quite easily.
  1237.  
  1238.    Alt Key Message - You may have noticed when you hold down the Alt for more 
  1239.    than a half second, a message appears for the possible combinations.  When 
  1240.    we created a submenu with global key access, it is not likely a first-time 
  1241.    user would know the key was available.  The AltML message is reserved for 
  1242.    this purpose.  Let's alter the line to:
  1243.  
  1244.      MsgLine[ord(AltML)] :=' ~Alt-F~-First  ~Alt-M~-MySubMenu           '+
  1245.                            '                              ~Alt-X~-Exit';
  1246.  
  1247.    Run the program and hold down the Alt key to test the new message.
  1248.  
  1249.  
  1250.    HELP WINDOWS
  1251.  
  1252.    Many times the help message is not enough to fully explain the options 
  1253.    available for the context.  In this section, you will discover how to 
  1254.    create context-sensitive help windows and apply them to the menus.
  1255.  
  1256.  
  1257.  
  1258.  
  1259.    Chapter 3, Programming Menus                                        Page 21
  1260.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1261.  
  1262.  
  1263.    Help Window Record - Just as each menu has its own record, each Help Window 
  1264.    also has one called HelpWndw.  There are only a couple of variables that 
  1265.    need adjustment, to link in the number of lines to be included in the 
  1266.    window.  Let's try creating a help window for a main menu.  
  1267.  
  1268.    Example Window - Run the current example program again and test the F1 
  1269.    key while the SecondMenu is pulled down.  You should see a two-line help 
  1270.    window with the message "Main menu help message".  So, some help window is 
  1271.    already there, but the message is just bare bones.  Let's find out how the 
  1272.    message got there and alter it.
  1273.  
  1274.    Help Lines - In PULLSTAT.PAS after the MsgLine messages, there is another 
  1275.    section for setting HelpLines.  You should be able to see the code:
  1276.  
  1277.      HelpLine[ord(HLm1)]:='Main menu help message';
  1278.      HelpLine[ord(HLmL)]:='';
  1279.  
  1280.    These are the actual messages you saw in the help window.  Each window can 
  1281.    have a variable number of lines in the help window.  The program will 
  1282.    automatically size the window to fit in all the lines.  Let's edit and add 
  1283.    an extra line:
  1284.  
  1285.      HelpLine[ord(HLm1)]:='Main menu help message';
  1286.      HelpLine[ord(HLm2)]:='Press RETURN on the highlighted line to make';
  1287.      HelpLine[ord(HLmL)]:='your selection.';
  1288.  
  1289.    Since a new HelpLine name, HLm2, has been added, it must be inserted in the 
  1290.    enumerated type HelpLineNames at the top of the file:
  1291.  
  1292.      ...
  1293.      HLt1,HLtL,        { Top Line Menu }
  1294.      HLm1,HLm2,HLmL,   { Main menu }        { Modify this line. }
  1295.      HLs1,HLsL         { Submenu }
  1296.      ...
  1297.  
  1298.    Now run the program and test the modified help window.  This time you 
  1299.    should see the three lines.  With just a couple of changes, all help 
  1300.    windows are still in order along with the contents because it is so easy to 
  1301.    work with names instead of numbers.  How did the program know how many 
  1302.    lines to display even though changes were made?
  1303.  
  1304.    Number of Help Lines - In the section just below the HelpLines, see the 
  1305.    following code:
  1306.  
  1307.      ...
  1308.      HelpMsgLineNum := ord(HelpML);     { Standard message for a Help window }
  1309.      SetHelpLines (WorkWndwHW,HLw1,HLwL);
  1310.      SetHelpLines (TopMenuHW ,HLt1,HLtL);
  1311.      SetHelpLines (MainMenuHW,HLm1,HLmL);
  1312.      ...
  1313.  
  1314.    The call to SetHelpLines is a trivial procedure listed earlier in the code 
  1315.    that simply sets the first and last line number into the help window record 
  1316.    by using HelpLineNames.  Notice that the first and last line names end with 
  1317.    1 and L respectively.  This makes it handy so these statements never need 
  1318.  
  1319.  
  1320.    Chapter 3, Programming Menus                                        Page 22
  1321.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1322.  
  1323.  
  1324.    to be altered when new lines are added or inserted.
  1325.  
  1326.    Help Window Names - The window name is MainMenuHW which in listed the 
  1327.    enumerated type HelpWndwNames at the beginning of PULLSTAT.PAS:
  1328.  
  1329.      HelpWndwNames = (NoHW,WorkWndwHW,TopMenuHW,MainMenuHW,SubMenuHW,
  1330.                       DataWndwHW);
  1331.  
  1332.    Help Window Record - A help window record is assigned to each one of these 
  1333.    names.  In the SecondMenu record, we can find the window record name by 
  1334.    examining the following:
  1335.  
  1336.      ...
  1337.      MsgLineNum  := ord(MainML);
  1338.      HelpWndwNum := ord(MainMenuHW);
  1339.      SaveMainMenu;
  1340.      ...
  1341.    
  1342.    So now we can finally see how this help window was assigned to the main 
  1343.    menu.  Rather than having a standardized help window for each main menu as 
  1344.    a whole, you can even create new ones just as new message lines were 
  1345.    created:
  1346.  
  1347.      1. Append HelpWndwNames.
  1348.      2. Append HelpLineNames.
  1349.      3. Make HelpLine assignments.
  1350.      4. Use SetHelpLines to identify the first and last help lines.
  1351.      5. Assign the HelpWndwNum to the menu record.
  1352.  
  1353.    Help Message - Even the help window needs a help message.  One has already 
  1354.    been standardized for you called HelpML.  InitPull will initialize all help 
  1355.    windows to be assigned the message number in HelpMsgLineNum.
  1356.  
  1357.    Window Width - All help windows have a standard width which is set by a 
  1358.    configuration constant in P70-VAR.INC called HelpCharsPerLine currently 
  1359.    set at 50.  The program adds 2 to this value to leave a space between the 
  1360.    left and right borders.  The value can only be changed with the source 
  1361.    code.
  1362.  
  1363.    No Help Window - If there are selected records where a help window is not 
  1364.    wanted, just set:
  1365.  
  1366.      HelpWndwNum := NoHW;
  1367.  
  1368.    Integrated Help Windows - This system will integrate the help windows into 
  1369.    the EXE file.  With enumerated names, up to 255 lines can be included.  If 
  1370.    you need more, it is suggested that you develop a disk-based help system 
  1371.    which is currently beyond the scope of the this utility.
  1372.  
  1373.  
  1374.    DEFAULT ATTRIBUTES
  1375.  
  1376.    This section will show the variables used to create default attributes for 
  1377.    menus, windows and messages.
  1378.  
  1379.  
  1380.  
  1381.    Chapter 3, Programming Menus                                        Page 23
  1382.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1383.  
  1384.  
  1385.  
  1386.    InitPull - At the very first of the procedure GetUserPullStats, several 
  1387.    default attribute variables can be given assignments.  For instance, 
  1388.    MainMenuWattr will be used by InitPull to give all main menus the same 
  1389.    window attribute for Wattr in the menu record.  This saves you from having 
  1390.    to make the same assignment to every menu record.
  1391.  
  1392.    Attributes - As a personal preference, many users prefer the screen to have 
  1393.    different attribute when possible.  The following is the list of default 
  1394.    attributes and what they affect:
  1395.  
  1396.                        Record
  1397.      Default variable  Variable   Description
  1398.      ----------------  ---------  ------------------------------------------
  1399.      TopLineMenuAttr   n/a        Full length of the top line menu.
  1400.      TopLineMenuHattr  n/a        Top line menu HiLite.
  1401.      TopLineMenuLattr  n/a        Top line menu command Letter.
  1402.  
  1403.      MainMenuWattr     Wattr      Main menu Window.
  1404.      MainMenuBattr     Battr      Main menu Border.
  1405.      MainMenuHattr     Hattr      Main menu HiLite.
  1406.      MainMenuLattr     Lattr      Main menu command Letter.
  1407.      MainMenuCattr     Cattr      Main menu Comment line.
  1408.  
  1409.      SubMenuWattr      Wattr      Sub menu Window.        
  1410.      SubMenuBattr      Battr      Sub menu Border.        
  1411.      SubMenuHattr      Hattr      Sub menu HiLite.        
  1412.      SubMenuLattr      Lattr      Sub menu command Letter.
  1413.      SubMenuCattr      Cattr      Sub menu Comment line.
  1414.      
  1415.      HelpWndwWattr     Wattr      Help Window Window.
  1416.      HelpWndwBattr     Battr      Help Window Border.
  1417.  
  1418.      MsgLineAttr       n/a        Message line full length.
  1419.      ErrMsgAttr        n/a        Error messages.
  1420.      KeyStatusAttr     n/a        Key status of NumLock, Caps, and ScrollLock.
  1421.  
  1422.    Find the variable MainMenuBattr and modify it to inverse video:
  1423.  
  1424.      MainMenuBattr := LightGrayBG;
  1425.  
  1426.    When you run the program, you will find that every main menu has this new 
  1427.    attribute.  All the other variables work similarly.
  1428.  
  1429.    Mono vs. Color - You probably noticed an "if" statement in the code testing 
  1430.    the current video mode.  The results of this test allows you to configure 
  1431.    the menus for either Monochrome or color monitors.  Refer to your technical 
  1432.    reference manual for the effects of one attribute on either monitor.
  1433.  
  1434.  
  1435.    DEFAULT BORDERS
  1436.  
  1437.    This section will show the variables used to create default border styles 
  1438.    for the menus and windows just like the attributes mentioned above.
  1439.  
  1440.  
  1441.  
  1442.    Chapter 3, Programming Menus                                        Page 24
  1443.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1444.  
  1445.  
  1446.  
  1447.    Border Styles - The following is a list of default border style variables 
  1448.    and what they affect:
  1449.  
  1450.                        Record
  1451.      Default variable  Variable   Description
  1452.      ----------------  ---------  -----------------
  1453.      MainMenuBrdr      Border     All main menus.
  1454.      SubMenuBrdr       Border     All submenus.
  1455.      HelpWndwBrdr      Border     All help windows.
  1456.  
  1457.    The shell program has assigned MainMenuBrdr to a custom border UserBrdr1.  
  1458.    Let's modify this to SingleBrdr:
  1459.  
  1460.      MainMenuBrdr := SingleBrdr;
  1461.  
  1462.    In addition, you can optionally comment out the assignment of UserBrdr1 in 
  1463.    the previous line since it is no longer needed.  When the program is run, 
  1464.    all main menus will now have a single-line border style including the 
  1465.    partitions.
  1466.  
  1467.  
  1468.    CONTROL FLAGS
  1469.  
  1470.    The pull-down menus can be programmably controlled in your program by 
  1471.    toggling various pull-down control flags.  This helps direct the users to 
  1472.    the needed menus automatically instead of manually pressing a key sequence.  
  1473.    In this section, you will discover these flags and what they control.  Save 
  1474.    the shell program now for later use and get back to PULLDEMO for this 
  1475.    section.
  1476.  
  1477.    Control Variables - Here is the list of variables that control the menus:
  1478.  
  1479.      PopToWorkWndw - (Type: boolean) if true, all menus are removed and 
  1480.                      control is returned to the work window.
  1481.      PopToTop      - (Type: boolean) if true, control is set to the Top Line 
  1482.                      menu.
  1483.      PopLevels     - (Type: byte) number of levels (or menus) to pop.
  1484.      Popped        - (function) pops all menus before execution of ExecPtr.
  1485.      MoreCmdSeq    - (Type: string) series of command letters to do after 
  1486.                      popping.
  1487.      PullDown      - (Type: boolean) if true, the menus will be pulled down 
  1488.                      according to MoreCmdSeq.
  1489.  
  1490.    Examples - Run PULLDEMO and access Alt-I/Update.  In the Update menu, there 
  1491.    are six examples of how the menus can be controlled in combination with 
  1492.    executing a ProcPtr.  Execute each of those six lines to see what they do.  
  1493.    In PULLSTAT.PAS, search for "GetSubMenu (UpdateMenu)" and see that each 
  1494.    line is executing ProcPtr in the menu, so let's find out what those 
  1495.    procedures are doing.
  1496.  
  1497.    Process Then Pop - Back up until you find the ProcessThenPop procedure.  
  1498.    Very simply, the program first executed DummyProc and then set 
  1499.    PopToWorkWndw true.  When the flow of execution passes back through the key 
  1500.    dispatcher, PULL will immediately pop all menus and return to the top work 
  1501.  
  1502.  
  1503.    Chapter 3, Programming Menus                                        Page 25
  1504.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1505.  
  1506.  
  1507.    window.
  1508.  
  1509.    Pop Then Process - But suppose we want to do the reverse.  Anytime ProcPtr 
  1510.    is used for execution, a copy of it is kept in the global variable ExecPtr.  
  1511.    By using Popped, the function sets the appropriate flags to pop the menus.  
  1512.    The first time Popped is tested, it is false.  So, DummyProc is not 
  1513.    executed.  Once the menus are popped back to the work window, PULL executes 
  1514.    ProcPtr again via ExecPtr.  This time Popped will be true and DummyProc 
  1515.    will be executed.
  1516.  
  1517.    Pop, Process, and Pull - Let's go one step further and pull the same menus 
  1518.    back down that were popped.  Looking few lines down further in the 
  1519.    PopProcessAndPull procedure, the new line that was added is setting 
  1520.    PullDown to true.  But how does the program know what menus to pull?  PULL 
  1521.    keeps a copy of the last command sequence in the string MoreCmdSeq.  When 
  1522.    PullDown is true, the menus are pulled down by MoreCmdSeq.  This is useful 
  1523.    when there is something under the menus that needs to be changed like 
  1524.    accessing another work window.
  1525.  
  1526.    Popping Levels - Or, if you just want to back up a number of menu levels, 
  1527.    just specify the number of levels to pop with PopLevels.  In the procedure 
  1528.    PopNumOfLevels, rather than making the menu completely disappear only to 
  1529.    needlessly pull them back down again, this procedure pops back as far as it 
  1530.    needs to go and then additionally pulls down another submenu (or data 
  1531.    window).  This sequence is useful when you know exactly where you are and 
  1532.    where you are going.
  1533.  
  1534.    Popping to New Menus - If you need to go to a new menu, you can use the 
  1535.    flag PopToTop which will pop the menus up to the Top Line.  By setting 
  1536.    PullDown true and MoreCmdSeq to the desired menu, you can get to the new 
  1537.    destination like the procedure PopToNewMenu.
  1538.  
  1539.    Smart Pop and Pull - But suppose the menus will execute the same ProcPtr 
  1540.    from three different locations in the menus, and still want it to appear 
  1541.    smart like PopNumOfLevels does?  PULL has a procedure called SetCmdSeq that 
  1542.    compares the current location, CmdSeq, with your destination.  It sets 
  1543.    MoreCmdSeq and PopLevels to the shortest path.  In fact, PopNumOfLevels 
  1544.    could have looked like:
  1545.  
  1546.      procedure PopNumOfLevels;
  1547.      begin
  1548.        PullDown := true;
  1549.        SetCmdSeq ('IY');
  1550.      end;
  1551.  
  1552.    The parameter for SetCmdSeq is the full sequence of command letters to be 
  1553.    pressed from the Top Line.
  1554.  
  1555.    Sequential Data Windows - One application of these control flags may be 
  1556.    sequential entry for data windows.  Access Alt-I/Date and press RETURN a 
  1557.    few times to see how the menus are cycled in a loop for the date.  To see 
  1558.    how it was done, follow the ProcPtrs in the DateMenu and see what flags 
  1559.    were set.
  1560.  
  1561.  
  1562.  
  1563.  
  1564.    Chapter 3, Programming Menus                                        Page 26
  1565.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1566.  
  1567.  
  1568.    SUMMARY
  1569.  
  1570.    At this point in the tutorial, you've been able to master the configuration 
  1571.    of the top line, main, and sub menus with all the menu modes and most of 
  1572.    the line modes.  In addition, you found how to add menus and submenus 
  1573.    and assign help messages and help windows.  You changed the appearance of 
  1574.    the menus with attributes and borders.  You could even programmably control 
  1575.    the sequence of menus that were pulled down.  These were all accomplished 
  1576.    by just filling out the appropriate variables.
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.  
  1602.  
  1603.  
  1604.  
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.    Chapter 3, Programming Menus                                        Page 27
  1626.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1627.  
  1628.  
  1629.    4.  S C R E E N   D E S I G N
  1630.  
  1631.    You are now at a point where you understand most of the fundamental 
  1632.    features in PULL.  In this section, you will discover how to control the 
  1633.    arrangement of the major components of full screen design.  You will be 
  1634.    able to relocate the Title line, Top Line menu, Main menus, Work 
  1635.    window(s), and Message line.  Arrangement of the components will depend on 
  1636.    the human factors needed for your application.
  1637.  
  1638.  
  1639.    TITLE LINE
  1640.  
  1641.    The title line is a row that you can reserve for pertinent information.  
  1642.    In the shell program, the title line is assumed to be row 1 where a program 
  1643.    name, title, and copyright were placed.  Actually, PULL does nothing to 
  1644.    program this line, but PULL was designed to work around it. 
  1645.  
  1646.  
  1647.    TOP LINE MENU
  1648.  
  1649.    Showing the Top Line - The top line menu is automatically created by 
  1650.    assembling the titles from each main menu.  So, the string is already 
  1651.    created for you in the string variable TopLineStr.  To write this string to 
  1652.    the screen, simply call ShowTopLine.  But where is it placed?  
  1653.  
  1654.    Top Line Placement - Back in GetPullUserStat, search for the variable 
  1655.    TopLineRow.  It is found in a section called Top Line Defaults.  This is 
  1656.    the variable that determines where the top line is placed:
  1657.  
  1658.      TopLineRow := 2;     { Top Line menu to appear on row 2. }
  1659.  
  1660.    Let's try reversing the title line and the top line menu in the shell 
  1661.    program.  Set TopLineRow to 1 and then look in PULLSHEL.PAS and modify the 
  1662.    row of the title line to 2:
  1663.  
  1664.      WWrite ( 2, 1,'PULLSHELL v7.0            Multi-level Pu'+
  1665.                    'll-down Menus       Copr 1993  J H LeMay');
  1666.  
  1667.    Now run the program and see both lines reversed, but when the main menus 
  1668.    are pulled, they are still on row 3.  How can they be moved?
  1669.  
  1670.  
  1671.    MAIN MENU ROW
  1672.  
  1673.    Main Menu Row - The row on which the main menus appear is controlled by 
  1674.    the value of MainMenuRow.  The Main menus do not have to be attached to Top 
  1675.    Line menu and can appear on any row provided they do not interfere with 
  1676.    the Message line.
  1677.  
  1678.    Moving the Row - Let's shift the Main menus back up so they will appear 
  1679.    to be attached to the Top Line menu.  In PULLSTAT.PAS, search for:
  1680.  
  1681.      MainMenuRow := 3;  { First row of main menus to appear on row 3 }
  1682.  
  1683.    and change it to 2.  Run the program again to see that the main menus pull-
  1684.  
  1685.  
  1686.    Chapter 4, Screen Design                                            Page 28
  1687.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1688.  
  1689.  
  1690.    down now on row 2.  But also check the submenu by pressing Alt-M.  Even the 
  1691.    submenu is correctly placed!  InitPull accommodates the changes.
  1692.  
  1693.  
  1694.    SUBMENU ROW
  1695.  
  1696.    SubMenu Row - Try to arrange the lines in your menus that link submenus so 
  1697.    that they are as high in the menu as practical.  Otherwise, long menus will 
  1698.    bottom out on the CRT and PULL will be sliding up the menus to keep them in 
  1699.    view.  PULL handles this well by using the slide-up configuration, but the 
  1700.    menus will not appear to have much foresight in your design.  The 
  1701.    Alt-A/Tires/Brands menu is a good example of keeping menus high. 
  1702.  
  1703.  
  1704.    WORK WINDOWS
  1705.  
  1706.    Window Modes - The major portion of the screen is intended to be the work 
  1707.    window for your application.  This area can have one or more windows and 
  1708.    they can be in any window mode that you chose - even virtual.  Usually one 
  1709.    of the modes can be PermMode since there is no data to save under the 
  1710.    screen, but with a TSR, you may need to save the screen, too.  
  1711.  
  1712.    Window Size - The example in the shell program uses a 22x80 PermMode window 
  1713.    with border.  Let's get rid of the title line, make the window larger, and 
  1714.    at the same time, take off the double border.  In PULLSHEL.PAS, comment out 
  1715.    the title line with braces and modify the MakeWindow statement to the 
  1716.    following:
  1717.  
  1718.    { WWrite ( 1, 1,'PULLSHELL v7.0            Multi-level Pu'+
  1719.                    'll-down Menus       Copr 1993  J H LeMay'); }
  1720.      ShowTopLine;
  1721.      SetWindowModes (PermMode);
  1722.      MakeWindow (2,1,CRTrows-2,CRTcols,White+BlueBG,White+BlueBG,NoBrdr,
  1723.                  Window1);
  1724.  
  1725.    Running the program, you will see the work window took up all but the Top 
  1726.    Line menu in Row 1 and the Message line on the last row.  Notice also that 
  1727.    the contents of the window also moved because they have window-relative 
  1728.    coordinates.  This shows you the flexibility of your screen design.
  1729.  
  1730.  
  1731.    MESSAGE LINE
  1732.  
  1733.    Message Line - This is the line on which all messages will appear and is 
  1734.    usually in reference to CRTrows to accommodate different video modes.  If 
  1735.    the message line is intended to list key commands, for human factor 
  1736.    reasons, it is best to keep it near the bottom row.  
  1737.  
  1738.    Location - The location of the line is set by the variable MsgLineRow in 
  1739.    GetUserPullStats.  To whatever line it is assigned, be sure that there is 
  1740.    no possibility that it may be covered by other windows.  You may need to 
  1741.    set the window margins to do this.
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.    Chapter 4, Screen Design                                            Page 29
  1748.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1749.  
  1750.  
  1751.    HELP WINDOWS
  1752.  
  1753.    There are two defaults that can be set for the Help windows - the bottom 
  1754.    row and the window modes.  This section shows how these can be modified.
  1755.  
  1756.    Bottom Row - All help windows are centered column-wise on the CRT.  
  1757.    However, the default bottom row of the window is assigned to HelpBottomRow 
  1758.    and is allowed to grow upward.  This variable is used to calculate the 
  1759.    upper left corner of the window and sets the Row and Col for each help 
  1760.    window record.
  1761.  
  1762.    Window Modes - The current example program uses a shadow with zoom effect 
  1763.    when the help window appears.  The cursor mode is also turned off.  This 
  1764.    default is assigned to HelpWndwModes which in turn assigns it to HWmodes in 
  1765.    each help window record.  
  1766.  
  1767.    Example - In the shell program, search for HelpWndwModes and modify the 
  1768.    code to the following:
  1769.  
  1770.      ...
  1771.      HelpWndwModes := CursorOffMode;
  1772.      HelpBottomRow := CRTrows-10;
  1773.      ...
  1774.  
  1775.    When you test any help window this time, the window will appear instantly 
  1776.    without the zoom effect and is placed higher from the bottom.
  1777.  
  1778.  
  1779.    START-UP MENU
  1780.  
  1781.    Control Variables - When the program first starts, you can also have the 
  1782.    program pull down any menu using the Top Line variables MPulled, PullDown, 
  1783.    and MoreCmdSeq.  Search again for TopMenuRow and see this code:
  1784.  
  1785.      TopMenuRow := 1;
  1786.      MPulled    := ord(FirstMenu);
  1787.      MoreCmdSeq := 'F';
  1788.      PullDown   := false;
  1789.  
  1790.    MPulled - This is initial assignment for the main menu title that would be 
  1791.    highlighted when pressing F10 for the first time.
  1792.  
  1793.    MoreCmdSeq - This is the actual variable that is set by the global key 
  1794.    routine SetCmdSeq.  When F2 is pressed for the first time, it would emulate 
  1795.    pressing F10 and "F" from the keyboard as if it remembered the last 
  1796.    sequence of keystrokes.  MoreCmdSeq can have as many characters as needed 
  1797.    to get down to the desired menu or window.  It is a good practice to make 
  1798.    sure the first character matches the MPulled menu.
  1799.  
  1800.    PullDown - If this is true, the program will pull-down the menus just as if 
  1801.    F2 had been pressed so that the menus pulled match the sequence in 
  1802.    MoreCmdSeq.  Try setting PullDown to true and see if FirstMenu is indeed 
  1803.    pulled.
  1804.  
  1805.  
  1806.  
  1807.  
  1808.    Chapter 4, Screen Design                                            Page 30
  1809.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1810.  
  1811.  
  1812.    OVERRIDING DEFAULTS
  1813.  
  1814.    PULL configures almost everything automatically, but sometimes things don't 
  1815.    always fit the mold.  This section will show you how to override the 
  1816.    settings before and after PULL has configured them.
  1817.  
  1818.  
  1819.    GetUserPullStats - Row/Col locations for submenus are located by default at 
  1820.    run time with the slide-up configuration when these values remain zero, and 
  1821.    likewise DWrow/DWcol for data windows for slide-under.  You can override 
  1822.    PULL and locate them absolutely by giving them non-zero values in the 
  1823.    procedure GetUserPullStats.
  1824.  
  1825.    Submenu Location - If submenus are unusually wide and will not fit in the 
  1826.    slide-up configuration, PULL will terminate the program with a warning 
  1827.    message to let you know of the problem.  If you set the variable 
  1828.    LocationWarning false in GetUserPullStats, you can go ahead and test all 
  1829.    submenus to see the one not fitting the slide-up configuration.  PULL will 
  1830.    attempt slide-under as a second best.  If it still doesn't fit, then you 
  1831.    need an override for the Row and Col setting.  If you are satisfied with 
  1832.    the menu locations, you can optionally set LocationWarning false.  But be 
  1833.    sure to check all the menus on the CRT to make sure they have been properly 
  1834.    placed.
  1835.  
  1836.    GetOverrideStats - This procedure in PULLSTAT is executed after all the 
  1837.    automatic configuration has been done.  If there are exceptions in your 
  1838.    program, you can assign them inside this procedure.  For just a few 
  1839.    changes, you can edit the records right in the heap.  Take a look at this 
  1840.    procedure in PULLSTAT for PULLDEMO.  What kind of things would you 
  1841.    typically change?
  1842.  
  1843.    Menu Command Letters - Not all menus use the first letter for the command 
  1844.    letter.  You assign the command letter by placing a tilde (~) in front of 
  1845.    the preferred letter on that line.  What happens when two lines start with 
  1846.    the same one?  They are not case sensitvie and only the first one will ever 
  1847.    be reached.  Just make sure the Lines do not contain duplicate letters.  
  1848.    But if you must do so manually, the command letters must be changed.  The 
  1849.    variable in the menu record that contains these letter is CmdLtrs.  For 
  1850.    instance, the command letters for FirstMenu are 'ABCD' where character one 
  1851.    corresponds to line 1, etc.  They are always upper case in this string, but 
  1852.    can be lower case in the menu.  So, you can edit this string to whatever 
  1853.    your command letters need to be.  In addition, that letter will also be 
  1854.    highlighted in the menu.  Inaccessible line modes like Comment and 
  1855.    Partition replace the command letter with #00.
  1856.  
  1857.    Top Line Command Letters - You can also do the same with the Top Line 
  1858.    command letters which are kept in a global variable called TopCmdLtrs.
  1859.  
  1860.    Attributes and Borders - Sometimes the default attributes and borders need 
  1861.    to be changed in a place or two.  GetOverrideStats is the place to make 
  1862.    those changes.
  1863.  
  1864.  
  1865.  
  1866.  
  1867.  
  1868.  
  1869.    Chapter 4, Screen Design                                            Page 31
  1870.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1871.  
  1872.  
  1873.    SUMMARY
  1874.  
  1875.    If you have completed the tutorial with the shell program up to this point, 
  1876.    you should now have enough confidence with the major components of screen 
  1877.    design.  You can now develop a concept for your application that can best 
  1878.    be suited the needs of your users.  If you would like to stop now, save the 
  1879.    shell program so that it can to be used later in the following sections.
  1880.  
  1881.  
  1882.  
  1883.  
  1884.  
  1885.  
  1886.  
  1887.  
  1888.  
  1889.  
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.  
  1921.  
  1922.  
  1923.  
  1924.  
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.    Chapter 4, Screen Design                                            Page 32
  1931.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1932.  
  1933.  
  1934.    5.  D A T A   W I N D O W S
  1935.  
  1936.    Often when a menu line is selected from a menu, a means is needed to enter 
  1937.    data into the application such as numbers or file names.  PULL already has 
  1938.    powerful utilities to do this for free-field data entry including flex 
  1939.    fields, set checking, key translation, and range checking for nine types of 
  1940.    data.
  1941.  
  1942.  
  1943.    DATA WINDOW PARTS
  1944.  
  1945.    There are two parts to a data entry window - the data entry field and the 
  1946.    window.
  1947.  
  1948.    Data Entry Field - As the name implies, this is the place where characters 
  1949.    are allowed to be entered for the data.  This is also called entry or field 
  1950.    for short.
  1951.  
  1952.    Data Window - The window is the border and spacing surrounding the field.  
  1953.    Using the term data window loosely refers to both the field and the window 
  1954.    together.
  1955.  
  1956.  
  1957.    DATA WINDOW RECORD
  1958.  
  1959.    The arrangement of the records for data windows is very similar to the way 
  1960.    menu records have been done.  So, the same concept of fill-in-the-blank is 
  1961.    used.  In this section, you will find how these records can be filled out 
  1962.    in the program.
  1963.  
  1964.  
  1965.    Top Data Window - Let's find the data window record and see what it 
  1966.    contains:
  1967.  
  1968.      1. Load the file PULLDATA.PAS into the IDE editor.
  1969.      2. Set PULLSHEL.PAS to be the Primary file.
  1970.      3. Search for "with TopDataWndw"
  1971.      4. See the following code:
  1972.  
  1973.          GetDataWndw (ord(aByteDW));         { Just gets cleared DataWndw }
  1974.          VarAddr       := @aByte;
  1975.        { TypeOfData    := Bytes; }           { This is the default }
  1976.          Field         := 3;
  1977.        { MsgLineNum    := ord(DW_ML); }      { This is the default }
  1978.        { HelpWndwNum   := ord(DataWndwHW); } { This is the default }
  1979.          SaveDataWndw;                       { Saves it in the heap }
  1980.  
  1981.    In the tutorial program of PULLSHEL.PAS, the program does not have any data 
  1982.    windows linked to the menus yet, but this record has already been written 
  1983.    to speed things along.  As you can see, only four lines were needed to be 
  1984.    set in the Data Window record which is named aByteDW.  Let's go ahead and 
  1985.    link this record into one of the menus.
  1986.  
  1987.    Linking Data Windows - Go back to PULLSTAT.PAS to find the FirstMenu record 
  1988.    and revise it to add this data window to line 3:
  1989.  
  1990.  
  1991.    Chapter 5, Data Windows                                             Page 33
  1992.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  1993.  
  1994.  
  1995.  
  1996.      GetMainMenu (FirstMenu);
  1997.      ...
  1998.      Line[1] := '~A line';
  1999.      Line[2] := '~B line';
  2000.      Line[3] := '~Enter Byte';  LineMode[3] := ToDataWndw;  
  2001.                                 LinkNum [3] := ord(aByteDW);
  2002.      Line[4] := '~D line';
  2003.      ...
  2004.  
  2005.    When the program is run, pressing RETURN on line 3 will pull-down the data 
  2006.    entry window.  The variable is a byte type which it was assigned by default 
  2007.    in the data window record.  Go ahead and experiment with the entry by 
  2008.    making mistakes such as a number over 255.  When you get an error message, 
  2009.    just press ESC.  For the full list of editing keys, press F1 for the help 
  2010.    window.
  2011.  
  2012.    Window Location - Notice that the location of the window is immediately 
  2013.    underneath the HiLite and shifted slightly to the right.  This is called a 
  2014.    slide-under configuration.  Since there is only one row in a Data Window, 
  2015.    they tend to grow horizontally.   Should the window be too long for the 
  2016.    right side of the screen, the window would then slide under the HiLite to 
  2017.    the left until it fit.  This location is determined at run time.  
  2018.  
  2019.    Justification - The entry is always left justified since it is an input-
  2020.    only window.
  2021.  
  2022.    Line Mode - If you remember about line modes, we did not get a chance to 
  2023.    test ToDataWndw.  So, now you can see that this instructs PULL that a Data 
  2024.    Window is linked to the menu and it then uses the named data window record 
  2025.    for the window.
  2026.  
  2027.    Link Number - The number of the Data Window record linked is of course the 
  2028.    value of the name aByteDW.  Again, names are used to easily arrange and 
  2029.    identify the contents of the record.  So, how is the name assigned?
  2030.  
  2031.    Data Window Names - At the top of the file PULLSTAT.PAS (not PULLDATA.PAS), 
  2032.    the enumerated type DataWndwNames has the following list:
  2033.  
  2034.      DataWndwNames = (NoDW,aByteDW);
  2035.  
  2036.    Only one window name has been assigned and that is the one being tested.  
  2037.    There are no reserved names except NoDW since the window numbers are 1-
  2038.    based.  Notice that PULLDATA uses PULLSTAT.  Since DataWndwNames is in the 
  2039.    interface, the names can also be used in PULLDATA.  Ok, the data is plugged 
  2040.    into the window, but where is it being stored?
  2041.  
  2042.  
  2043.    DATA WINDOW VARIABLE
  2044.  
  2045.    Variable Address - To know where the variable is located, the record uses a 
  2046.    pointer to the variable location.  The variable used in this window is 
  2047.    aByte which is a typed constant declared at the beginning of PULLDATA.PAS 
  2048.    and given a value of 100.  To get the address of the variable, you just 
  2049.    place the "@" operator in front of the variable and it returns its FAR 
  2050.  
  2051.  
  2052.    Chapter 5, Data Windows                                             Page 34
  2053.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2054.  
  2055.  
  2056.    address.
  2057.  
  2058.    Type of Data - Because a pointer is being used instead of the variable 
  2059.    itself, it is not known how many bytes the variable uses in memory and 
  2060.    neither is the type of data.  So, PULL must be instructed what type of data 
  2061.    is being accessed.  PULL can handle nine types of data which is enumerated 
  2062.    in P70-VAR.INC:
  2063.  
  2064.      TypeOfDataType = (Bytes,Words,ShortInts,Integers,LongInts,Reals,UserNums,
  2065.                        Chars,Strings);
  2066.  
  2067.    The associated data types should be intuitive.  A special case is UserNums 
  2068.    which are really strings, but are meant to be displayed as numbers like hex 
  2069.    for example.  Remembering that all zero values in the record are the 
  2070.    default, now you can see why TypeOfData defaulted to Bytes when nothing was 
  2071.    assigned - good ol' fill-in-the-blank again.
  2072.  
  2073.    Matching the Type - Pascal has strong type checking and it can spoil you 
  2074.    easily.  This arrangement of splitting the variable into a type and a 
  2075.    pointer is most convenient for the Data Window.  However, it is up to your 
  2076.    skills as a programmer to ensure that the type truly matches the data at 
  2077.    that destination as PULL both reads and writes to it.
  2078.  
  2079.    Validity Check - All numeric types are given a validity check by using the 
  2080.    Val procedure.  If the data entry can successfully be converted to the 
  2081.    specified numeric type and without overflow, the data is considered valid.  
  2082.    If not, the error message "Invalid entry." is displayed.  For now, here is 
  2083.    a hint about error messages.  You can see the string for this message 
  2084.    earlier in the file:
  2085.  
  2086.      ErrMsgLine[ord(InvalidEM)]:=' Invalid entry.           ESC-acknowledge';
  2087.  
  2088.  
  2089.    FIELDS
  2090.  
  2091.    This section gives instructions on how to adjust the field sizes for the 
  2092.    data entry window.
  2093.  
  2094.    Field - Let's see how easy it to add a new data window on our own for 
  2095.    strings and adjust the field sizes.  Right after the aByteDW record, add 
  2096.    the following new record:
  2097.  
  2098.      GetDataWndw (ord(MyStringDW));
  2099.      VarAddr       := @MyString;
  2100.      TypeOfData    := Strings;
  2101.      Field         := 25;
  2102.      SaveDataWndw;
  2103.  
  2104.    At the top of the file, declare the constant MyString:
  2105.  
  2106.      ...
  2107.      aByte2: byte = 200;
  2108.      MyString: string[25] = 'This is my string.';
  2109.  
  2110.    Now let's link it into line 4 of the FirstMenu.  So, in PULLSTAT, modify 
  2111.  
  2112.  
  2113.    Chapter 5, Data Windows                                             Page 35
  2114.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2115.  
  2116.  
  2117.    the FirstMenu record to:
  2118.  
  2119.      GetMainMenu (FirstMenu);
  2120.      ...
  2121.      Line[1] := '~A line';
  2122.      Line[2] := '~B line';
  2123.      Line[3] := '~Enter Byte';  LineMode[3] := ToDataWndw;  
  2124.                                 LinkNum [3] := ord(aByteDW);
  2125.      Line[4] := '~My string';   LineMode[4] := ToDataWndw;
  2126.                                 LinkNum [4] := ord(MyStringDW);
  2127.      ...
  2128.      
  2129.    And let's not forget to add MyStringDW to the DataWndwNames type:
  2130.  
  2131.      DataWndwNames = (NoDW,aByteDW,MyStringDW);
  2132.  
  2133.    Run the program and test the data window.  Since Field was set to 25, the 
  2134.    window was expanded to allow a 25 character entry with a space on either 
  2135.    side.  So, whatever the field width is, that is how many characters can be 
  2136.    entered in the string.  Notice that we were careful not to make Field 
  2137.    larger than the string size so it would not overwrite too many characters 
  2138.    at MyString's address.  But what if the string can have up to 100 
  2139.    characters?  How can that be made to fit?
  2140.  
  2141.    Maximum Field - There are actually two variables to adjust the size of the 
  2142.    entry field, one is Field and the other is MaxField.  Rather than 
  2143.    explaining it, let's see what it can do.  First change the constant to:
  2144.  
  2145.      MyString: string[100] = 'This is my string.';
  2146.  
  2147.    and then add the variable setting of MaxField in the Data Window record:
  2148.  
  2149.      ...
  2150.      Field         := 25;
  2151.      MaxField      := pred(sizeof(MyString));      { = 100 }
  2152.      SaveDataWndw;
  2153.  
  2154.    Now when you run it, the field is flexible.  You can now enter up to 100 
  2155.    characters even though the field only displays 25.  These fields are called 
  2156.    flex fields.  
  2157.  
  2158.    Default Field - By default, program sets MaxField equal to Field.  Anytime 
  2159.    MaxField has been set and is not the equal to Field, the flex field becomes 
  2160.    active.  So, this can be used with any type of data and not just strings.
  2161.  
  2162.  
  2163.    TITLES
  2164.  
  2165.    If your field is wide enough, you can easily add a title.  Try adding the  
  2166.    following code to the MyStringDW record:
  2167.  
  2168.      GetDataWndw (ord(MyStringDW));
  2169.      Title         := 'Enter File Name';   
  2170.      VarAddr       := @MyString;
  2171.      ...
  2172.  
  2173.  
  2174.    Chapter 5, Data Windows                                             Page 36
  2175.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2176.  
  2177.  
  2178.  
  2179.    Pulling down this data window, the title will be centered on the top row of 
  2180.    the window.  Titles are optional and will be truncated if necessary to fit 
  2181.    within the window.
  2182.  
  2183.  
  2184.    EDITING KEYS
  2185.  
  2186.    If you didn't get a chance to try out the full editing keys, here's the 
  2187.    list and their function:
  2188.  
  2189.      Keys                          Movement
  2190.      ----------------------------  -----------------------------------------
  2191.      Left Arrow / ^S               Character Left/Right
  2192.      Right Arrow / ^D              Character Left/Right
  2193.      Home / Ctrl Left  Arrow / ^A  First character
  2194.      End  / Ctrl Right Arrow / ^F  Last character
  2195.      Del / ^G                      Deletes character under cursor or deletes 
  2196.                                    the entire entry when data window is 
  2197.                                    opened.
  2198.      Backspace / ^H                Deletes character to left of cursor
  2199.      Ins / ^V                      Toggles between insert and overwrite mode
  2200.      ^R/^U                         Restores original contents
  2201.      ^Y                            Deletes entire contents
  2202.  
  2203.    Insert Toggle - PULL allows you to use both insert and overwrite mode.  You 
  2204.    can tell the status by the shape of the cursor.  The half-block cursor 
  2205.    indicates the insert mode which appears correctly in any video mode.
  2206.  
  2207.    Cursor Handling - In flex fields, some special cursor handling has also 
  2208.    been included that you will appreciate when the cursor is at either end.  
  2209.    When adding characters to the far right there is always one space open 
  2210.    until the maximum character is reached.  It helps identify the last 
  2211.    character and shows the character when the Del key is used.  The same 
  2212.    principle is used when backspacing - at least one character is always shown 
  2213.    until the last one is deleted.  The cursor always remains confined inside 
  2214.    the Field width on a flex field.
  2215.  
  2216.    One-Column Field - A special case is considered when Field is 1 column in 
  2217.    width.  The cursor does not move and any valid character typed in will 
  2218.    overwrite the contents.  Del or Backspace also deletes the contents.  
  2219.    Please do not consider using flex fields for this case.
  2220.  
  2221.    AutoNumLock - On machines with enhanced keyboards, it may be an advantage 
  2222.    to automatically turn on the NumLock when in Edit mode.  If so, by setting 
  2223.    AutoNumLock true, numeric key pad will be have the NumLock turned on when 
  2224.    you start editing.  After the edit, PULL will restore it to its original 
  2225.    mode, on or off.  Please note that even though the "NUM" message appears on 
  2226.    the message line to show the true internal status of NumLock, many machines 
  2227.    do not have a smart enough BIOS to also toggle the NumLock LED on the 
  2228.    keyboard itself.  Pressing the key can put it back in sync, but the "NUM" 
  2229.    message is the thing to watch.
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.    Chapter 5, Data Windows                                             Page 37
  2236.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2237.  
  2238.  
  2239.    KEY SETS
  2240.  
  2241.    This section gives instructions on how to use BP's powerful sets to screen 
  2242.    for valid keystrokes into the data entry.
  2243.  
  2244.  
  2245.    Entry Sets - As a preventative measure, each keystroke is checked against a 
  2246.    set to see if it is valid before it is allowed into the field.  If it is 
  2247.    not, the keystroke is simply ignored.  Several set have included and a 
  2248.    default is given to each of the nine types of data:
  2249.  
  2250.      SetNames = (NoSet,UnsignedSet,SignedSet,RealSet,CharSet,
  2251.                  HexSet,FileNameSet,PathSet,MaskSet);
  2252.  
  2253.    where the following types are given the following sets:
  2254.  
  2255.      Type       Set
  2256.      ---------  -----------
  2257.      Bytes      UnsignedSet
  2258.      Words      UnsignedSet
  2259.      ShortInts  SignedSet
  2260.      Integer    SignedSet
  2261.      LongInts   SignedSet
  2262.      Reals      RealSet
  2263.      UserNums   CharSet
  2264.      Chars      CharSet
  2265.      Strings    CharSet
  2266.  
  2267.    Four more practical sets have also been included for your use.  To examine 
  2268.    the contents of the sets, they are located in P70-VAR.INC in an array 
  2269.    called EntrySet.  Since it is in the include file for PULL, these can only 
  2270.    be modified when you have the complete source code.
  2271.  
  2272.    Assigning Sets - Most of your work can be done by default, but once in a 
  2273.    while, a custom set will be required.  Let's change MyString to be a file 
  2274.    name with only valid DOS characters by changing the MyStringDW record to:
  2275.  
  2276.      ...
  2277.      Field         := 25;
  2278.      MaxField      := pred(sizeof(MyString));      { = 100 }
  2279.      SetName       := FileNameSet;
  2280.      SaveDataWndw;
  2281.  
  2282.    Try entering a string into the window and find that invalid characters like 
  2283.    the space, "\", and "*" can not be entered.  This gives the user immediate 
  2284.    cues about the validity of the entry before it is completely entered.
  2285.  
  2286.  
  2287.    KEY TRANSLATION
  2288.  
  2289.    As each key is entered, it is possible to intercept the keystroke before it 
  2290.    reaches the data entry editor.  This section will show how it is done.
  2291.  
  2292.  
  2293.    Translation Pointer - Each data window record has a translation pointer 
  2294.  
  2295.  
  2296.    Chapter 5, Data Windows                                             Page 38
  2297.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2298.  
  2299.  
  2300.    called TranslateProc.  You probably know by now, that the default is nil.  
  2301.    If a valid FAR procedure is assigned to this pointer, it will be executed.  
  2302.    Suppose you prefer to have the file name entries in upper case.  Modify 
  2303.    MyStringDW to:
  2304.  
  2305.      ...
  2306.      Field         := 25;
  2307.      MaxField      := pred(sizeof(MyString));      { = 100 }
  2308.      SetName       := FileNameSet;
  2309.      TranslateProc := TranslateCase;
  2310.      SaveDataWndw;
  2311.  
  2312.    Back up a few lines to find this procedure and you will see:
  2313.  
  2314.      procedure TranslateCase;
  2315.      begin
  2316.        if not ExtKey then
  2317.          Key := upcase(Key);        { Simple upper case translation }
  2318.      end;
  2319.  
  2320.    In PULL, Key is the character returned from ReadKey, and ExtKey is true if 
  2321.    it is an extended key.  Notice the far directive used to force the 
  2322.    procedure to FAR.  Run the program again and find that all keys typed in 
  2323.    this data window are forced to upper case.
  2324.  
  2325.    Every Key - All keys can be translated with this procedure.  Even global 
  2326.    or editing keys can be intercepted and translated to whatever is desired.  
  2327.    It is also useful for foreign language translation.
  2328.  
  2329.  
  2330.    RANGE CHECKING
  2331.  
  2332.    After the entry is entered and checked as valid, there is one more option 
  2333.    of checking the entry to make sure it is in the range or form that is 
  2334.    acceptable to the program.  This section will show how to create range 
  2335.    checking procedures and out of range error messages.
  2336.  
  2337.  
  2338.    Three Parts - Before setting up a range check, you need to understand how 
  2339.    the data is transferred between the entry and the variable.  There are 
  2340.    three parts to performing the data entry transfer - the data entry string, 
  2341.    data pad, and destination variable.
  2342.  
  2343.    Data Entry String - The data entry string is the string that is seen and 
  2344.    edited on the CRT.  This string is held in DataStr of type DataStrType and 
  2345.    is declared in P70-VAR.INC.
  2346.  
  2347.    Reading - The data pad, called DataPad, is a two-way messenger that 
  2348.    transfers data between the variable and DataStr.  When the data window is 
  2349.    initially displayed, the data pad reads the contents of the variable and 
  2350.    makes an exact copy of the value onto itself.  Then the program converts 
  2351.    this value over to DataStr into a string form which the user can easily 
  2352.    read and edit.
  2353.  
  2354.    Storing - As mentioned before, pressing RETURN after editing is completed, 
  2355.  
  2356.  
  2357.    Chapter 5, Data Windows                                             Page 39
  2358.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2359.  
  2360.  
  2361.    the program attempts to store the entry to the variable.  First, numeric 
  2362.    data must pass a validity check by converting DataStr to a value.  If it 
  2363.    passes, a copy of the converted data is now on the data pad.  Now is the 
  2364.    time to do a data range check.  By default, there is no check and the data 
  2365.    would continue to be stored from the data pad to the destination variable 
  2366.    as is.  But to do the range check, you need to know the identifiers that 
  2367.    are used on the data pad.
  2368.  
  2369.    Data Pad Identifiers - The data pad is completely generic.  Any type of 
  2370.    data occupies the exact same address.  So all you need to do is select the 
  2371.    right identifier to match the type of data for your variable.  You can look 
  2372.    at the data pad record in P70-VAR.INC for the field list, but here is a 
  2373.    list of those identifiers:
  2374.  
  2375.      Type       Identifier
  2376.      ---------  ----------
  2377.      Bytes      Bdata
  2378.      Words      Wdata
  2379.      ShortInts  SIdata
  2380.      Integers   Idata
  2381.      LongInts   Ldata
  2382.      Reals      Rdata
  2383.      UserNums   UNdata
  2384.      Chars      Cdata
  2385.      Strings    Sdata
  2386.  
  2387.    Example - Let's set up a range check for aByteDW.  Modify its data window 
  2388.    record to:
  2389.  
  2390.      GetDataWndw (ord(aByteDW));         { Just gets cleared DataWndw }
  2391.      ...
  2392.      Field         := 3;
  2393.      CheckRangeProc := CheckAbyte;       { add this line. }
  2394.      SaveDataWndw;                       { Saves it in the heap }
  2395.  
  2396.    Arbitrarily, let the range for aByte be between 20 and 50 inclusive.  Now 
  2397.    back up a few lines before the TranslateCase procedure and the following 
  2398.    procedure has already been added for you:
  2399.  
  2400.      procedure CheckAbyte;
  2401.      begin
  2402.        with DataPad do
  2403.          if ((Bdata<20) or (Bdata>50)) then
  2404.            MakeErrMsg (20,50);
  2405.      end;
  2406.  
  2407.    Since aByte is byte type, Bdata is used for the comparison.  For the range 
  2408.    check, any values under 20 or over 50 will run the MakeErrMsg procedure.  
  2409.    Try it and see if you can produce the error message.
  2410.  
  2411.    Error Messages - How does PULL know if an error is found?  It tests the 
  2412.    value of ErrMsg in DataPad.  If the value remains zero, then the range 
  2413.    check is passed.  Otherwise, it has failed.  And, it uses this same value 
  2414.    as the error message name.  The ErrMsgLines are much like the MsgLines 
  2415.    using names for indexes.  Right after the implementation you can see the 
  2416.  
  2417.  
  2418.    Chapter 5, Data Windows                                             Page 40
  2419.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2420.  
  2421.  
  2422.    error message names:
  2423.  
  2424.      ErrMsgNames = (NoEM,UserEM,InvalidEM,MyEM);
  2425.  
  2426.    The names up to InvalidEM are reserved.  The name UserEM is of most 
  2427.    interest.  ErrMsgLine[ord(UserEM)] is meant to be customized by creating a 
  2428.    message at run-time.  This saves you from making several hard-coded 
  2429.    messages.  The example used MakeErrMsg, located a few lines back.  It is a 
  2430.    good simple example how to set both ErrMsg and create a custom message on 
  2431.    the UserEM.  But the important value is the change of ErrMsg.
  2432.  
  2433.    Message Length - Error messages tend to be short, so there is no need to 
  2434.    allocate a full screen width for the message.  The maximum length of a 
  2435.    message is set by MaxErrStrLength in P70-VAR.INC.  The program will 
  2436.    automatically clear the remaining part of the line and takes special care 
  2437.    not to do a needless full-line clear and thereby preventing a flicker 
  2438.    effect.
  2439.  
  2440.    Maximum Message - Similarly, the maximum number of ErrMsgLines is set by 
  2441.    NumOfErrMsgLines in P70-VAR.INC.
  2442.  
  2443.    Summary - The outcome of the range check is determined by the value of 
  2444.    DataPad.ErrMsg.  PULL sets it to zero.  Compare your range with the DataPad 
  2445.    identifiers in any fashion.  Only if it is out of range, set ErrMsg to the 
  2446.    ErrMsgLine you want to show.
  2447.  
  2448.  
  2449.    HELP MESSAGES
  2450.  
  2451.    A help message can be assigned to the Data Window record exactly the same 
  2452.    as the menus.  One name has already been reserved for the Data Window 
  2453.    called DW_ML and is the default.  But you can also assign new ones.  The 
  2454.    MsgLines and names are in PULLSTAT.PAS.
  2455.  
  2456.  
  2457.    HELP WINDOWS
  2458.  
  2459.    Again, just like the menus, help windows can be assigned to the Data 
  2460.    Window.  The record name reserved for Data Window records is called 
  2461.    DataWndwHW and is the default.  If you have not seen this window, run the 
  2462.    program with a Data Window pulled and press F1.  The Help Window records 
  2463.    and Help Lines are in PULLSTAT.PAS.
  2464.  
  2465.  
  2466.    DEFAULT ATTRIBUTES AND BORDER
  2467.  
  2468.    This section will show the variables used to create default attributes and 
  2469.    border for the Data Window.
  2470.  
  2471.  
  2472.    Initialization - PULLDATA is self-initialized when it is included in the 
  2473.    USES list.  There are two procedures that set up the colors and border:
  2474.  
  2475.      SetDefaultColors - assigns colors and border to the default variables.
  2476.      InitDataColors   - assigns the defaults to the Data Window record.
  2477.  
  2478.  
  2479.    Chapter 5, Data Windows                                             Page 41
  2480.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2481.  
  2482.  
  2483.  
  2484.    SetDefaultColors - In PULLDATA, search for SetDefaultColors and see the 
  2485.    following code:
  2486.  
  2487.      DataWndwIattr  := Black+BrownBG;
  2488.      DataWndwOattr  := Yellow+BlackBG;
  2489.      DataWndwBattr  := Black+BrownBG;
  2490.      DataWndwBrdr   := HdoubleBrdr;
  2491.  
  2492.    InitDataColors - These variables in turn are assigned to the following 
  2493.    record variables in DataWndw:
  2494.  
  2495.                        Record
  2496.      Default variable  Variable   Description
  2497.      ----------------  ---------  ----------------------------
  2498.      DataWndwIattr     Iattr      Attribute for Input
  2499.      DataWndwOattr     Oattr      Attribute for Output
  2500.      DataWndwBattr     Battr      Attribute of the Border
  2501.      DataWndwBrdr      Border     Border of the window
  2502.  
  2503.    Just like the menus, this saves you from having to make the same assignment 
  2504.    to every menu record.  Try experimenting with the colors and border in the 
  2505.    shell program and see the results.  Although NoBrdr is permissible, it is 
  2506.    not suggested.
  2507.  
  2508.  
  2509.    DEFAULT LOCATION
  2510.  
  2511.    The location of a data window is placed by PULL at run time.  With the 
  2512.    slide-under configuration, the menu is placed underneath the HiLite and 
  2513.    shifted to the right 2 columns.  If necessary, it is shifted to the left to 
  2514.    prevent wraparound.  To alter this position manually, set Row and Col in 
  2515.    the menu record to your desired location.
  2516.  
  2517.  
  2518.    SUMMARY
  2519.  
  2520.    In addition to mastering the menus, you can now link data windows into the 
  2521.    menus by adding and linking data window records in PULLDATA.PAS.  You have 
  2522.    been able to address the entry variable and create a window suitable for 
  2523.    the data type including the field type and size, title, key set and 
  2524.    translation, range checking, error and help messages, and help windows.  
  2525.    With this environment in your application along with the power and speed of 
  2526.    QWIK and WNDW, your programs can match and even better professional 
  2527.    programs.
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.    Chapter 5, Data Windows                                             Page 42
  2541.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2542.  
  2543.  
  2544.    6.  D A T A   E N T R Y
  2545.  
  2546.    Data Windows in the pull-down menus are not the only place where data is 
  2547.    needed to be entered.  The work windows themselves may need several data 
  2548.    entry fields as well.  PULL simply uses a subset of Data Windows to handle 
  2549.    the job very easily.  In addition, a smart HiLite automatically knows the 
  2550.    location of each field in the window.
  2551.  
  2552.  
  2553.    DATA ENTRY vs. DATA WINDOW
  2554.  
  2555.    Data Windows have both a data entry field and a window surrounding it.  In 
  2556.    work windows, all that is needed is the data entry field.  So, to 
  2557.    distinguish between data entry in the pull-down menus and the work windows, 
  2558.    the Data Windows are only in the menus, while Data Entry will be considered 
  2559.    in this document to be in the work windows.
  2560.  
  2561.  
  2562.    DATA ENTRY RECORD
  2563.  
  2564.    One Data Entry field has already been included in the work window.  Let's 
  2565.    take a look at its record.  In PULLDATA, find GetDataEntryStats and search 
  2566.    for "with TopEntry" to see the following code:
  2567.  
  2568.      GetDataEntry (ord(aIntegerDE));
  2569.      VarAddr     := @aInteger;
  2570.      TypeOfData  := Integers;
  2571.      Row         := 2;
  2572.      Col         := 11;
  2573.      Field       := 4;
  2574.      MaxField    := 3;
  2575.      CheckRangeProc := VerifyAinteger;
  2576.    { MsgLineNum  := ord(DE_ML); }      { This is the default }
  2577.    { HelpWndwNum := ord(DataWndwHW); } { This is the default }
  2578.      SaveDataEntry;
  2579.  
  2580.    The record identifiers should look quite familiar because they are the same 
  2581.    ones use in a Data Window record.  The only differences are the Get and 
  2582.    Save procedures, because the record is of type DataEntryRec rather than 
  2583.    DataWndwRec.  If you examine these type declarations in P70-VAR.INC, you 
  2584.    will find there is a DataEntryRec inside of DataWndwRec.  So, Data Entry is 
  2585.    truly a subset of Data Windows.
  2586.  
  2587.    Variable - The variable is aInteger which is a constant declared early in 
  2588.    the file and is of type Integers.
  2589.  
  2590.    Row/Col - This time, a row and column is specified where the left column of 
  2591.    the field is to appear in the work window.  These coordinates are window 
  2592.    relative.
  2593.  
  2594.    Default Helps - Both the help message and help window are set to a default 
  2595.    so your program can be up and running without being concerned about 
  2596.    details.  Being in a different part of the pull-down menu environment, the 
  2597.    DE_ML is different from DW_ML because the function of F2 is the opposite to 
  2598.    either case.
  2599.  
  2600.  
  2601.    Chapter 6, Data Entry                                               Page 43
  2602.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2603.  
  2604.  
  2605.  
  2606.    Other Variables - All the other variables in the record should be familiar 
  2607.    to you from the explanations in the previous section on Data Windows.  So, 
  2608.    there is no need to repeat them here.
  2609.  
  2610.  
  2611.    ADDING ENTRIES
  2612.  
  2613.    Entry Record - We have already seen how to add entries with the fill-in-
  2614.    the-blank concept, so let's try adding another entry to the work window.  
  2615.    Just after the aInteger record, add the following code:
  2616.  
  2617.      GetDataEntry (ord(aRealDE));
  2618.      VarAddr     := @aReal;
  2619.      TypeOfData  := Reals;
  2620.      Row         := 3;
  2621.      Col         := 11;
  2622.      Field       := 12;
  2623.      Decimals    := 2;
  2624.      SaveDataEntry;
  2625.  
  2626.    Decimal - This variable is just for reals to format the number of decimals 
  2627.    for the output display.  If the value is negative, then no decimal is used.
  2628.  
  2629.    aReal - Be sure to set up a default value for aReal.  At the beginning of 
  2630.    PULLDATA, add the constant aReal:
  2631.  
  2632.      ...
  2633.      aInteger: integer = 200;
  2634.      aReal:    real    = 4.56e7;
  2635.  
  2636.    aRealDE - Now append the data entry record name to the DataEntryNames list 
  2637.    at the beginning of the file:
  2638.  
  2639.      DataEntryNames = (NoDE,aIntegerDE,aRealDE);
  2640.  
  2641.    Now run the code and see if it appears in the Work Window.  When it runs, 
  2642.    the field does not appear.  Why?
  2643.  
  2644.  
  2645.    DISPLAYING FIELDS
  2646.  
  2647.    Work Window - The Work Window controls what is to appear inside the window 
  2648.    and this code is in the file PULLWORK.PAS.  Note that PULLWORK uses 
  2649.    PULLDATA.  Take a look at it and search for "case WorkWndwStep" and see:
  2650.  
  2651.      ...
  2652.      WWrite (2,2,'Integer:');
  2653.      DisplayFields (ord(aIntegerDE),ord(aIntegerDE));
  2654.      WorkWndwStep := 1;
  2655.      ...
  2656.  
  2657.    DisplayFields - This is the code that displayed the Integer field.  The 
  2658.    DisplayFields procedure displays a sequence of fields in order of the list 
  2659.    of DataEntryNames.  It is declared in the interface of PULL as:
  2660.  
  2661.  
  2662.    Chapter 6, Data Entry                                               Page 44
  2663.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2664.  
  2665.  
  2666.  
  2667.      procedure DisplayFields (First,Last: word);
  2668.  
  2669.    So, what it does is display each field starting with the record First and 
  2670.    ending with Last.  Looking back in PULLWORK again, it displayed records 
  2671.    both beginning and ending with aIntegerDE.  So, it never reached aRealDE.  
  2672.    Let's modify the parameter to include aRealDE as follows:
  2673.  
  2674.      DisplayFields (ord(aIntegerDE),ord(aRealDE));
  2675.  
  2676.    Field Label - Running it, the aRealDE will be displayed this time.  But it 
  2677.    doesn't have a label, so add one to the window with:
  2678.  
  2679.      ...
  2680.      WWrite (2,2,'Integer:');
  2681.      WWrite (3,2,'Real:');
  2682.      DisplayFields (ord(aIntegerDE),ord(aRealDE));
  2683.      ...
  2684.  
  2685.    Justification - aReal now appears on the screen with the field right 
  2686.    justified.  By default, numbers are justified to the right and strings to 
  2687.    the left.  To alter this, just include your setting in the Data Entry 
  2688.    record.  Let's try left justifying aReal by adding the following code in 
  2689.    PULLDATA:
  2690.  
  2691.      GetDataEntry (ord(aRealDE));
  2692.      ...
  2693.      Decimals    := 2;
  2694.      JustifyOutput := Left;           { Add this line. }
  2695.      SaveDataEntry;
  2696.  
  2697.    Everything appears correctly on the screen.  But when we try to move the 
  2698.    HiLite, it just stays on the Integer field.  How can we make it select the 
  2699.    other field?  Real easy - keep reading.
  2700.  
  2701.  
  2702.    SEQUENTIAL ENTRY
  2703.  
  2704.    With sequential entries of several fields, PULL gives you the advantage of 
  2705.    using not just one movement with the HiLite, but both relative and 
  2706.    sequential movement.
  2707.  
  2708.  
  2709.    EnterSeq - PULL makes sequential entry as natural as can be.  In PULLWORK, 
  2710.    search for EnterSeq and see:
  2711.  
  2712.      EnterSeq (ord(aIntegerDE),ord(aIntegerDE),Start1);
  2713.  
  2714.    This procedure is also in the interface of PULL.PAS and is declared as:
  2715.  
  2716.      procedure EnterSeq (First,Last: word; VAR Start: word);
  2717.  
  2718.    EnterSeq allows you to enter a whole block of entries in the DataEntry 
  2719.    array of records where First and Last are the first and last records in the 
  2720.    block.  The aRealDE was not included in this block.  So let's modify the 
  2721.  
  2722.  
  2723.    Chapter 6, Data Entry                                               Page 45
  2724.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2725.  
  2726.  
  2727.    code to:
  2728.  
  2729.      EnterSeq (ord(aIntegerDE),ord(aRealDE),Start1);
  2730.  
  2731.    Now run the code and find that the highlight can now move freely between 
  2732.    the two fields.  That all there is to do!  PULL handles the rest, now.  
  2733.  
  2734.    Start - Start is the record where the highlight is to begin.  At the bottom 
  2735.    of the file, Start1 is initialized to aIntegerDE.  Or, Start1 could be made 
  2736.    into a typed constant with a default value.  This lets EnterSeq remember 
  2737.    where the HiLite is after using the menus.
  2738.  
  2739.    Smart HiLite Algorithms - Take a break from PULLSHEL and go back to 
  2740.    PULLDEMO.  Run the program and take a look at the work window with several 
  2741.    entries.  PULL has smart algorithms that know where all the fields are 
  2742.    located on the screen.  The HiLite can be moved freely to select any field 
  2743.    with the following keys:
  2744.  
  2745.      Keys                     Movement                   Type of Movement
  2746.      -----------------------  -------------------------  ----------------
  2747.      Left/Right Arrow         Left/Right                 Relative
  2748.      Up/Down Arrow            Up/Down nearest cursor     Relative
  2749.      Home / Ctrl Left  Arrow  First one on the row       Relative
  2750.      End  / Ctrl Right Arrow  Last one on the row        Relative
  2751.      PgUp / Ctrl Home         First in sequence          Sequential
  2752.      PgDn / Ctrl End          Last  in sequence          Sequential
  2753.      Tab / Shift Tab          Next/Previous in sequence  Sequential
  2754.  
  2755.    Relative Movement - PULL checks the block of entries to see where to move 
  2756.    the HiLite relative to the current field.  If the field is already at its 
  2757.    limit, say to the far left with the left arrow key, it does not wrap around 
  2758.    to the far right.  When the HiLite is moved up or down, PULL looks for the 
  2759.    field nearest the cursor, not the full width of the field, and also does 
  2760.    not wrap.
  2761.  
  2762.    Sequential Movement - Primarily, the Tab key is used for sequential 
  2763.    movement.  If you reach the end of the sequence, the next Tab will wrap 
  2764.    back to the first.  What determines sequential movement?  It's the order of 
  2765.    the DataEntryNames.  So, changing the sequence is as simple as reorganizing 
  2766.    the names - no interlinks between fields are necessary!  Now you can insert 
  2767.    a new field without fretting over links.
  2768.  
  2769.    Auto Tab - The value of sequential entry is the order in which you want to 
  2770.    enter fields.  After entering one field, the program should be smart enough 
  2771.    to go the next one.  With AutoTab set true, PULL will jump to the next 
  2772.    field in sequence automatically after each entry.  Let's try it again on 
  2773.    the PULLDEMO program.
  2774.  
  2775.      1. Get into the work window.
  2776.      2. Press PgUp to get to the "Byte" entry field.
  2777.      3. Enter any value in range and press RETURN.
  2778.      4. See that the HiLite is now on "Integer".
  2779.  
  2780.    To prove the point of relative and sequential movement, let's move one of 
  2781.    the fields to a different location.  In PULLDATA, search for the data entry 
  2782.  
  2783.  
  2784.    Chapter 6, Data Entry                                               Page 46
  2785.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2786.  
  2787.  
  2788.    record for aChar2DE, and change the location to:
  2789.  
  2790.      GetDataEntry (ord(aChar2DE));
  2791.      VarAddr     := @aChar2;
  2792.      TypeOfData  := Chars;
  2793.      Row         := 5;            { Change the row (was 15) }
  2794.      Col         := 5;            { Change the column (was 55) }
  2795.      ...
  2796.  
  2797.    Run PULLDEMO and see the field moved to (5,5).  Moving the up arrow as far 
  2798.    as it will go, the HiLite will end up on aChar2DE.  But when you press Tab, 
  2799.    the next field is String.  Now, suppose we want aChar2DE to be first in 
  2800.    sequence.  How easy is it?  Look for DataEntryNames at the top of the file 
  2801.    and see:
  2802.  
  2803.      DataEntryNames = (
  2804.        NoDE,aByte2DE,aWord2DE,aShortInt2DE,aInteger2DE,aLongInt2DE,aReal2DE,
  2805.        aHex2DE,aChar2DE,aString2DE,FileNameDE);
  2806.  
  2807.    There is a bunch of names here, but all we are interested in is moving 
  2808.    aChar2DE.  Move the name to be right after NoDE.  But now we have changed 
  2809.    the beginning name of the block from aByte2DE to aChar2DE.  So, go into 
  2810.    PULLWORK and do a global search and replace of aByte2DE with aChar2DE.  
  2811.    Three familiar lines will be changed.  Run the program now and see that 
  2812.    PgUp will now move the HiLite to the top and a subsequent tab will move it 
  2813.    to Byte.  This makes organizing your screen very easy.  
  2814.  
  2815.    Setting AutoTab - In PULLDATA, search for AutoTab which is right at the 
  2816.    beginning of the Data Entry records.  The current value is true.  If this 
  2817.    value is set false, then the HiLite would stay in the same field after 
  2818.    entry.
  2819.  
  2820.  
  2821.    EDIT MODE
  2822.  
  2823.    When the HiLite moves from field to field, it is in Select Mode.  But when 
  2824.    your are editing a field, it is in Edit Mode.  What exactly makes it change 
  2825.    from Select to Edit mode?  
  2826.  
  2827.  
  2828.    Overwrite vs. Edit - To overwrite the contents, just start typing the new 
  2829.    entry.  To edit the contents, the suggested key to use is the Return key.  
  2830.    When pressed, the HiLite changes color and the cursor is set past the last 
  2831.    character.
  2832.  
  2833.    Non-Extended Keys - In addition to the Return key, any non-extended key 
  2834.    will work as well and will also apply that key to the field.  For example, 
  2835.    while in select mode, if ^A is pressed, the HiLite would change into Edit 
  2836.    mode and, in addition, the cursor would be moved to the first character.
  2837.  
  2838.    Invalid Characters - If the key pressed is not a member of the entry key 
  2839.    set, it acts the same as return on the first key, but is otherwise ignored.
  2840.  
  2841.    Escape - To escape Edit mode and restore the original contents, just press 
  2842.    ESC and the HiLite will return to Select Mode.  If ESC is pressed again, 
  2843.  
  2844.  
  2845.    Chapter 6, Data Entry                                               Page 47
  2846.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2847.  
  2848.  
  2849.    the program would escape the entire sequence of entry and would return 
  2850.    control to the WorkWindow procedure.
  2851.  
  2852.  
  2853.    FIELD ATTRIBUTES
  2854.  
  2855.    There are three attributes that can be modified for the Data Entry fields - 
  2856.    the display, the edit, and the HiLite attributes.
  2857.  
  2858.  
  2859.    Default Attributes - Data Entry fields have default attributes for each 
  2860.    record just like the Data Windows.  These variables are also set in 
  2861.    SetDefaultColors and InitDataColors.
  2862.  
  2863.    SetDefaultColors - In PULLDATA, search for SetDefaultColors and see the 
  2864.    following code:
  2865.  
  2866.      DataEntryIattr  := Yellow+MagentaBG;
  2867.      DataEntryOattr  := Black+LightGrayBG;
  2868.  
  2869.    InitDataColors - These variables in turn are assigned to the following 
  2870.    record variables in DataEntry:
  2871.  
  2872.                        Record
  2873.      Default variable  Variable   Description
  2874.      ----------------  ---------  --------------------
  2875.      DataEntryIattr    Iattr      Attribute for Input
  2876.      DataEntryOattr    Oattr      Attribute for Output
  2877.  
  2878.    HiLite Bar - The HiLite attribute is set by the color on the data pad 
  2879.    called DataPad.Hattr.  This variable is right next to AutoTab in PULLDATA.  
  2880.    Rather than having both the cursor and the HiLite, the HiLite can be turned 
  2881.    off by assigning Hattr the value of SameAttr.  Then each field will appear 
  2882.    in its own display attribute.
  2883.  
  2884.  
  2885.    SINGLE ENTRY
  2886.  
  2887.    If you prefer to customize your own procedures, you can use the procedure 
  2888.    Enter in lieu of EnterSeq.  The procedure is declared in PULL as:
  2889.  
  2890.      procedure Enter (RecNum: word);
  2891.  
  2892.    This accesses the same powerful editing features as EnterSeq, but only 
  2893.    works on the one field indicated in the parameter.  It does not display the 
  2894.    fields before or after editing which must be done with DisplayFields.
  2895.  
  2896.  
  2897.    SUMMARY
  2898.  
  2899.    You have just covered enough features to master data entry in the work 
  2900.    windows or user windows.  You can enter the records, display and locate the 
  2901.    fields, control the sequence of entry, and adjust the appearance with the 
  2902.    justification and attributes.  You also learned how to direct PULL's built 
  2903.    in HiLite bar for field selection.
  2904.  
  2905.  
  2906.    Chapter 6, Data Entry                                               Page 48
  2907.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2908.  
  2909.  
  2910.    7.  W O R K   W I N D O W S
  2911.  
  2912.    The bulk of your application needs to be displayed somewhere, and the Work 
  2913.    Windows are used for this purpose.  In this section, you will discover how 
  2914.    to integrate your work window procedures in a pull-down menu environment so 
  2915.    the program can randomly access any procedure.  In addition, you can create 
  2916.    a sophisticated multi-level window environment.
  2917.  
  2918.  
  2919.    MAKING STEPS
  2920.  
  2921.    In this section, you will find how to break down procedures into individual 
  2922.    steps and still allow the flow of execution to cycle through the Key 
  2923.    dispatcher.
  2924.  
  2925.     
  2926.    Requirements - When procedures are broken down into steps, your procedures 
  2927.    can do most anything.  But each step must exit with two settings:
  2928.  
  2929.      1. Assignment made for the next WorkWndwStep.
  2930.      2. Assignment made for Key and ExtKey.
  2931.  
  2932.    Example - Let's do an example to understand the flow of execution.  Get the 
  2933.    original files for PULLDEMO.PAS - PULLWORK and PULLDATA.  Now take a look 
  2934.    at the last of PULLWORK and see:
  2935.  
  2936.      procedure WorkWndw;
  2937.      begin
  2938.        ...
  2939.        case WorkWndwStep of
  2940.          0:  ShowFields;
  2941.          1:  EditFields;
  2942.        end;
  2943.      end;
  2944.  
  2945.    With this construct, your work can be separated into different steps.  To 
  2946.    add a new step, just insert one.  To demonstrate how to create a new step, 
  2947.    let's separate the left and right columns of the data entry fields into two 
  2948.    separate steps.  So, let's add step 2:
  2949.  
  2950.        ...
  2951.          0:  ShowFields;
  2952.          1:  EditFields;
  2953.          2:  EditFields2;
  2954.        end;
  2955.  
  2956.    and change EditFields to:
  2957.  
  2958.      procedure EditFields;
  2959.      begin
  2960.        DisplayFields (ord(FileNameDE),ord(FileNameDE));
  2961.        EnterSeq (ord(aByte2DE),ord(aReal2DE),Start1);    { Change this line. }
  2962.        if Key=EscKey then                                { Add this line. }
  2963.          WorkWndwStep := 2;                              { Add this line. }
  2964.      end;
  2965.  
  2966.  
  2967.    Chapter 7, Work Windows                                             Page 49
  2968.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  2969.  
  2970.  
  2971.  
  2972.    This will isolate the sequence to the left column of fields.  And now add 
  2973.    EditFields2:
  2974.  
  2975.      procedure EditFields2;
  2976.      begin
  2977.        DisplayFields (ord(FileNameDE),ord(FileNameDE));
  2978.        EnterSeq (ord(aHex2DE),ord(FileNameDE),Start2);
  2979.        if Key=EscKey then
  2980.          WorkWndwStep := 1;
  2981.      end;
  2982.  
  2983.    Start2 has already been added for you.  Set the TP primary file to be 
  2984.    PULLDEMO.PAS.  Now try the program and see that you can only access the 
  2985.    left or right sequence of fields.  If you want to swap between the left and 
  2986.    right columns, just press ESC.
  2987.  
  2988.    Flow of Execution - ESC has been assigned inside EnterSeq as the key that 
  2989.    is used to exit the procedure.  This is called a gated exit.  Once it 
  2990.    exits, it also exits WorkWndw and goes back into PULL to analyze the 
  2991.    keystroke in a key dispatcher.  If no key combinations are used to access 
  2992.    the menus, execution will return right back to WorkWndw and into the right 
  2993.    step.  You can catch the execution flow, by testing for the Esc key right 
  2994.    after EnterSeq.  If so, then change the step as we did in the example.
  2995.  
  2996.    Menu Access - Why even bother to test the key if ESC exits EnterSeq?  The 
  2997.    Esc key is not the only key that would exit this procedure.  Any menu key 
  2998.    like F10 will also exit the same way.  So, the "if" statement is needed to 
  2999.    confirm the correct key before changing the step.
  3000.  
  3001.    Updating the Window - Did you notice that DisplayFields was used twice for 
  3002.    just one field?  Any time you exit a menu and re-enter the window, there is 
  3003.    a possibility that something may need to be updated.  And this time the 
  3004.    File name field is a possibility because it was linked to the output of the 
  3005.    file directory.  If you haven't had a chance, press Alt-D to get the 
  3006.    directory and pick a file by pressing RETURN.  The selected file name will 
  3007.    appear in the File name field.  The other link is that the file name data 
  3008.    entry field also preselects the initial file name when the directory is 
  3009.    pulled again.  But there are other alternatives than using DisplayFields 
  3010.    twice.
  3011.  
  3012.    Changing Steps - This example was quite simple.  When step 1 was complete, 
  3013.    WorkWndwStep was incremented to step 2.  When step 2 was done, it was 
  3014.    cycled back to step 1.  It continues to stay in this loop until the program 
  3015.    is terminated, or until some other procedure changes the step number.  In 
  3016.    step 0, if we had failed to assign a new step at the end of the step, the 
  3017.    program would have been locked in an infinite loop, because it never 
  3018.    accesses any keyboard input.
  3019.  
  3020.  
  3021.    READING THE KEYBOARD
  3022.  
  3023.    In some steps, the program may need keyboard input while others do not.  In 
  3024.    this section you will find out how to read the keyboard within each step.
  3025.  
  3026.  
  3027.  
  3028.    Chapter 7, Work Windows                                             Page 50
  3029.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3030.  
  3031.  
  3032.    Output-Only Step - Step 0 in the example, is an output-only step that 
  3033.    displays the fields in the window.  No keyboard input was required.  So, at 
  3034.    the end of the step, we needed to emulate a keystroke of some kind to meet 
  3035.    the Step requirements.  By setting Key to NullKey (#00), the key dispatcher 
  3036.    and will bypass a call to the menus and ignore the key.  This guarantees 
  3037.    that the flow of execution will return to back WorkWndw.  ExtKey should 
  3038.    also be set properly if a valid combination is needed.  Some keys do not 
  3039.    require it such as NullKey, EscKey, and RetKey.  See your reference book 
  3040.    for more details.
  3041.  
  3042.    Input and Output Step - Most steps will require both input and output.  
  3043.    Step 1 called EnterSeq which has a keyboard reading routine built in.  So, 
  3044.    no keystroke emulation is needed.  However, the last line in the step still 
  3045.    needs to check for a change of step.
  3046.  
  3047.    Custom Input - There will be several occasions where you will want to have 
  3048.    your own procedures that read the key board.  If you have the source code,  
  3049.    look at PULLDENT.INC for the construct of EnterSeq which looks like:
  3050.  
  3051.      repeat
  3052.        ...
  3053.        CheckForPullDown (ord(SeqML));
  3054.        ...
  3055.        CheckForPop;
  3056.      until (Key=EscKey) or Pop or PullDown;
  3057.  
  3058.    CheckForPullDown is a procedure available to you to read the key board.  
  3059.    Its parameter, MsgLineNum, will show this message while the program pauses 
  3060.    for entry.  A subroutine in CheckForPullDown is ReadKbd which can be used 
  3061.    instead.  It just reads the keyboard and does not show a message.
  3062.  
  3063.    CheckForPop - This procedure is also available to you to check if any menu 
  3064.    control flags have been set and regulates them.  If the flags indicate a 
  3065.    pop it needed, then Pop will be set true.
  3066.    
  3067.    Gated Exit - Now you can see two more possible reasons that would cause the 
  3068.    program to exit EnterSeq - Pop and PullDown.  These are the very same flags 
  3069.    used for controlling the menus.  By gating the exit, the flow of execution 
  3070.    is confined with the repeat/until construct until a control flag permits 
  3071.    the exit.  Using these two flags allow EnterSeq to be used in either the 
  3072.    Work Window or a User Window in the menus.  If the procedure is only going 
  3073.    to be used in the Work Window, then Pop is not necessary.
  3074.  
  3075.    Non-Gated Exit - The step doesn't have to be gated at all.  You can use 
  3076.    CheckForPullDown by itself if the flow of execution can continue through 
  3077.    the dispatcher every time a key is pressed.  For EnterSeq, this would not 
  3078.    work, because the HiLite would flash with each keystroke.  The next section 
  3079.    shows an example where a non-gated Exit works perfectly fine.
  3080.  
  3081.    Idle Keyboard - Rather than just letting the program just sit there and 
  3082.    wait for keyboard input, you could be letting the program do other 
  3083.    background processing.  An indirect call from PULL inside ReadKbd 
  3084.    continually runs the contents of the FAR procedure KbdIdle while no key is 
  3085.    pressed.  Although KbdIdle is seen here in PULLWORK, it can be placed in 
  3086.    any file, but it MUST be included somewhere, even if the procedure is 
  3087.  
  3088.  
  3089.    Chapter 7, Work Windows                                             Page 51
  3090.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3091.  
  3092.  
  3093.    empty.  The variable AddKbdIdle declares its address.
  3094.  
  3095.  
  3096.    MULTI-LEVEL WINDOWS
  3097.  
  3098.    One work window may not be enough for your application and others may be 
  3099.    needed.  The following example shows how to add a simple hidden Work 
  3100.    Window.
  3101.  
  3102.    Making the Step - Add step 3 to WorkWindow:
  3103.  
  3104.        ...
  3105.          2:  EditFields2;
  3106.          3:  EditWorkWndw2;   { Add this line. }
  3107.        end;
  3108.  
  3109.    Now, create this editing step to just put ASCII keys into the window.  A 
  3110.    non-gated procedure will work fine:
  3111.  
  3112.      procedure EditWorkWndw2;
  3113.      begin
  3114.        CheckForPullDown (ord(WorkML));      
  3115.        if not ExtKey then
  3116.          case Key of
  3117.            #32..#126: write (Key);
  3118.            RetKey:    writeln;
  3119.            EscKey:    HideWorkWndw;
  3120.          end;
  3121.      end;     { Non-gated exit }
  3122.  
  3123.  
  3124.    The key chosen to hide the window is ESC although any key could be assigned 
  3125.    to do this.  But we also need to initialize the second work window to be 
  3126.    available to the program.  So, add the following line to InitWorkWndws:
  3127.  
  3128.      procedure InitWorkWndws;
  3129.      begin
  3130.        ShowFields;
  3131.        MakeWorkWndw2;   { Add this line. }
  3132.        ...
  3133.      end;
  3134.  
  3135.    and then code the procedure to make a hidden window and place it just after 
  3136.    the ShowFields procedure.  (The code is already there.  Just remove the 
  3137.    braces for this example.)
  3138.  
  3139.      procedure MakeWorkWndw2;
  3140.      begin
  3141.        SetWindowModes (HiddenMode);
  3142.        MakeWindow ( 8,21,10,40,LightBlue+LightGrayBG,LightBlue+LightGrayBG,
  3143.                     DoubleBrdr,Window2);
  3144.        SetWindowModes (0);
  3145.        WriteToHidden (Window2);
  3146.        TitleWindow (Top,Left  ,SameAttr,'2');
  3147.        TitleWindow (Top,Center,SameAttr,' Press ESC to hide ');
  3148.  
  3149.  
  3150.    Chapter 7, Work Windows                                             Page 52
  3151.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3152.  
  3153.  
  3154.        TitleWindow (Top,Center,SameAttr,' Work Window 2 ');
  3155.        WWriteC (1,'Type in any input');
  3156.        WGotoRC (2,1);
  3157.        WriteToCRT;
  3158.      end;
  3159.  
  3160.    At the beginning of the PULLDEFS.INC file, let's also activate the multi-
  3161.    level work window code by shifting the "$" to the left to look like:
  3162.  
  3163.      {$define MultiWorkWndws }
  3164.  
  3165.    This activates the AccessWorkWndw procedure which simply accesses the 
  3166.    selected window set by TopWorkWndwName.  When TopWorkWndwName has changed,  
  3167.    WorkWndwStep also needs to be reset.  In the procedure ResetWorkWndwStep, 
  3168.    confirm that Window2 starts on the correct step:
  3169.  
  3170.      Window2:  WorkWndwStep := 3;
  3171.  
  3172.    Now we need some keys to get access to these windows.  Let Window1 and 
  3173.    Window2 be assigned to the Alt-1 and Alt-2 keys.  To do this, go back to 
  3174.    PULLSTAT.PAS and edit CheckGlobalKeys to the following:
  3175.  
  3176.        ...
  3177.        AltX:    SetQuit;
  3178.        Alt1:    SetWorkWndw (Window1);
  3179.        Alt2:    SetWorkWndw (Window2);
  3180.      else
  3181.      ...
  3182.  
  3183.    The constants for Alt1 and Alt2 have already been set for you.  SetWorkWndw 
  3184.    is located just before CheckGlobalKeys and looks like:
  3185.  
  3186.      procedure SetWorkWndw (WN: WindowNames);
  3187.      begin
  3188.        PullDown        := false;
  3189.        PopToWorkWndw   := true;
  3190.        TopWorkWndwName := WN;
  3191.      end;
  3192.  
  3193.    This assigns a new Work Window name for the AccessWorkWndw procedure.  Now 
  3194.    it is all set.  Give the program a run.  You will see that anytime you 
  3195.    press Alt-1 or Alt-2, it immediately accesses that window even if you are 
  3196.    in the menus!  And, when you get Window2, the contents are preserved.  If 
  3197.    you were able to program this successfully, you have attained a highly 
  3198.    sophisticated environment with little code.
  3199.  
  3200.  
  3201.    MANAGING WINDOWS
  3202.  
  3203.    We have just covered all the code necessary to have several work windows on 
  3204.    the screen at once.  To randomly access any window, the Alt keys were 
  3205.    assigned to a particular window number.  To hide a window, the Esc key was 
  3206.    used and the contents were saved.
  3207.  
  3208.    Should you decide to use temporary windows so that ESC would remove the 
  3209.  
  3210.  
  3211.    Chapter 7, Work Windows                                             Page 53
  3212.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3213.  
  3214.  
  3215.    window, just replace the two occurrences of HideWindow with RemoveWindow.  
  3216.    Of course, you could make a combination of both.  You now have the tools 
  3217.    for complete window management.
  3218.  
  3219.  
  3220.  
  3221.  
  3222.  
  3223.  
  3224.  
  3225.  
  3226.  
  3227.  
  3228.  
  3229.  
  3230.  
  3231.  
  3232.  
  3233.  
  3234.  
  3235.  
  3236.  
  3237.  
  3238.  
  3239.  
  3240.  
  3241.  
  3242.  
  3243.  
  3244.  
  3245.  
  3246.  
  3247.  
  3248.  
  3249.  
  3250.  
  3251.  
  3252.  
  3253.  
  3254.  
  3255.  
  3256.  
  3257.  
  3258.  
  3259.  
  3260.  
  3261.  
  3262.  
  3263.  
  3264.  
  3265.  
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.    Chapter 7, Work Windows                                             Page 54
  3273.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3274.  
  3275.  
  3276.    8.  U S E R   W I N D O W S
  3277.  
  3278.    While in the menus, you may have to create a window or a menu that differs 
  3279.    from the ones in PULL.  This section will show you the pull-down directory 
  3280.    included with the package and how to integrate any user window into the 
  3281.    pull-down environment.
  3282.  
  3283.  
  3284.    PULL-DOWN DIRECTORY
  3285.  
  3286.    The pull-down directory unit has already been linked into the demo.  By 
  3287.    now, you can probably figure out how the directory is accessed.  Looking in 
  3288.    the FilesMenu, find the following code:
  3289.  
  3290.      Line[3]:='~Directory';          LineMode[3]:=ToUserWndw;
  3291.                                      ProcPtr [3]:=DoDir;
  3292.  
  3293.    To pull down a user window, the line mode is set to ToUserWndw which places 
  3294.    a solid triangle symbol on that line.  Then, DoDir is the procedure that 
  3295.    will access the directory and looks like:
  3296.  
  3297.      procedure DoDir;
  3298.      begin
  3299.        { Use (FileName,FileName) to initially Hilite a close match. }
  3300.        { Use (FileName,'') to start at default. }
  3301.        PullDirectory (FileName,FileName);
  3302.      end;
  3303.  
  3304.    PullDirectory handles every thing once inside the procedure.  A particular 
  3305.    emphasis was made on end-user human factors in its development.
  3306.  
  3307.      . Single column - A single column, alphabetically sorted list is the 
  3308.        easiest to visually scan quickly.  Multi-column lists such as the one 
  3309.        provided in the TP5 environment require difficult zig-zag scanning.
  3310.  
  3311.      . Cursor key scanning - Cursor keys are the expected way to scan through 
  3312.        the directory.  In addition, Home, ^Home, End, and ^End keys only move 
  3313.        the HiLite while PgUp, ^PgUp, PgDn, and ^PgDn move only the page.
  3314.  
  3315.      . Letter key scanning - Any alpha-numeric key will scan for the first 
  3316.        file name starting with the same first letter.  The page is moved and 
  3317.        the cursor is centered as much as possible.
  3318.  
  3319.      . Lower-case text - Lower case text is more legible than the standard 
  3320.        upper-case text provided by DOS.
  3321.  
  3322.      . Right justified extension - Visual searches for extensions are easier 
  3323.        to read when aligned.  In addition, this also facilitates proper 
  3324.        alphabetic sorting.
  3325.  
  3326.      . High speed sort - The sorting routine uses is a secondary-index quick 
  3327.        sort which is the fastest kind for this application.  It is currently 
  3328.        set at a limit of 250 file names are permitted, but it can be set to 
  3329.        grow as much as your heap allows.
  3330.  
  3331.  
  3332.  
  3333.    Chapter 8, User Windows                                             Page 55
  3334.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3335.  
  3336.  
  3337.      . High speed scroll - The display is expected to be fast when scrolling 
  3338.        and is.  Neither the HiLite nor the screen ever flicker.
  3339.  
  3340.      . Default HiLite - If a value file name is passed to the directory for 
  3341.        the default other than '', the directory searches for a close match to 
  3342.        HiLite.  In either case, the HiLite is centered as much as possible.
  3343.  
  3344.      . Picked file name - Pressing CR will replace the referenced file name 
  3345.        passed to the directory.
  3346.  
  3347.  
  3348.    INTERFACE
  3349.  
  3350.    If you have the source code to PULLDIR.PAS, take a look at PullDirectory 
  3351.    and see how the code interfaces the pull-down menus.  This is an excellent 
  3352.    example of incorporating all the features to integrate with the menus:
  3353.  
  3354.      procedure PullDirectory; { (VAR NameToChange: FileNameStr;
  3355.                                      NameToHiLite: FileNameStr); }
  3356.      begin
  3357.        TurnArrows (On);                                         { 1 }
  3358.        with TopMenu do
  3359.          CmdSeq := CmdSeq+CmdLtrs[HiLiteLine];                  { 2 }
  3360.        ShowDirMenu (NameToHiLite);                              { 3 }
  3361.        repeat
  3362.          with DirectoryMenu do
  3363.            begin
  3364.              CheckForPullDown (DirectoryMenu.MsgLineNum);       { 4 }
  3365.              if ExtKey then
  3366.                begin
  3367.                  if HelpKeyPressed then
  3368.                    {$ifdef UseHelpWndwCode }
  3369.                    PullHelpWndw (HelpWndwNum)                   { 5 }
  3370.                    {$endif UseHelpWndwCode }
  3371.                  else ScanDirByCursor;
  3372.                end
  3373.              else
  3374.                if Key<>RetKey then
  3375.                  ScanDirByLetter;
  3376.              if (Key=RetKey) and (TotalFiles>0) then
  3377.                begin
  3378.                  PopToWorkWndw := true;                         { 6 }
  3379.                  { ... }
  3380.                end;
  3381.              CheckForPop                                        { 7 }
  3382.            end;  { with }
  3383.        until (Key=EscKey) or (Key=RetKey) or Pop;               { 8 }
  3384.        Key := NullKey;                                          { 9 }
  3385.        RemoveWindow;                                            { 10 }
  3386.        dec (CmdSeq[0]);                                         { 11 }
  3387.        TurnArrows (Off);                                        { 12 }
  3388.      end;
  3389.  
  3390.    Comments - Comments for the numbered lines follow.
  3391.  
  3392.  
  3393.  
  3394.    Chapter 8, User Windows                                             Page 56
  3395.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3396.  
  3397.  
  3398.      Line 1  - TurnArrows is a procedure that places arrow symbols on 
  3399.                the top menu to direct the user's attention to the new 
  3400.                menu.
  3401.      Line 2  - Append CmdSeq so that PULL can know how it got to this 
  3402.                menu.
  3403.      Line 3  - This procedure actually produces the window on the CRT 
  3404.                and it custom designed.
  3405.      Line 4  - CheckForPullDown monitors keyboard entry and displays a 
  3406.                message.
  3407.      Line 5  - You can include your custom help window here.
  3408.      Line 6  - Once the item was selected on the menu, this option 
  3409.                commands PULL to return to the top work window.  This is 
  3410.                optional.
  3411.      Line 7  - CheckForPop analyzes all the menu controls flags, 
  3412.                including PopToWorkWndw, to see if a request has been 
  3413.                made to pop out of the menu.  If so, Pop is set to true.
  3414.      Line 8  - The repeat/until construct provides a gated exit.
  3415.      Line 9  - Alter the value of Key so the next menu will ignore an 
  3416.                EscKey value.  ESC is meant to pop only one menu.  If the 
  3417.                key was not changed, the menus would continue to pop 
  3418.                until is was back into the work window.
  3419.      Line 10 - The exit has been confirmed and the window/menu needs to 
  3420.                be removed from the CRT.
  3421.      Line 11 - Adjust CmdSeq for one pop.
  3422.      Line 12 - Turn the arrows back off of the top menu.
  3423.  
  3424.    This same construct can be used for any user window/menu to be included 
  3425.    with the pull-down menus.
  3426.  
  3427.  
  3428.  
  3429.  
  3430.  
  3431.  
  3432.  
  3433.  
  3434.  
  3435.  
  3436.  
  3437.  
  3438.  
  3439.  
  3440.  
  3441.  
  3442.  
  3443.  
  3444.  
  3445.  
  3446.  
  3447.  
  3448.  
  3449.  
  3450.  
  3451.  
  3452.  
  3453.  
  3454.  
  3455.    Chapter 8, User Windows                                             Page 57
  3456.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3457.  
  3458.  
  3459.    9.  C O N D I T I O N A L   C O M P I L A T I O N
  3460.  
  3461.    Many times your application may not need to use all of the features built 
  3462.    into PULL.  Although most of the code is optimized out by the compiler, 
  3463.    some of the code is nested and it would be helpful to eliminate some of 
  3464.    that code.  This section will show you how easy it is to do this.
  3465.  
  3466.  
  3467.    DEFINE SYMBOLS
  3468.  
  3469.    Here is a complete list of the define symbols used in PULL:
  3470.  
  3471.      UseSubMenuCode   - to include submenus.
  3472.      UseHelpWndwCode  - to include help windows.
  3473.      UseDataEntryCode - to include data entry or data windows.
  3474.      UseMsgLineCode   - to include normal and error messages.
  3475.      MultiWorkWndws   - to include multi-level work windows.
  3476.  
  3477.    Location - You can find these directives defined in the PULLDEFS.INC file 
  3478.    which is includes in all *.PAS files.  Most files will not have every one 
  3479.    of them, but only the ones that affect it.
  3480.  
  3481.    Definition - When you see the define directive, it will look like:
  3482.  
  3483.      {$define UseSubMenuCode }
  3484.  
  3485.    With the "$" in its place, UseSubMenuCode would be defined and would 
  3486.    include all of the submenu code.  If you do not want the code, then 
  3487.    undefine it by just shifting the "$" to column 3:
  3488.  
  3489.      { $define UseSubMenuCode }
  3490.  
  3491.    Affected Files - Should you decide to undefine a symbol, you should 
  3492.    rebuild the program since it affects PULL.PAS as well.  You can get away 
  3493.    without rebuilding PULL on all of them except UseMsgLineCode where you must 
  3494.    rebuild PULL as well.
  3495.  
  3496.  
  3497.    RECOMPILING
  3498.  
  3499.    Once you have changed all the needed directives, do a Make and the code 
  3500.    will be ready for use.
  3501.  
  3502.  
  3503.  
  3504.  
  3505.  
  3506.  
  3507.  
  3508.  
  3509.  
  3510.  
  3511.  
  3512.  
  3513.  
  3514.  
  3515.  
  3516.    Chapter 9, Conditional Compilation                                  Page 58
  3517.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3518.  
  3519.  
  3520.    10.  T R O U B L E   S H O O T I N G
  3521.  
  3522.    PULL is a well thought out unit.  If you find that the program has not done 
  3523.    what you expected, there may be something that you overlooked.  This 
  3524.    section will try to help jog your memory as to what the problems may be.
  3525.  
  3526.  
  3527.    GOOF UNIT
  3528.      
  3529.    All programmers make mistakes, right?  So, what happens when you try to 
  3530.    make more windows than there are records available?  Since WNDW and PULL 
  3531.    are powerful tools and can even write in RAM, there is a good possibility 
  3532.    that your mistake may not even show up on the screen.  How do you know if 
  3533.    anything has gone wrong?  The GOOF unit was made especially for handling 
  3534.    errors.
  3535.  
  3536.    Displaying Errors - When an error is found in your program, the ShowGoof 
  3537.    procedure is called and the program is terminated.  The CRT will display an 
  3538.    error message in a flashing window.  There are eight fatal errors that are 
  3539.    listed in APPENDIX B in WNDWREF.DOC to identify problems before they 
  3540.    happen.  Please refer to it for the error messages and their solutions.  If 
  3541.    you do not have a copy of WNDW70A.ZIP, you can get one direct from the 
  3542.    Eagle.
  3543.  
  3544.    Flexibility - ShowGoof is accessed indirectly with an indirect call.  This 
  3545.    means that you can freely edit the GOOF unit without needing to recompile 
  3546.    WNDW or PULL.  You can even edit it for use in your own applications.  The 
  3547.    error message numbers 1-50 are reserved.  So, for your own applications, it 
  3548.    is suggested that you start with number 51.  If you have thoroughly tested 
  3549.    your program, some of the messages can be eliminated.  
  3550.  
  3551.    Using GOOF - GOOF is a locally call unit.  As long as the interface is not 
  3552.    changed, you can edit it without needing to rebuild PULL.
  3553.  
  3554.  
  3555.    FAR ADDRESSES
  3556.  
  3557.    Because PULL uses several pointers for procedures and variables, it is 
  3558.    quite possible to lock up your computer if these are not properly 
  3559.    addressed.  A debugger is most helpful in these circumstances.  But if you 
  3560.    do not have one, here is a check list of possible causes:
  3561.  
  3562.  
  3563.    Forcing FAR - The far pointers used by TranslateProc, CheckRangeProc, and 
  3564.    ProcPtr must be calling FAR procedures.  All procedures that are not 
  3565.    declared in the interface of a unit must be forced to FAR with the FAR
  3566.    directive.
  3567.  
  3568.    KbdIdle - The far procedure KbdIdle must be used and can be located in any 
  3569.    unit.  This procedure does background processing while the keyboard is 
  3570.    idle.
  3571.  
  3572.    Data - The variable address and type of data in each data record must 
  3573.    exactly match or risk possible data loss.  Strings lengths must not be 
  3574.    longer than MaxField.
  3575.  
  3576.  
  3577.    Chapter 10, Trouble Shooting                                        Page 59
  3578.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3579.  
  3580.  
  3581.  
  3582.  
  3583.    MULTI-TASKING
  3584.  
  3585.    This demo has already been set to work in multi-tasking environments 
  3586.    compatible to DESQview, TopView, and IBM 3270 PC Workstation.  It uses the 
  3587.    multi-tasking video buffer (MTVB) whenever possible.  To always disable 
  3588.    MTVB use, set PreferMultiTask to false in PULLSHEL.PAS. 
  3589.  
  3590.  
  3591.    CUSTOMER SERVICE
  3592.  
  3593.    If you are still having problems, leave us a message or give us a call.
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.  
  3607.  
  3608.  
  3609.  
  3610.  
  3611.  
  3612.  
  3613.  
  3614.  
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.    Chapter 10, Trouble Shooting                                        Page 60
  3639.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3640.  
  3641.  
  3642.    A P P E N D I X   A :   O T H E R   P R O D U C T S
  3643.  
  3644.  
  3645.    SPEEDPACK II
  3646.  
  3647.    SpeedPack II is a commercial product specifically for Borland/Turbo Pascal 
  3648.    7.0.  Here are excerpts from our press release:
  3649.  
  3650.  
  3651.    Product Name:     SpeedPack II version 7.01 (32-bit specific version)
  3652.    Product Type:     Programming Tools
  3653.    Environments:     Turbo / Borland Pascal 7.0 (DOS, DPMI, and Windows)
  3654.    Package Contents: One high-density disk
  3655.    Files on disk:    40 files plus 190 compressed files.  Includes fully disk-
  3656.                      based manuals and Windows 3.1 help files
  3657.    Disk space:       About 1.2Mb total for all environments
  3658.    Price:            $99.00 (call for discounts!)
  3659.    Guarantee:        30-day money back guarantee
  3660.    Availability:     February 15, 1993
  3661.  
  3662.  
  3663.    PRODUCT OVERVIEW:
  3664.    SpeedPack II provides the Borland Pascal programmer with easy tools to 
  3665.    significantly increase the performance of applications by advancing to 32-
  3666.    bit specific platforms in DOS, DPMI, or Windows with minimal effort.  The 
  3667.    package includes 32-bit System units and an extensive string-handling unit.
  3668.  
  3669.  
  3670.    PRODUCT DESCRIPTION:
  3671.    To increase performance, SpeedPack II allows the programmer to dedicate 
  3672.    applications for 16-bit or 32-bit platforms. The System unit in the Run-
  3673.    Time Library (RTL) has been completely rewritten to take advantage of 32-
  3674.    bit CPUs.  A one-step RTL management utility allows the programmer to 
  3675.    choose platforms using only one button while using the Borland IDE. The 
  3676.    programmer simply recompiles his program to incorporate 32-bit performance 
  3677.    without changing the source code in any way. The resulting applications are 
  3678.    100% compatible.  Additional System units have been included to increase 6-
  3679.    byte real floating point performance and precision that surpasses the 
  3680.    Borland units.  Units incorporate Borland's 7.01 maintenance version 
  3681.    changes.  
  3682.    
  3683.    The System units speed up math, reals, strings, number/string conversions, 
  3684.    text file I/O, file access, sets, heap allocation, and memory transfer.  
  3685.    Performance improvement depends on the programmer's software design. 
  3686.    Specific increases for each routine are shown below. On the "average," 
  3687.    applications may improve from 40 to 100% in speed. Utilities have been 
  3688.    included for the programmer to test the difference in performance between 
  3689.    16- and 32-bit platforms.
  3690.  
  3691.    One-step management utilities are provided for both DOS and Windows.
  3692.  
  3693.    SpeedPack II also comes with a high-speed string unit with 130 string 
  3694.    processing routines all written in assembler with 1,400,000 strings/minute 
  3695.    average speed. The unit can be used in either 16-bit or 32-bit platforms.  
  3696.    Identifiers use C-like mnemonics and are well organized. The Windows 
  3697.  
  3698.  
  3699.    Appendix A: Other Products                                          Page 61
  3700.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3701.  
  3702.  
  3703.    version includes a 350-page help file with cut-and-paste examples for each 
  3704.    routine.  Categories include case, classification, comparison, conversion, 
  3705.    find/replace, insert/delete, justification, membership, operations, 
  3706.    parsing, patterns, placement, position, quantity, sort, tabs, and ASCIIZ. 
  3707.    Many routines have match/ignore case alternates. Code usage is only 7.2kb 
  3708.    for all routines.  Complete source code is included.
  3709.  
  3710.  
  3711.                        ** OUR NON-OBJECTIVE INFORMATION **
  3712.  
  3713.    Did you see our ad in the Borland Et Cetera catalog?  It's there.  Missed 
  3714.    it?
  3715.  
  3716.    OK, Borland and Turbo Pascal programmer's, moving up to full 32-bit power 
  3717.    is just a compile away.  We're serious about how easy this is.  Push ONE 
  3718.    button and presto!  32-bit performance.  Borland only added 32-bit power to 
  3719.    their longint operations.  We added it everywhere!
  3720.  
  3721.    We spent almost three years in the development in this project and wanted 
  3722.    to make sure it was magic and effortless.  Absolutely no code changes.  
  3723.    Doesn't matter who's code you've used.  It will work the first time.  NO 
  3724.    DEBUGGING NECESSARY.
  3725.  
  3726.    And check out the string unit.  This one is extensive and WELL organized.  
  3727.    We spent quite a bit of time laying out an excellent naming scheme so all 
  3728.    the routines were easy to remember.  They'll just fall right out of your 
  3729.    memory and you'll be asking yourself "why didn't I think of something as 
  3730.    simple as this?"  And the parameters ... TOTALLY consisent and common with 
  3731.    all the other routines.  You just can't forget them.
  3732.  
  3733.    And while you're new to the string unit, we went overboard with the Windows 
  3734.    help.  The cross-references are right where you want them in a well mapped 
  3735.    out help system so you'll know right where you are.  There are demos for 
  3736.    every routines.  Lots of tips on programming strings are included -- things 
  3737.    you always wanted to know about Pascal vs. ASCIIZ, alignment affects, and 
  3738.    procedures vs. functions.
  3739.  
  3740.    With 130 routines, it covers every possibility you can think of and the 
  3741.    complete 7500 lines of assembly source code is included.
  3742.  
  3743.    How well did we do on the Windows help?  It's so well done we said, "forget 
  3744.    the manuals!"  Everything is disk-based help.  We put every possible 
  3745.    keyword into the SEARCH buttons so that they are better than any index 
  3746.    could possibly be.  And it's always at your fingertips.
  3747.  
  3748.    But remember, there's only one button to switch between our 32-bit units 
  3749.    and Borland's units.  So, how much more can we write about ONE button?
  3750.  
  3751.    Just think!  You can provide your clients with 16-bit and 32-bit versions 
  3752.    of your product.  You'll be on the edge -- state of the art.
  3753.  
  3754.    FREE!  FREE!  FREE!  You gotta give this a try.  You'll never know how much 
  3755.    faster your programs can be until you try.  Call us.  We will send you a 
  3756.    disk.  If any time within 30 days it didn't do the job you thought, send 
  3757.    the disk back and no bill.  Seriously.
  3758.  
  3759.  
  3760.    Appendix A: Other Products                                          Page 62
  3761.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3762.  
  3763.  
  3764.                     ** ACTUAL PERFORMANCE STATISTICS **
  3765.  
  3766.    ---------------------------------------------------------------------------
  3767.    SPEEDPACK II:  System Unit Performance
  3768.  
  3769.    Table 1.  Performance: Decimal / String Conversions
  3770.    Operation                       Increase        Typical
  3771.    ------------------------------- --------------- -------
  3772.    Str (scalar)                     50-205%           125%
  3773.    Str (real)                      170-250%           180%
  3774.    Str (float)                       5- 35%            20%
  3775.    Val (scalar)                      20-40%            20%
  3776.    Val (real)                       90-340%           300%
  3777.    Val (float)                      20- 55%            30%
  3778.  
  3779.    Table 2.  Performance: LongInt Arithmetic
  3780.    Operation                       Increase
  3781.    ------------------------------- --------
  3782.    Div / Mod                             5%
  3783.    *  (Multiply)                         7%
  3784.    Shl / Shr                            11%
  3785.  
  3786.    Table 3.  Performance: Real Math (6-byte reals)
  3787.    Operation                       Increase        Typical
  3788.    ------------------------------- --------------- -------
  3789.    *  (Multiply)                     -5- 70%           25%
  3790.    /  (Divide)                      170-480%          250%
  3791.    Sqr                               90-150%           95%
  3792.    +  (Add)                          -5- 70%           25%
  3793.    -  (Subtract)                     11-160%           50%
  3794.    Real Compare                       5- 10%            5%
  3795.    LongInt to Real                    5- 35%           15%
  3796.    SqRt                            480-2600%          600%
  3797.    Trunc / Round                     40-140%           80%
  3798.    Frac                              60-430%          170%
  3799.    Int                               20-135%           50%
  3800.    Ln                                60- 95%           80%
  3801.    Exp                              110-130%          125%
  3802.    Sin                               45- 55%           50%
  3803.    Cos                               50- 55%           53%
  3804.    ArcTan                            65- 95%           80%
  3805.  
  3806.    Table 4.  Performance: String Handling
  3807.    Operation                       Increase        Comments
  3808.    ------------------------------- --------------- ----------------------
  3809.    Loading, storing, moving        up to   110%    (such as ":=" )
  3810.    Comparing                       up to    75%    (such as Str1<Str2)
  3811.    Concat                          up to   105%    proportional to length
  3812.    Convert char to string                   20%
  3813.    Copy                            up to    75%    proportional to length
  3814.    Delete                          up to   600%    proportional to length
  3815.    Insert                          up to   500%    proportional to length
  3816.    Pos                             up to   340%    proportional to length
  3817.  
  3818.    Table 5.  Performance: Set Handling
  3819.  
  3820.  
  3821.    Appendix A: Other Products                                          Page 63
  3822.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3823.  
  3824.  
  3825.    Operation                       Increase        Typical
  3826.    ------------------------------- --------------- -------
  3827.    Add component                   40- 80%             60%
  3828.    Add variable range              35-480%
  3829.    Difference                      25-110%             50%
  3830.    Equality                        35-105%             50%
  3831.    Intersection                    25-140%             50%
  3832.    Subset/Superset relation        35-100%             50%
  3833.    Union                           25-120%             50%
  3834.  
  3835.    Table 6.  Performance: Random Numbers
  3836.    Operation                       Increase
  3837.    ------------------------------- --------
  3838.    Integer                           20-40%
  3839.    Real                              25-45%
  3840.    Float ($N+)                       30-50%
  3841.  
  3842.    Table 7.  Performance: Variable / Memory Handling
  3843.    Operation                               Increase
  3844.    --------------------------------------- -----------
  3845.    :=                                      up to  200%
  3846.    Functions returning arrays/records      up to  200%
  3847.    Move                                    up to  200%
  3848.    Copying objects                         up to  195%
  3849.    FillChar                                up to  295%
  3850.    MemAvail                                      5-15%
  3851.    MaxAvail                                     1000+%     (DOS)
  3852.    GetMem / New / Constructor                   15-50%     (DOS)
  3853.    FreeMem / Dispose / Destructor               30-80%     (DOS)
  3854.  
  3855.    Table 8.  Performance: File Access
  3856.    Operation                               Increase
  3857.    --------------------------------------- ----------
  3858.    Assign (text files)                          4-25%
  3859.    Assign (non-text)                           10-30%
  3860.    FilePos (record size >1)                      240%
  3861.    FileSize        (record size >1)               15%
  3862.    Read/ReadLn     (text files)            up to  30%
  3863.    Write/WriteLn   (text files)            up to  25%
  3864.  
  3865.  
  3866.    The increases listed above are compared with Borland's Turbo Pascal or 
  3867.    Borland Pascal 7.0 using Eagle's 32-bit Enhanced System unit.  Gains are 
  3868.    highly dependent on software design, value variations, data alignment, CPU 
  3869.    level and CPU / Disk caching combinations.  Turbo Pascal is a trademark of 
  3870.    Borland International.
  3871.  
  3872.  
  3873.  
  3874.  
  3875.  
  3876.  
  3877.  
  3878.  
  3879.  
  3880.  
  3881.  
  3882.    Appendix A: Other Products                                          Page 64
  3883.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3884.  
  3885.  
  3886.    SPEEDPACK II:  String Unit Routines
  3887.  
  3888.  
  3889.    Table 1.  Routines: Strg Unit
  3890.    Group           Description                             Routines
  3891.    --------------- --------------------------------------- -------------------
  3892.    Classification  Classifies characters similar to C.     IsAlNum, IsAlpha,
  3893.                    Special routines also classify valid    IsASCII, IsCntrl,
  3894.                    DOS, path, and file name characters.    IsDigit, IsDos,
  3895.                                                            IsFile,  IsGraph,
  3896.                                                            IsLower, IsPath,
  3897.                                                            IsPrint, IsPunct,
  3898.                                                            IsReal,  IsSigned,
  3899.                                                            IsSpace, IsUpper,
  3900.                                                            IsXDigit
  3901.  
  3902.    Comparison      Compares two substrings at a given      StrCmp, StrCmpI
  3903.                    index combined with match/ignore case.
  3904.  
  3905.    Conversion      Converts Pascal strings to or from      StrBin,  StrHex,
  3906.                    binary/hex numbers, ASCII text, ASCIIZ, ValBin,  ValHex,
  3907.                    and embedded tabs.  In-situ routines    AscStr,  StrAsc,
  3908.                    allows Pascal and ASCIIZ to be used     ChrAppZ, ChrLenZ,
  3909.                    interchangeably.                        LnStr,   StrLn,
  3910.                                                            StrReTab,StrDeTab
  3911.  
  3912.    Find / Replace  Finds a given character or substring    ChrRepl, ChrReplI,
  3913.                    and replaces it with another one,       StrRepl, StrReplI
  3914.                    combined with match/ignore case and
  3915.                    overflow recovery.
  3916.  
  3917.    Insert / Delete Includes leading, trailing, padding,    ChrDel,  ChrDelL,
  3918.                    centering, and truncation routines.     ChrDelR, ChrIns,
  3919.                                                            ChrInsL, ChrInsR,
  3920.                                                            ChrPadC, ChrPadL,
  3921.                                                            ChrPadR, StrCut,
  3922.                                                            StrIns
  3923.  
  3924.    Justification   Pads strings for left-, right-, or      StrJL, StrJR, StrJC
  3925.                    center-justification.
  3926.  
  3927.    Membership      Searches for membership or              ChrSpnL, ChrSpnLI,
  3928.                    non-membership.  Reduces a string to    ChrSpnR, ChrSpnRI,
  3929.                    its members.                            StrBrk,  StrSpn,
  3930.                                                            StrMemb
  3931.  
  3932.    Operations      Operates directly on the existing       StrCap,  StrLwr,
  3933.                    characters in the string for case,      StrUpr,  StrRev,
  3934.                    reverse, roll, and sort.                StrRoll, StrSort,
  3935.                                                            LoCase,  UpCase
  3936.  
  3937.    Parsing         Counts, finds, and parses words         WrdQty,   WrdPosL,
  3938.                    separated by spaces or a custom group   WrdPosR,  WrdPosLX,
  3939.                    of delimiters.                          WrdPosRX, WrdL, WrdR,
  3940.                                                            WrdLX,    WrdRX,
  3941.  
  3942.  
  3943.    Appendix A: Other Products                                          Page 65
  3944.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  3945.  
  3946.  
  3947.                                                            WrdParse, WrdToken
  3948.  
  3949.    Pattern         Creates strings with repetitive         ChrFill, StrFill,
  3950.                    patterns of concatenation or            StrEnum
  3951.                    enumeration.
  3952.  
  3953.    Placement       Copies, moves, and concatenates         ChrCat,  ChrCatZ,
  3954.                    quickly.  Includes overwrite routines   ChrOvr,  StrCat,
  3955.                    with left-, right- and center-          StrCatV, StrCatX,
  3956.                    justification.                          StrCpy,  StrEnd,
  3957.                                                            StrMov,  StrOvrC,
  3958.                                                            StrOvrL, StrOvrR,
  3959.                                                            StrPeek, StrPoke
  3960.  
  3961.    Position        Locates the position of multiple        ChrPosL,  ChrPosLI,
  3962.                    occurrences of a substring searching    ChrPosR,  ChrPosRI,
  3963.                    from left or right, or from an index,   ChrPosRX, ChrPosRXI,
  3964.                    combined with match/ignore case.        ChrPosX,  ChrPosXI,
  3965.                                                            StrPosL,  StrPosLI,
  3966.                                                            StrPosR,  StrPosRI,
  3967.                                                            StrPosX,  StrPosXI
  3968.  
  3969.    Quantity        Counts the occurrences of a single      ChrQty, ChrQtyI,
  3970.                    character or substring combined with    StrQty, StrQtyI
  3971.                    match/ignore case.
  3972.  
  3973.    Standard        Substitutes faster standard routines    Copy, Delete, Pos
  3974.                    if the Sys unit is not used.
  3975.  
  3976.    Str Functions   Provides function forms of the          StrC, StrCF, StrCFD,
  3977.                    standard Str procedure for all numbers  StrD, StrDF, StrDFD,
  3978.                    including scalars, Turbo reals and      StrE, StrEF, StrEFD,
  3979.                    IEEE reals.                             StrL, StrLF, StrR,
  3980.                                                            StrRF, StrRFD, StrS,
  3981.                                                            StrSF, StrSFD
  3982.  
  3983.     * 7500 lines of assembly source code included.
  3984.     * Alternative routines offer different strategies for faster processing.
  3985.     * Fully optimized object files permit smart linking.
  3986.     * Compiles in DOS, DPMI, and Windows (protected modes).
  3987.  
  3988.  
  3989.  
  3990.  
  3991.  
  3992.  
  3993.  
  3994.  
  3995.  
  3996.  
  3997.  
  3998.  
  3999.  
  4000.  
  4001.  
  4002.  
  4003.  
  4004.    Appendix A: Other Products                                          Page 66
  4005.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4006.  
  4007.  
  4008.    ACTUAL PERFORMANCE TESTS FOR THE FOLLOWING CONDITIONS ON A 486/25MHZ MACHINE:
  4009.    (386 tests will be faster)
  4010.  
  4011.    ============================================================================
  4012.               BP7 PERFORMANCE GAIN OF SPEEDPACK II IN DOS (w/o IEEE)
  4013.    ============================================================================
  4014.    Please note that these gains are ARBITRARY. They do not reflect the full 
  4015.    range or even an average gain of what can be expected in your own programs.  
  4016.    Gains are highly dependent on software design, the values used, as well as 
  4017.    the CPU level and CPU caching combination used.  For example, file management 
  4018.    routines will reveal greater gains when SmartDrive is not used, because this 
  4019.    program does not put it to task.
  4020.  
  4021.    The value of 0% means 0 gain while 100% means twice as fast.
  4022.  
  4023.                                                     --- TIME (ms) ---
  4024.    TEST DESCRIPTION                                  Borland    Eagle    GAIN
  4025.    ---- ------------------------------------------- -------- -------- -------
  4026.      1: Str for LongInt                                0.124    0.085     45%
  4027.      2: Str for 6-byte/IEEE reals with no exponent     0.280    0.115    144%
  4028.      3: Str for 6-byte/IEEE reals with exponent        0.298    0.105    184%
  4029.      4: Val for LongInt                                0.090    0.070     29%
  4030.      5: Val for 6-byte/IEEE reals with no exponent     0.520    0.108    381%
  4031.      6: Val for 6-byte/IEEE reals with exponent        0.494    0.130    280%
  4032.      7: Div/Mod for LongInt                            0.039    0.038      4%
  4033.      8: *       for LongInt                            0.027    0.025      7%
  4034.      9: Sqr     for LongInt                            0.041    0.041      0%
  4035.     10: Shl/Shr for LongInt                            0.839    0.755     11%
  4036.     11: /   for 6-byte reals only                      0.268    0.094    186%
  4037.     12: *   for 6-byte reals only                      0.074    0.056     31%
  4038.     13: Sqr for 6-byte reals only                      0.047    0.024     93%
  4039.     14: +   for 6-byte reals only                      0.042    0.030     39%
  4040.     15: -   for 6-byte reals only                      0.067    0.043     57%
  4041.     16: Typecast LongInt into 6-byte reals only        0.816    0.693     18%
  4042.     17: Trunc/Round only 6-byte reals to LongInt       0.023    0.013     80%
  4043.     18: Frac   for 6-byte reals only                   0.062    0.022    185%
  4044.     19: Int    for 6-byte reals only                   0.019    0.014     35%
  4045.     20: SqRt   for 6-byte reals only                   1.293    0.203    538%
  4046.     21: Ln     for 6-byte reals only                   1.147    0.623     84%
  4047.     22: Exp    for 6-byte reals only                   2.458    1.192    106%
  4048.     23: Sin    for 6-byte reals only                   0.898    0.582     54%
  4049.     24: Cos    for 6-byte reals only                   0.949    0.589     61%
  4050.     25: ArcTan for 6-byte reals only                   2.137    1.183     81%
  4051.     26: ":="   for strings                             0.043    0.022     96%
  4052.     27: String comparison                              0.080    0.046     75%
  4053.     28: "+"    for strings                             0.085    0.040    113%
  4054.     29: Convert char to string                         0.120    0.091     31%
  4055.     30: Copy   for strings                             0.060    0.037     64%
  4056.     31: Insert for strings                             0.127    0.018    591%
  4057.     32: Delete for strings                             0.118    0.014    729%
  4058.     33: Pos    for strings                             0.097    0.096      2%
  4059.     34: +      for sets (single component)             1.496    0.888     68%
  4060.     35: [a..b] for sets (variable range)               0.246    0.052    373%
  4061.     36: -      for sets                                1.555    0.887     75%
  4062.     37: *      for sets                                1.492    0.857     74%
  4063.  
  4064.  
  4065.    Appendix A: Other Products                                          Page 67
  4066.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4067.  
  4068.  
  4069.     38: +      for sets                                1.488    0.862     73%
  4070.     39: =      for sets                                0.387    0.272     42%
  4071.     40: <=     for sets                                0.808    0.399    103%
  4072.     41: In     for sets                                0.126    0.123      2%
  4073.     42: :=     for sets                                0.644    0.520     24%
  4074.     43: Random integers                                0.893    0.637     40%
  4075.     44: Random 6-byte/IEEE reals                       0.247    0.198     25%
  4076.     45: ":=" array assignment                          9.474    3.178    198%
  4077.     46: Move array                                     9.474    3.181    198%
  4078.     47: Fill array                                    10.584    2.653    299%
  4079.     48: MaxAvail                                       0.852    0.009   9145%
  4080.     49: MemAvail                                       0.943    0.815     16%
  4081.     50: GetMem, New, Constructor  (random)             1.270    1.122     13%
  4082.     51: GetMem, New, Constructor  (sequential)         2.341    1.907     23%
  4083.     52: FreeMem, Dispose, Destructor (random)          5.344    4.368     22%
  4084.     53: FreeMem, Dispose, Destructor (sequential)      3.307    2.596     27%
  4085.     54: Assign        (text files)                     1.760    0.525    235%
  4086.     55: Assign        (non-text files)                 1.728    1.049     65%
  4087.     56: FilePos       (record size >1)                 9.294    3.166    194%
  4088.     57: FileSize      (record size >1)                 9.066    8.559      6%
  4089.     58: Write/WriteLn (text files)                    66.454   51.563     29%
  4090.     59: Read/ReadLn   (text files)                    22.087   17.694     25%
  4091.    ---- ------------------------------------------- -------- -------- -------
  4092.     60: Total gain for this program:                 177.141  115.279     54%
  4093.         Unweighted average gain (59 tests)                               269%
  4094.  
  4095.  
  4096.  
  4097.  
  4098.  
  4099.  
  4100.  
  4101.  
  4102.  
  4103.  
  4104.  
  4105.  
  4106.  
  4107.  
  4108.  
  4109.  
  4110.  
  4111.  
  4112.  
  4113.  
  4114.  
  4115.  
  4116.  
  4117.  
  4118.  
  4119.  
  4120.  
  4121.  
  4122.  
  4123.  
  4124.  
  4125.  
  4126.    Appendix A: Other Products                                          Page 68
  4127.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4128.  
  4129.  
  4130.    Eagle Performance Software has developed identical products for both 
  4131.    Turbo C and Turbo Pascal.  Our pledge is to provide you quality products 
  4132.    with unparalleled performance and ease of use.  All registered users 
  4133.    receive the complete source code when a signed license agreement is 
  4134.    returned.
  4135.  
  4136.  
  4137.    QWIK
  4138.  
  4139.    QWIK - For direct screen video, QWIK is the highest performance screen 
  4140.    writing tools available today for all text modes in any video 
  4141.    configuration.  QWIK provides capabilities far beyond those in the 
  4142.    unit/library that comes with your compiler.   Here are some of the 
  4143.    features:
  4144.                 
  4145.      - Writes on all IBM compatible computers, displays and adapters 
  4146.        including MDA, CGA, EGA, MCGA, VGA, 8514/A, Hercules and 3270 PC.
  4147.      - Works in DOS and DPMI.
  4148.      - Superior video detection routine.
  4149.      - Eliminates snow and flicker.
  4150.      - Writes directly to the screen in absolute rather than relative 
  4151.        coordinates.
  4152.      - Writes in all text modes and column modes.
  4153.      - Writes on all video pages.
  4154.      - Writes on virtual screens in RAM.
  4155.      - Writes text and attribute, text only, or attribute only.
  4156.      - Reads strings, characters and attributes.
  4157.      - Uses End-Of-String (EOS) marker for quick string chaining.
  4158.      - Provides standardized cursor shapes for all adapters.
  4159.      - Enhanced cursor movement.
  4160.      - Compatible with DESQview and similar multitasking environments.
  4161.      - Over 650% faster than standard direct screen writing.
  4162.      - Only 2.9k bytes of code if all 43 utilities are used.
  4163.      - Optimized by the compiler and drops unused code.
  4164.      - Used in all other Eagle products.
  4165.      - Excellent documentation like this document.
  4166.  
  4167.    Here are the product versions:
  4168.  
  4169.       File name    CIS Name    Compiler  Release date
  4170.       -----------  ----------  --------  ------------
  4171.       QWIK71.ZIP   QWIK71.ZIP  BP7        05-27-93
  4172.       QWIKC21.ARC  QWKC21.ARC  TC2        07-06-89
  4173.  
  4174.  
  4175.    WNDW
  4176.  
  4177.    WNDW - For multi-level virtual windows, WNDW is the highest performance 
  4178.    window utilities available today.  It offers very powerful utilities for 
  4179.    full window control and management you probably never thought possible.  
  4180.    They are simple and yet very powerful with high speed and tight code.  With 
  4181.    WNDW, you can choose the absolute writing routines of QWIK, the window-
  4182.    relative writing routines of WNDW, and even customize your own.  Here are 
  4183.    some of the features you will discover:
  4184.  
  4185.  
  4186.  
  4187.    Appendix A: Other Products                                          Page 69
  4188.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4189.  
  4190.  
  4191.      - Uses the powerful direct screen writing routines of QWIK.
  4192.      - Works in DOS and DPMI.
  4193.      - Ideal for small projects.
  4194.      - Up to 254 fixed or virtual windows can be on the screen at one 
  4195.        time.
  4196.      - Extremely high-speed virtual screens in RAM (up to 40 times 
  4197.        faster).
  4198.      - Virtual windows are fully updated on screen, even if covered.  
  4199.        Screens can scroll underneath one another right on the screen at 
  4200.        very high speeds!
  4201.      - Virtual windows have virtual titles.
  4202.      - Fully supported hidden windows saved in RAM.
  4203.      - Fully supports all video pages.
  4204.      - Adjustable-rate moving, resizing, and scrolling.
  4205.      - All windows can be randomly accessed, not just stacked or tiled.
  4206.      - 28 window-relative writing routines.
  4207.      - 15 different border styles with shadow and zoom effects.
  4208.      - Full line drawing procedures.
  4209.      - Full cursor mode control for each window.
  4210.      - Writes in all text modes and column modes.
  4211.      - Writes direct to multi-tasking video buffers (MTVB).
  4212.      - Only 13k bytes of code if all 69 utilities are used.
  4213.      - Used in all other Eagle products.
  4214.      - Excellent documentation like this document.
  4215.  
  4216.    Here are the product versions:
  4217.  
  4218.       File name    CIS Name    Compiler  Release date
  4219.       -----------  ----------  --------  ------------
  4220.       WNDW70A.ZIP  WNDW70.ZIP  TP/BP7     06-10-93
  4221.       WNDWC21.ARC  WNDC21.ARC  TC2        08-01-89
  4222.  
  4223.  
  4224.    PULL
  4225.  
  4226.    Here are the product versions:
  4227.  
  4228.       File name    CIS name    Compiler  Release date
  4229.       -----------  ----------  --------  ------------
  4230.       PULL70.ZIP   PULL70.ZIP  TP/BP7    06-21-93
  4231.       PULLC20.ZIP  PULC20.ZIP  TC2        TBA
  4232.  
  4233.  
  4234.    ON-LINE SERVICES
  4235.  
  4236.    CompuServe - All updated files and later versions can be found on the 
  4237.    CompuServe Borland Forums (GO BPASCAL for BP7 and GO BCPPDOS for TC).
  4238.  
  4239.  
  4240.    RELEASE DATES
  4241.  
  4242.    Please note that some of the release dates are only estimates.
  4243.  
  4244.  
  4245.  
  4246.  
  4247.  
  4248.    Appendix A: Other Products                                          Page 70
  4249.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4250.  
  4251.  
  4252.    A P P E N D I X   B :   R E V I S I O N   H I S T O R Y
  4253.  
  4254.    REVISIONS:
  4255.  
  4256.    Version 1.1 (02-27-87): Initial release
  4257.    Version 1.2 (04-08-87): limited release
  4258.    Version 1.3 (04-20-87)
  4259.    Version 1.4 (06-30-87): limited release
  4260.    Version 1.5 (08-31-87):
  4261.  
  4262.    Version 2.0 (01-12-88):
  4263.      . Converted to TP4 and incorporated QWIK40 and PULL40.
  4264.      . Added pull-down directory with path and mask.
  4265.      . Added global keys like Alt-F and Alt-X in PULLSTAT.PAS.
  4266.      . Eliminated PULLUSER.INC and instead allow access to user 
  4267.          windows direct through PullProc.Process.
  4268.      . Menu partitions now use Wndw.BrdrRec.
  4269.      . Added TypeOfDataTypes Word and LongInt.
  4270.      . Added "ClearScreen" option in InitPull.
  4271.      . Deleted i and j variables in PULL20.PAS.
  4272.      . Modified Pull.TempMsg; Deleted TempMsgArray.
  4273.      . Top menu record is available from TopMenuRecPtr^.
  4274.  
  4275.    Version 4.2 (01-03-89):
  4276.      . Incorporated QWIK42 and WNDW42.
  4277.      . Added excellent documentation.
  4278.      . Expanded the fill-in-the-blank concept.
  4279.      . Simplified work window data entry with sequential data entry
  4280.        routines.
  4281.      . Changed data windows to the slide-under configuration.
  4282.      . Added complete editing in data entry fields.
  4283.      . Added custom set control for data entry and deleted UserStrings.
  4284.      . Added key translation and range checking pointers.
  4285.      . Added multi-level window control.
  4286.      . Deleted PullProc.pas and the Process and Transfer procedures and
  4287.        replaced them with pointers.
  4288.      . Added automatic menu and line counting.
  4289.      . Simplified Menu Modes with execution pointers.
  4290.      . Changed menu records from global to dynamic data.
  4291.      . Improved submenu linking following the direction trend of the parent 
  4292.        menu.
  4293.  
  4294.    Version 5.X (01-07-89):
  4295.      . Compiled PULL42 under TP5.  No other changes.
  4296.  
  4297.    Version 5.Xa (01-11-89):
  4298.      . Corrected right-arrow key problem in data entry (P5X-DATA.INC).
  4299.      . Improved cursor mode handling during dynamic updates.
  4300.  
  4301.    Version 5.Xb (03-04-89):
  4302.      . Incorporated QWIK5XA and WNDW5XB for multi-tasking.
  4303.      . Added new LineModeType of NoChoice for dynamic disabling of any 
  4304.        line.
  4305.  
  4306.  
  4307.  
  4308.  
  4309.    Appendix B: Revision History                                        Page 71
  4310.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4311.  
  4312.  
  4313.    Version 5.Xc (05-29-89):
  4314.      . Incorporated WNDW70.  No other changes.
  4315.  
  4316.    Version 7.0 (06-21-93):
  4317.      . Revised menu symbols to be more in line with SAA.
  4318.      . Revised Top menu alignment with main menus.
  4319.      . Added transparent shadows.
  4320.      . Added a slide-up / slide-under option for submenus in the 
  4321.        initialization using the variable DefaultLinkDir.
  4322.      . Automated command key initialization using the tilde character.
  4323.      . Added status message highlighting.
  4324.      . Updated source code to use new Borland Pascal 7.0 features.
  4325.      . Updated source code to optionally use Eagle's STRG unit in 
  4326.        SpeedPack II.
  4327.  
  4328.  
  4329.  
  4330.  
  4331.  
  4332.  
  4333.  
  4334.  
  4335.  
  4336.  
  4337.  
  4338.  
  4339.  
  4340.  
  4341.  
  4342.  
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.  
  4352.  
  4353.  
  4354.  
  4355.  
  4356.  
  4357.  
  4358.  
  4359.  
  4360.  
  4361.  
  4362.  
  4363.  
  4364.  
  4365.  
  4366.  
  4367.  
  4368.  
  4369.  
  4370.    Appendix B: Revision History                                        Page 72
  4371.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4372.  
  4373.  
  4374.    A P P E N D I X   C :   C R E D I T S
  4375.  
  4376.    Art Hill started some initial ideas on this with PullDown.arc
  4377.  
  4378.       Art Hill 
  4379.       936 S. Kensington Ave.
  4380.       La Grange, IL 60525
  4381.       CIS 72307,3570
  4382.  
  4383.    Copyright (c) 1986,1993 by James H. LeMay for Eagle Performance Software.
  4384.    All Rights Reserved.  Protected by the United States Copyright Laws.
  4385.  
  4386.    Turbo Pascal and Borland Pascal are trademarks of Borland International.
  4387.    WordStar is a trademark of MicroPro International.
  4388.  
  4389.  
  4390.  
  4391.  
  4392.  
  4393.  
  4394.  
  4395.  
  4396.  
  4397.  
  4398.  
  4399.  
  4400.  
  4401.  
  4402.  
  4403.  
  4404.  
  4405.  
  4406.  
  4407.  
  4408.  
  4409.  
  4410.  
  4411.  
  4412.  
  4413.  
  4414.  
  4415.  
  4416.  
  4417.  
  4418.  
  4419.  
  4420.  
  4421.  
  4422.  
  4423.  
  4424.  
  4425.  
  4426.  
  4427.  
  4428.  
  4429.  
  4430.  
  4431.    Appendix C: Credits                                                 Page 73
  4432.    PULL Multi-level Pull-Down Menus                  User's Guide, Version 7.0
  4433.  
  4434.  
  4435.    A P P E N D I X   D :   G L O S S A R Y
  4436.  
  4437.    Command letter - A letter highlighted in a menu that executes that line.
  4438.    Command sequence - The sequence of command letters pressed to arrive at a 
  4439.                    window or menu.
  4440.    Data entry    - Field for entering data into the application program in the 
  4441.                    work windows or user windows.
  4442.    Data window   - Window for entering data into the application program from 
  4443.                    the menus.
  4444.    Error message - A short message for data out of range.
  4445.    Field         - A highlighted area reserved for a data entry string to be 
  4446.                    displayed.
  4447.    Flex field    - A field that allows more characters into the data entry 
  4448.                    than what the field displays.
  4449.    Free field    - A field that allows a continuous string of characters to 
  4450.                    expand in the field in any position.  This is in contrast 
  4451.                    to formatted fields where each column is designated an 
  4452.                    entry.
  4453.    Local key     - A key that only works within the menu or window.
  4454.    Gated exit    - A procedure that lets the flow of execution pass through 
  4455.                    back to PULL's key dispatcher only on specific keystrokes.
  4456.    Global key    - A key that accesses a different part of the program at any 
  4457.                    time.
  4458.    Help message  - A message appear on the message line for keyboard 
  4459.                    instructions.
  4460.    Help window   - A window displayed by pressing F1 that provides context-
  4461.                    sensitive help.
  4462.    HiLited       - A highlighted bar pointed at in a menu.
  4463.    Level         - A window or menu where the program is operating.
  4464.    Line          - A row of text.
  4465.    Link          - A menu line showing a symbol (ellipsis or solid triangle) 
  4466.                    that pulls another menu or window.  The solid triangle 
  4467.                    symbol is also on the same side where it is pulled.
  4468.    Main menu     - The first menu pulled from the Top Line menu.
  4469.    Menu          - A list of selectable lines.
  4470.    Message line  - The bottom row to display key helps or processing status.
  4471.    MTVB          - Multi-Tasking Video Buffer used in multi-tasking 
  4472.                    environments.
  4473.    Pop           - removes menu and returns to the previous menu.
  4474.    PullDown      - pulls menus down to the previous level.
  4475.    Selection     - A line selected in a menu with a CR.
  4476.    Shell         - A bare bones program of pull-down menus to get you started 
  4477.                    in your own application.
  4478.    Slide-under   - The configuration of data windows them to slide under the 
  4479.                    HiLite if the field grows wider.
  4480.    Slide-up      - The configuration of submenus that allows them to slide 
  4481.                    upward as the menu list grows.
  4482.    Submenu       - All subsequent menus pulled after a main menu.
  4483.    Title line    - A optional line reserved for status information pertinent 
  4484.                    to your program.
  4485.    Top Line menu - The menu always shown (usually in row 1 or 2).
  4486.    Window        - Not a menu.
  4487.    Work window   - The window where the bulk of the application is shown.
  4488.  
  4489.  
  4490.  
  4491.    Appendix D: Glossary                                                Page 74
  4492.