home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 26 / CD_ASCQ_26_1295.iso / vrac / tvme30.zip / MANUAL.DOC < prev    next >
Text File  |  1995-08-02  |  230KB  |  4,590 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.                        Virtual Memory Text Editor Classes
  11.                                 For Turbo Vision
  12.                                (Shareware Edition)
  13.  
  14.                                   Eric Woodruff
  15.                               16719 Lakeside Drive
  16.                               Medical Lake WA 99022
  17.  
  18.                         Copyright (c) 1994, Eric Woodruff
  19.                                All rights reserved
  20.  
  21.                         CompuServe ID: 72134,1150
  22.                              Internet: 72134.1150@compuserve.com
  23.  
  24.                               Version: 3.00
  25.                              Released: Wed 08/02/95
  26.                             Compilers: Borland C++ 3.1 to 4.xx
  27.                          Turbo Vision: 1.03 or 2.0
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.      Description
  36.      ===========
  37.          These classes are intended as a total replacement for the default
  38.      Turbo Vision editor classes TEditor, TMemo, TFileEditor, TEditWindow,
  39.      and TIndicator.  While the basic Turbo Vision editor classes are a
  40.      good start for basic editing, I found them to be seriously lacking for
  41.      larger jobs.  The biggest problems are a size limit of 64K, a tendency
  42.      to consume more memory than required, a lack of some necessary editing
  43.      features such as word wrapping and printing, limited undo/redo
  44.      capabilities, and I had a hard time in general deriving a new editor
  45.      class that would accomplish what I needed.
  46.          I had kicked around the idea of doing another editor for Turbo
  47.      Vision for ages and actually made a start by trying to make the
  48.      existing code use virtual memory.  To be blunt, that was a total PITA
  49.      and I gave up after a couple of tries.  After several months, I
  50.      finally came back to the project with a different approach altogether
  51.      and TVMEditor finally became reality.
  52.           The class definition and code used for the editor are radically
  53.      different and were written from scratch.  However, I did try to keep
  54.      the class variable names, constants, #defines and, where possible, the
  55.      function names the same.  I started out with the basic editing
  56.      functions found in the original TEditor and, as I am inclined to do,
  57.      found all kinds of other features that could be added or improved
  58.      upon.  As this editor bears no relation to the original TEditor, be
  59.      aware that a number of variables and functions where dropped from the
  60.      class definitions because they no longer had purpose.  I have also
  61.      made some of the functions inline or virtual as I deemed necessary and
  62.      there are a number of additions that aren't found in the original.
  63.          TVMEditWindow, TVMFileEditor, and TVMMemo, do not differ too much
  64.      from the originals although they benefit from several enhancements
  65.      that I will describe later on.  Of the three, TVMMemo is the most
  66.      different in usage, but those differences greatly expand its
  67.      flexibility and capabilities.
  68.          Instantiating a TVMEditor-type object should not be all that
  69.      different from instantiating a TEditor-type object.  The constructors
  70.      are fairly similar, but there are extra parameters available.  Most of
  71.      those have default values and may not need to be specified anyway. 
  72.      There is a demo program included, so it should give you a good idea of
  73.      how they can be used.
  74.           As I said to start with, these classes are complete replacements
  75.      for their original counterparts.  They *cannot* be used in conjunction
  76.      with their original TEditor ancestors due to the duplication of some
  77.      constants' names and/or reassignment of values.  The duplication of
  78.      names was intentionally done to provide some compatibility with any
  79.      existing code that uses TEditor.
  80.          Because of the restriction of mixing the old and new classes, I
  81.      have packed as much functionality and flexibility as possible into the
  82.      basic editor classes.  I hope you will find as I have that the basic
  83.      editor classes will serve a multitude of applications without the need
  84.      to derive new classes from them except for very specialized purposes. 
  85.      I have created editor classes that only overcome the limitations of
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.      the originals that I could find.  Others may still see limitations in
  94.      these ones that I do not.  If you think something is lacking, let me
  95.      know and I will try to add the missing capability.  However, bear in
  96.      mind that this is not intended to replace any commercial text editors
  97.      or word processors.  It is simply intended to provide a solid base for
  98.      drop-in text editing that can be used in your applications for
  99.      whatever purpose you need.
  100.          In short, here are some of the new capabilities:  Can use virtual
  101.      memory (EMS + disk or XMS + disk), implements buffer sharing for
  102.      instances editing the same file,  can load more than 32,767 lines,
  103.      extended editing capabilities, separate global and local editor
  104.      options, enter matching, find matching, jump to specific/relative
  105.      line, bookmarks, soft tabs or hard tabs with variable size, a choice
  106.      of persistent or non-persistent marked block, all new search and
  107.      replace capabilities, basic and automatic word wrapping, paragraph
  108.      reformatting, reformat on window resize, and lots more.  Complete
  109.      details can be found below for each class.
  110.  
  111.  
  112.  
  113.      DISCLAIMER
  114.      ==========
  115.           I have made every effort to test this code and insure that there
  116.      aren't any bugs.  However, I'm not infallible.  I'm pretty sure I've
  117.      got all the problems worked out but, as with any other software:
  118.  
  119.           THIS SOFTWARE AND MANUAL ARE DISTRIBUTED "AS IS" AND WITHOUT
  120.      WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR ANY OTHER
  121.      WARRANTIES WHETHER EXPRESSED OR IMPLIED.  BECAUSE OF THE VARIOUS
  122.      HARDWARE AND SOFTWARE ENVIRONMENTS INTO WHICH THIS PRODUCT MAY BE PUT,
  123.      NO WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE IS OFFERED.  THE USER
  124.      MUST ASSUME THE ENTIRE RISK OF USING THE SOFTWARE.  I WILL NOT BE
  125.      RESPONSIBLE FOR ANY DAMAGE OR LOSS OF TIME, DATA, HARDWARE, OR
  126.      SOFTWARE YOU INCUR THROUGH USE OF THIS PRODUCT.
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.      Copyrights
  135.      ==========
  136.          I must state now that two of the classes used by this library,
  137.      TVMPoint and TVMScrollBar, are derived directly from copyrighted
  138.      Borland code and are only a little different from the original source. 
  139.      The only changes made were to enforce usage of type long values for
  140.      the editor's expanded line range.
  141.          I make no claim of ownership or copyright to the code in those two
  142.      files (specifically TVMPOINT.CPP and TVMSBAR.CPP) and to comply with
  143.      Borland's licensing agreement *WILL NOT* distribute the source code in
  144.      those two files.  However, *I HAVE* supplied the necessary
  145.      instructions to recreate those files.  The changes involve some simple
  146.      replacements and a couple of additions and are easy to do.  To
  147.      recreate the files, you will need the source files TPOINT.CPP and
  148.      TSCRLBAR.CPP from the original Turbo Vision 1.03 or 2.0 though.  If
  149.      you do not have the source code to Turbo Vision 1.03, I have included
  150.      the necessary .OBJ files that can be used to rebuild the libraries.
  151.          All other source code associated with the package is of my own
  152.      creation and was designed and written entirely by me.  I retain all
  153.      rights to all other files.
  154.  
  155.  
  156.  
  157.      Borland C++ 3.1, Borland C++ 4.0 through 4.51, Turbo Vision 1.03,
  158.      Turbo Vision 2.0, and PowerPack for DOS are trademarks of Borland
  159.      International
  160.  
  161.  
  162.      The SemWare Editor (TSE) and QEdit are trademarks of the SemWare
  163.      Corporation
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.      Files you should receive in TVME30.ZIP
  172.      ======================================================================
  173.      HISTORY.DOC    - History of changes to the TVMEditor library and
  174.                       documentation for any last minute changes.
  175.      MANUAL.DOC     - TVMEditor class library documentation (this file)
  176.      ORDER.DOC      - Registration, technical support, and order form
  177.      KEYHELP.DOC    - Keyboard command help text used for the memo demo
  178.      TVBC4BUG.DOC   - Describes a Turbo Vision 1.03 bug that needs fixing
  179.                       to make Turbo Vision 1.03 work properly with BC++
  180.                       4.xx.
  181.  
  182.      TVMEDIT.H      - TVMEditor class library header file
  183.      TVMEDIT.???    - Library containing the editor functions:
  184.  
  185.                         TVMEDIT.BC3 - BC++ 3.1/TV 1.03
  186.                         TVMEDIT.BC4 - BC++ 4.xx/TV 1.03
  187.                         TVMEDIT.TV2 - BC++ 4.xx/TV 2.0
  188.  
  189.                         Rename one of these files to TVMEDIT.LIB before
  190.                         compiling the demo.
  191.  
  192.      LINK.H         - __link() definition header file for the demo
  193.      TVEDIT.H       - Application header file for the demo
  194.      TINTFILE.H     - TInteger and TFilename class header for the demo
  195.      TVCOLR.???     - Color definitions header file (See notes later on)
  196.      HEAPVIEW.H     - Header file for the heap viewer
  197.      TMSGVIEW.H     - Header file for the message viewer window
  198.      HEAPVIEW.CPP   - Heap viewer class for the demo
  199.      TFILENM.CPP    - Filename input line for the demo
  200.      TINTEGER.CPP   - Numeric input line for the demo
  201.      TMSGVIEW.CPP   - Message viewer window to demonstrate the cmSetLine
  202.                       command for the editor demo
  203.      MAPCOLOR.CPP   - An alternate TView::mapColor() for the TVCOLR.H stuff
  204.      BLDRSC.CPP     - Resource file builder for the demo
  205.      TVEDIT1.CPP    - Demo editor routines
  206.      TVEDIT2.CPP    - Demo editor routines
  207.      TVEDIT3.CPP    - Demo editor routines
  208.      TMACRO.CPP     - Demo editor simple event macro recorder/player
  209.      TV20DPMI.DEF   - Default module resource definition file for TV 2.0
  210.                       DPMI apps
  211.      DEMO.MAK       - Make file for the demo executables and resource file
  212.  
  213.      TVEDIT.EXE     - The demo editor application
  214.      TVEDIT.RSC     - The resource file for the demo editor
  215.      TVECLEAN.COM   - TVMEditor EMS clean-up utility
  216.  
  217.          If your copy is incomplete or out of date, you can always find a
  218.      full, up to date copy in the BCPPDOS forum on CompuServe in the Turbo
  219.      Vision library (Section 11).
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.                              Class Hierarchy Diagram
  228.                              -----------------------
  229.  
  230.          Below is a class hierarchy diagram for the new TVMEditor library
  231.      classes.  Although similar in most cases, TVMMemo is now derived from
  232.      TVMFileEditor instead of TVMEditor.  This gives it some additional
  233.      capabilities not present in the basic TVMEditor class.  Also, TVMPoint
  234.      and TVMScrollBar have been added due to the expanded line capacity of
  235.      the editors.
  236.  
  237.                               ┌─────────────┐
  238.                               │    TView    │
  239.                               └┬───┬───┬───┬┘
  240.                               /│\ /│\ /│\ /│\
  241.                                │   │   │   │
  242.          ┌─────────────────────┘   │   │   └──┐
  243.          │                 ┌───────┘   │      │
  244.    ┌─────┴─────┐    ┌──────┴───────┐   │  ┌───┴────┐  ┌─────────────┐
  245.    │ TVMEditor │    │ TVMIndicator │   │  │ TGroup │  │ TWindowInit │
  246.    └─────┬─────┘    └──────────────┘   │  └───┬────┘  └─────┬───────┘
  247.         /│\                            │     /│\           /│\
  248.          │                       ┌─────┘      │             │
  249.   ┌──────┴────────┐      ┌───────┴──────┐     └──────┬──────┘(virtual)
  250.   │ TVMFileEditor │      │ TVMScrollBar │            │
  251.   └──────┬────────┘      └──────────────┘       ┌────┴────┐
  252.         /│\                                     │ TWindow │
  253.          │                                      └────┬────┘
  254.     ┌────┴────┐                                     /│\
  255.     │ TVMMemo │                                      │
  256.     └─────────┘                              ┌───────┴───────┐
  257.                                              │ TVMEditWindow │
  258.                                              └───────────────┘
  259.  
  260.   ┌──────────┐
  261.   │ TVMPoint │
  262.   └──────────┘
  263.   ┌──────────────────┐
  264.   │ TVMFindDialogRec │
  265.   └──────────────────┘
  266.   ┌─────────────────────┐
  267.   │ TVMReplaceDialogRec │
  268.   └─────────────────────┘
  269.   ┌─────────────┐
  270.   │ TVMMemoData │
  271.   └─────────────┘
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.       **
  280.       ** ATTENTION!!  PLEASE READ THIS!
  281.       **
  282.       **     Please be aware of the fact that most of the constants and
  283.       ** definitions below duplicate the existing names found in Borland's
  284.       ** EDITORS.H file.  I did this intentionally so that the names would
  285.       ** be familiar and so that entirely new command values didn't have to
  286.       ** be created.  Many of the duplicate names have the same value
  287.       ** assigned to them as in EDITORS.H but many others don't.
  288.       **     As long as you don't define Borland's Uses_TEditor,
  289.       ** Uses_TFileEditor, Uses_TEditWindow, Uses_TMemo, Uses_TIndicator,
  290.       ** Uses_TReplaceDialogRec, or Uses_TFindDialogRec you shouldn't get
  291.       ** any compiler errors.
  292.       **     Instead, you should be using the equivalent Uses_TVMxxx
  293.       ** definitions for TVMEDIT.H because these classes are all intended
  294.       ** as a complete replacement for the Turbo Vision editor classes.
  295.       ** The two should not be mixed.  Given the advantages offered by this
  296.       ** set of classes, there should be no reason to mix them anyway.
  297.       **
  298.  
  299.                             Definitions and Constants
  300.                             -------------------------
  301.  
  302.      -----------------
  303.      TVMEDITOR_VERSION
  304.      TVMVERSION_STRING
  305.      -----------------
  306.          These define the version number for the TVMEditor classes. 
  307.      Currently, they are defined as 0x0300 and "3.00" respectively.
  308.  
  309.      ---------------------------------
  310.      const ushort kbCtrlLBrkt = 0x1A1B
  311.      ---------------------------------
  312.          This constant defines the Ctrl+[ (left bracket) key code value for
  313.      the default Find Matching command key.  There was no equivalent in
  314.      Turbo Vision's TKEYS.H file so it had to be defined here.
  315.  
  316.      -----------------
  317.      ufXXXXX constants
  318.      -----------------
  319.          These constants serve the same purpose as in the original TEditor
  320.      classes.  They indicate how much of the view should be drawn the next
  321.      time a screen update is performed (scrollbars and indicators, one or
  322.      more lines, or the entire view).
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.      -----------------
  331.      smXXXXX constants
  332.      -----------------
  333.          These constants are used internally by the editor classes to keep
  334.      track of the current block marking mode (none, block key (^Kx),
  335.      Shift+Movement keys, mouse drag, whole line mouse drag).
  336.  
  337.      -----------------
  338.      cmXXXXX constants
  339.      -----------------
  340.          These, of course, define all available commands for the editor
  341.      classes.  The constants in the range 80 to 90 (cmSave to cmReSynch)
  342.      are in Turbo Vision's reserved command range of 0-99 and can be
  343.      disabled if necessary.  Some of these already existed in the original,
  344.      but there are some new ones.  Note that some of the constants are
  345.      conditionally defined only when using Turbo Vision 1.03.  This is
  346.      because Turbo Vision 2.0 added these commands to its default set and
  347.      they no longer need to appear in TVMEDIT.H.
  348.          The constants in the range 500 and up are in Turbo Vision's
  349.      reserved command range of 256-999 and are not allowed to be disabled. 
  350.      They represent the commands for editing text and other such
  351.      operations.  A majority of the existing command names have new values
  352.      and are grouped with the new commands into two sets: Commands that are
  353.      destructive and commands that are non-destructive.  Destructive
  354.      commands are ignored when the editor is in read-only mode to prevent
  355.      alterations to the text..
  356.  
  357.      -----------------
  358.      edXXXXX constants
  359.      -----------------
  360.          These constants define the message types that can be handled by
  361.      the editorDialog() function.  The first eight message types (0-7) will
  362.      be handled by the default editorDialog() function if you decide not to
  363.      define one of your own.  Those commands are considered fatal or at
  364.      least worthy of mention to the user.  Messages numbered 8 through 22
  365.      are optional and will be ignored by the default editorDialog()
  366.      function.  Commands associated with those message types will be
  367.      unavailable to the user.
  368.          By making your own version of editorDialog() handle these events,
  369.      you can add the associated functionality to your application's editors
  370.      and memo fields.  See the documentation for the TVMEditor data member
  371.      'editorDialog' and the section on Command Operation and Implementation
  372.      for more information.
  373.  
  374.      -----------------
  375.      efXXXXX constants
  376.      -----------------
  377.          These constants define the available editor options in effect such
  378.      as Insert Mode, Auto Indent, Word Wrap, etc.  efInsertMode through
  379.      efOverWriteBlocks are local options, efExpandTabs through efUseLFOnly
  380.      are global options, and efReadOnly through efUseCSH are classed as
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.      "Other".  Local options are inherited from the defaults structure when
  389.      a new editor is created.  Global options are common to all editors. 
  390.      The options marked as "Other" are inherited like local options, but
  391.      probably should not be user-modifiable.  The intent of those options
  392.      is to set them at start up and leave them set.  The efUseCSH option
  393.      bit is the exception as it can be toggled via a broadcast command to
  394.      enable or disable color syntax highlighting (requires the derived
  395.      editor class found in CSH 1.00).
  396.           The Enter Matching and Auto EOL options are also inherited at
  397.      construction and are local to each editor.  The Search and Replace
  398.      efXXXXX constants are always considered global options.  They affect
  399.      all editors that use them.  A complete description of each option can
  400.      be found in the TVMEditor Local and Global Options section of this
  401.      manual.
  402.  
  403.      ---------------------------------
  404.      maxLineLength and maxSearchString
  405.      ---------------------------------
  406.          maxLineLength defines the maximum length of an editor line.  As in
  407.      the original, it is set to 256.  maxSearchString defines the maximum
  408.      length of a search and/or replace string.  As in the original, it is
  409.      set to 80.
  410.  
  411.      -------------------------------------------
  412.      typedef ushort (*TVMEditorDialog)(int, ...)
  413.      ushort VMdefEditorDialog(int dialog, ...)
  414.      -------------------------------------------
  415.          These define the typedef for editorDialog() functions and the
  416.      function prototype for the default editorDialog() handler.  The
  417.      default handler will display a simple error message dialog box for
  418.      errors below and including the value of the constant edGeneralMsg. 
  419.      These are considered important because they generally indicate an
  420.      error condition of some sort.  The message displayed is in the form:
  421.  
  422.                           TVMEditor Error #nn occurred
  423.  
  424.          The number displayed can be matched up to one of the edXXXXX
  425.      constants in TVMEDIT.H
  426.  
  427.      --------------------------------------------------------------------
  428.      enum SignsOfLife { slInitiate, slReporting, slHide, slShow, slDone }
  429.      --------------------------------------------------------------------
  430.           This enumerated type defines the different states that the
  431.      signsOfLife() function can be called to handle.  slInitiate is used to
  432.      intialize the signs of life event.  slReporting is called periodically
  433.      to issue the "signs of life" event.  slHide and slShow are not
  434.      implemented by the default editors but they can be used by you to hide
  435.      or show any dialog box that may be on screen.  An example of their use
  436.      may be to hide the signs dialog while you stop for user input or some
  437.      other such event and then resuming the operation that uses the signs. 
  438.      slDone is used to let the Signs of Life function know that the
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.      operation is complete and it can get rid of any dialog box or other
  447.      items it may be using.
  448.  
  449.      ---------------------------------------------------------------------
  450.      typedef void (*TVMSignsOfLife)(SignsOfLife, ushort, long, long);
  451.      void VMdefSignsOfLife(SignsOfLife, ushort, long, long);
  452.      ---------------------------------------------------------------------
  453.           These define the typedef for signsOfLife() functions and the
  454.      function prototype for the default signsOfLife() handler.  The default
  455.      handler will not do anything.  You must define your own in order for
  456.      it to do something useful.  A simple but effective Signs of Life
  457.      handler can be found in the demo program.  See the manual section on
  458.      Signs of Life for more information on this feature.
  459.  
  460.      ---------------------------
  461.      extern "C" {
  462.      char *unique_name(char *s);
  463.      }
  464.      ---------------------------
  465.           The unique_name() function was added to replace calls to the
  466.      tmpnam() standard language library function.  This was done to prevent
  467.      disk access to the default drive during construction of the virtual
  468.      memory object.  Regardless of where the file would reside, tmpnam()
  469.      always checked the default drive for existing filenames which proved
  470.      to be irritating if it was a floppy drive.  The new function will not
  471.      access any drive and is capable of generating a unique eight character
  472.      filename that won't repeat for at least 3.55 years down to the
  473.      hundredth of a second.  This is a standalone function unrelated to any
  474.      class.  It may be used to generate a unique filename for any part of
  475.      your application if so desired.  Just pass it a pointer to a buffer
  476.      that can take at least nine characters (8 for the filename and 1 for
  477.      the NULL terminator).  It will return the pointer that you pass it.
  478.  
  479.      -----------------------------
  480.      extern "C" {
  481.      void AllocateDescriptor(void)
  482.      }
  483.      -----------------------------
  484.           This function is only available when using the 32-bit protected
  485.      mode version of the library.  It will allocate a descriptor for
  486.      TVMEditor::lowMemDesc and register an exit function to deallocate it
  487.      at program end.  In 32-bit protected mode, accessing the BIOS keyboard
  488.      flags is not as simple as it is in real mode or 16-bit protected mode. 
  489.      To simplify the process, this function was added.  The TVMEditor
  490.      constructor will call this function whenever a new editor is
  491.      instantiated.  If a descriptor has not already been allocated, it does
  492.      so.  If one has been allocted, it simply returns.  See the description
  493.      of TVMEditor::lowMemDesc for more information.
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.      --------------------------
  502.      struct TVMFindDialogRec
  503.      struct TVMReplaceDialogRec
  504.      --------------------------
  505.          These two structures define the items found in the "Find" and
  506.      "Find and Replace" dialog boxes that can be used by the editorDialog()
  507.      function for the cmFind and cmReplace command events.  As a rule, you
  508.      will not use them directly.  The editor class itself will format them
  509.      with the necessary values and pass them to the editorDialog() function
  510.      for you to handle.  The demo program contains an example of this.  See
  511.      TVEDIT2.CPP.
  512.  
  513.  
  514.                       The TVMPoint and TVMScrollBar Classes
  515.                       -------------------------------------
  516.  
  517.          These two classes are identical to their normal counterparts
  518.      TPoint and TScrollBar.  The only difference is that they have been
  519.      reimplemented using type long values internally.  This was done in
  520.      order to support the expanded line range of the editor classes.  These
  521.      two classes are used when dealing with line oriented information
  522.      (vertical scrolling, line range limits, line number references,
  523.      column-row coordinates, etc).
  524.          You normally won't be using TVMPoint, but it is possible that you
  525.      might use a TVMScrollBar when adding a memo field to a dialog box.  In
  526.      such cases, you construct it just as you would the normal TScrollBar
  527.      used for horizontal scrolling.  Just pass it a TRect() defining its
  528.      boundaries.
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.                              The TVMIndicator Class
  537.                              ----------------------
  538.  
  539.   ╔══════════════════════════════════════════════════════════════════════════╗
  540.   ║ * 999999:255 │A W250 H16 T !│Ovr│CAPS│Num│ScLk│<------message area------>║
  541.   ╟──────────────────────────────────────────────────────────────────────────╢
  542.     │       │     │ │ │  │ │ │ │  │   │    │   │    └─── Message display area
  543.     │       │     │ │ │  │ │ │ │  │   │    │   └──────── Scroll Lock on
  544.     │       │     │ │ │  │ │ │ │  │   │    └──────────── Num Lock on
  545.     │       │     │ │ │  │ │ │ │  │   └───────────────── CAPS Lock on
  546.     │       │     │ │ │  │ │ │ │  └───────────────────── Overwrite/insert mode
  547.     │       │     │ │ │  │ │ │ └──────────────────────── Swap to virtual memory
  548.     │       │     │ │ │  │ │ └────────────────────────── Trailing spaces kept
  549.     │       │     │ │ │  │ └──────────────────────────── Current tab width
  550.     │       │     │ │ │  └────────────────────────────── Hard/soft tabs
  551.     │       │     │ │ └───────────────────────────────── Word wrap right margin
  552.     │       │     │ └─────────────────────────────────── Word wrap mode on
  553.     │       │     └───────────────────────────────────── Auto-indent mode on
  554.     │       └─────────────────────────────────────────── Cursor Line:Column
  555.     └─────────────────────────────────────────────────── * = Modified (0Fh),
  556.                                                          R = Read-Only,
  557.                                                          Blank = Not modified
  558.  
  559.          This indicator will be inserted on a full width line either above
  560.      or below the text editing region within the borders of a
  561.      TVMEditWindow.  It displays the various options in effect for the
  562.      associated editor.  You can also use it for TVMMemo fields.  In such
  563.      cases, you can create the bounds such that the indicator occupies a
  564.      full line as it does in a TVMEditWindow or shorten its right boundary
  565.      so that it displays only the column and row information similar to its
  566.      original TIndicator ancestor.  The demo program has examples of both.
  567.  
  568.      Indicator Flags
  569.      ---------------
  570.          If the text is read-only, the Modified indicator will be a
  571.      flashing "R".  It will flash to be more visible.  That way, the user
  572.      won't try typing or deleting text and think it has locked up when
  573.      nothing happens.  If not a read-only editor, the space will remain
  574.      blank until the text is modified.  At that time, a star will appear
  575.      (0x0F character).
  576.          Note that there is room for a type long line value.  TVMEditor and
  577.      its derived classes can handle more than 32,767 lines.  Given the type
  578.      long value, the number of lines in a file is only limited by available
  579.      virtual memory.  Columns are limited to a maximum of 255 as before.
  580.          When the Auto Indent Marker is displayed, pressing ENTER will
  581.      cause the cursor to line up under the first non-blank character of the
  582.      previous line.  When not enabled, the cursor always goes to column 1
  583.      when ENTER is pressed.
  584.          The right margin value is used for word wrapping and line
  585.      centering.  When the 'W' for Word Wrap Mode is not displayed, no word
  586.      wrapping is performed and the right margin only has an effect for the
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.      Center Lines command.  When Word Wrap is enabled, text will be word
  595.      wrapped at the specified right margin.  The right margin can be set to
  596.      any value from 20 to 250 in the demo.  Note that standard word wrap
  597.      mode is indicated by a lower case 'w'.  In this mode, full paragraph
  598.      reformatting only occurs when manually done via the Ctrl+B keypress. 
  599.      If automatic word wrapping is enabled (the efAutoWrap bit is set),
  600.      automatic word wrapping and paragraph reformatting will occur as you
  601.      type.  In this mode, inserting text or deleting characters will
  602.      reformat text from the current cursor line forward as far as is
  603.      needed.  In standard word wrap mode (efAutoWrap is not set), an
  604.      uppercase 'W' is displayed and wrapped text moves to the next line but
  605.      subsequent lines are left alone.
  606.          Hard Tab means that a physical 0x09 character is inserted into the
  607.      editor when the Tab key is hit.  These tabs will cause the display to
  608.      change if the tab width is modified after loading the file.  Soft tabs
  609.      are just an appropriate number of spaces inserted at the time the Tab
  610.      key is hit.  After the tab type indicator, the number of spaces a tab
  611.      represents is displayed.  This value can be set to any number from 2
  612.      to 16 in the demo.  When Tab or Shift+Tab is hit, the cursor will be
  613.      moved to the appropriate tab stop.  There is also a load-time option
  614.      that will convert hard tabs to spaces when the file is initially read
  615.      into the editor.
  616.          If Trailing Spaces is turned on, any trailing spaces and/or tabs
  617.      at the end of the lines will be retained.  This is the way the
  618.      original TEditor worked.  If turned off, any trailing spaces and tabs
  619.      will be stripped from the end of the line.  There are other benefits
  620.      to having this turned on or off.  See below for further information on
  621.      this feature.
  622.          The Swap Marker will appear as soon as the editor starts swapping
  623.      text to virtual memory.  When blank, it indicates that the file is
  624.      entirely within the editor's conventional memory buffer.  When the
  625.      0x12 character (looks like up and down arrowheads) is displayed, data
  626.      is being swapped to XMS.  When the 0x17 character (looks like up and
  627.      down arrowheads with an underline) is displayed, data is being swapped
  628.      to EMS.  For the protected mode libraries, the 0x17 symbol simply
  629.      means that swapping is occurring (there is no concept of EMS or XMS
  630.      memory in protected mode, it's just conventional memory).  When the
  631.      0x1D character (looks like left and right arrowheads) is displayed,
  632.      data is being swapped to EMS/XMS and disk or disk alone if EMS/XMS was
  633.      not available for use.  For the protected mode libraries, it means
  634.      that no more conventional memory could be allocated so it is using a
  635.      disk swap file.  I used this marker so that I could see where data was
  636.      going during development.
  637.          Note that it is possible for a file to use enough EMS or XMS
  638.      memory that it eventually starts swapping to disk but a newly opened
  639.      file will display the marker indicating EMS/XMS usage.  This is due to
  640.      the way that the editor class extends its memory block via a
  641.      Reallocate Pages/Block function call to the EMS/XMS handler.  The same
  642.      thing applies to the protected mode versions.
  643.          Ins/Ovr indicates the current insert state of the editor.  When
  644.      Ins is displayed, any typed text is inserted into the line at the
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.      current position.  When Ovr is displayed, typed text overwrite data at
  653.      the current cursor position.  Also, while in overwrite mode, the
  654.      Tab/Shift+Tab keys function as positional keys and simply move the
  655.      cursor forward or backward by the given tab size.  When in insert
  656.      mode, the appropriate hard or soft tab will be inserted or deleted.
  657.          When displayed, CAPS and Num indicate that the CAPS and/or NumLock
  658.      keys are toggled on.  This is displayed purely for your information
  659.      and serves no other purpose but to remind you of their current state. 
  660.      If the proper code is added to an overridden TApplication::idle()
  661.      function, these indicators can be updated immediately whenever the
  662.      CAPS or NumLock keys are pressed.  This is done with a broadcast
  663.      message event.  If the proper code is not present, these two
  664.      indicators will not get updated until something happens to cause a
  665.      redraw of the view (type text, switch windows, etc).  The demo program
  666.      has an example of an overridden TApplication::idle() function.
  667.          The ScLk (Scroll Lock) indicator is used in a similar fashion. 
  668.      For TVMFileEditor, it is purely informational.  However, for the
  669.      TVMMemo class it does have meaning.  When the ScLk indicator is
  670.      displayed (on), Tab and Shift+Tab will operate within the memo edit
  671.      window to insert or delete hard/soft tabs.  When ScLk is not displayed
  672.      (off), Tab and Shift+Tab will change the focus from one item to the
  673.      next in the dialog box as it always has.  Thus, with the TVMMemo
  674.      class, you do not have to use spacebar instead of the Tab key if you
  675.      don't want to.
  676.          The section marked <message area> currently has two possible
  677.      settings.  <TwoKey> is displayed when the first key of a two-key
  678.      sequence is pressed (i.e. ^K of the two-key command <^KB>) and
  679.      <Literal> is displayed when the Literal command key is pressed
  680.      (default: ^P).  The message disappears once the second key is pressed. 
  681.      These messages appear to alert you to the fact that another key press
  682.      is needed to complete the command just selected.  Pressing ESC while
  683.      one of these messages is displayed will effectively cancel the
  684.      command.  The exception is Literal, which inserts the next keypress
  685.      received as a literal character.  In that case, the ESC key code
  686.      character 0x1B is inserted.  This is easily erased with a press of the
  687.      Backspace key.  There are also functions available that allow you to
  688.      display your own temporary message or set a default message that is
  689.      displayed in place of the normal blank area.
  690.  
  691.                             Data and Function Members
  692.                             -------------------------
  693.  
  694.      ---------------------------------------
  695.      TVMPoint Location
  696.      Boolean  ShowReadOnly, UseMemoColor, Modified;
  697.      ushort   Opts
  698.      short    RightMargin, TabSize, Swapping
  699.      char     Message[80]
  700.      ---------------------------------------
  701.          These data members track the current values of each of the
  702.      indicator's different display fields.  ShowReadOnly and UseMemoColor
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.      relate to the extra parameters passed to the constructor.
  711.  
  712.      ----------------------
  713.      const char *DefaultMsg
  714.      ----------------------
  715.           This pointer can be used to set up a default message for display
  716.      in the message area of the indicator.  At construction, it will be set
  717.      to NULL (a blank message area).  It can be changed using the
  718.      setDefaultMessage() member function to point to a different string
  719.      that indicates something meaningful to your applications such as a
  720.      mode or state that the editor object is in for longer than a key press
  721.      or two.  An example of this might be a terminal object with a
  722.      scrollback mode.  When in scrollback mode, the default message could
  723.      be set to something like <ScrollBack> to let the user know it is
  724.      enabled.  Any temporary text stored to Message[] will be displayed
  725.      when needed, but once cleared, it returns to showing the default
  726.      message string pointed to by this data member.  When you are done with
  727.      the default message, call setDefaultMessage(NULL) to go back to a
  728.      blank message area.  An editor's indicator pointer is a protected data
  729.      member.  However, you can still set a default message via the
  730.      TVMEditor access function setDefaultMessage.  For example:
  731.  
  732.                     anEditor->setDefaultMessage("A message")
  733.  
  734.      --------------------------------------------------------
  735.      TVMIndicator(const TRect &bounds, Boolean ShowRO = True,
  736.          Boolean IsForMemo = True);
  737.      --------------------------------------------------------
  738.          The constructor is like the old TIndicator with the exception of
  739.      the extra parameters ShowRO, and IsForMemo.  The ShowRO parameter is
  740.      used to determine whether or not the "R" is displayed when the
  741.      associated editor's text is read-only.  In situation where it can be
  742.      assumed that the text is read-only (in an informational dialog for
  743.      example), you can pass this parameter as False so that the flashing
  744.      "R" does not appear.  By default, it will be True so that if the text
  745.      is read-only, the user will be notified by the indicator.  The
  746.      IsForMemo parameter determines what color from the indicator's palette
  747.      will be used to draw the view.  There are two separate colors for the
  748.      indicator.  One is for edit windows and the other is for memo fields
  749.      in a dialog box.  This was done because I found that the color used
  750.      for edit windows didn't always look good in a dialog box.  By default
  751.      it is True so that the parameter doesn't have to be specified when you
  752.      create a TVMMemo's indicator for a dialog box.  Since TVMEditWindow
  753.      creates the editor's indicator automatically, you probably won't have
  754.      to alter or specify this parameter at any time.
  755.  
  756.      ---------------------------------------
  757.      void setDefaultMessage(const char *msg)
  758.      ---------------------------------------
  759.           As noted above, this function can be used to establish a default
  760.      message that is displayed in the message area.  Such messages will not
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.      be cleared until you call setDefaultMessage() again with a new message
  769.      or NULL to clear it.  Note that temporary messages displayed with the
  770.      setMessage() command take precedence and will be displayed instead. 
  771.      As soon as the temporary message is cleared, the default message is
  772.      shown again.
  773.  
  774.      ---------------------------------------------------------------
  775.      void setValue(const TVMPoint &aLocation, Boolean aModified,
  776.          ushort aOpts, short RMargin, short TabSz, short SwapStatus)
  777.      ---------------------------------------------------------------
  778.          This function is called internally by the owning editor to update
  779.      the indicator with its current settings.
  780.  
  781.      --------------------------------
  782.      void setMessage(const char *msg)
  783.      --------------------------------
  784.          This function is called internally by the owning editor to update
  785.      the indicator with a flag message such as <TwoKey> or <Literal>.
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.                              The TVMEditWindow Class
  794.                              -----------------------
  795.  
  796.   ╔═[ ]═════════════════════ FILENAME                ═════════════════════[ ]═╗
  797.   ║ * 999999:255 │A W250 H16 T !│Ovr│CAPS│Num│ScLk│<indicator at top ...>     ^
  798.   ║ Text editing region below the indicator.                                  ░
  799.   ║                                                                           ░
  800.   ║                                                                           ░
  801.   ║                                                                           V
  802.   ╚═<░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░>──┘
  803.  
  804.   ╔═[ ]═════════════════════ FILENAME                ═════════════════════[ ]═╗
  805.   ║ Indicator below the text editing region.                                  ^
  806.   ║                                                                           ░
  807.   ║                                                                           ░
  808.   ║                                                                           ░
  809.   ║ * 999999:255 │A W250 H16 T !│Ovr│CAPS│Num│ScLk│<... or at the bottom >    V
  810.   ╚═<░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░>──┘
  811.  
  812.          This is simply a window that contains a TVMFileEditor object and
  813.      its associated indicator and scrollbars.  It differs from the standard
  814.      Turbo Vision TEditWindow in that you can pass it a Boolean specifying
  815.      the indicator position, a buffer size (in KILOBYTES not just bytes),
  816.      and a flag to optionally suppress the loading of the file text until a
  817.      later time.  A suppressed load is useful in situations where you need
  818.      to do something special (change the swap file location or name, etc)
  819.      prior to the text being loaded.  The window's handleEvent() will also
  820.      respond to a cmEditorPresent broadcast event by returning its 'this'
  821.      pointer in the TEvent event.message.infoPtr member.  This is useful
  822.      for detecting the presence of an editor for other application
  823.      operations.
  824.          As in the original, the window constructor creates the indicator,
  825.      scrollbars, and editor.  However, due to the fact that the editor can
  826.      handle over 32,767 lines, a specially created scrollbar (TVMScrollBar)
  827.      is inserted for the vertical scrollbar.  It is identical to a normal
  828.      scrollbar, but can handle type long values.
  829.          Another minor difference between my edit window and the original
  830.      is that I turn on the ofTileable option bit and turn off the
  831.      ofBuffered option bit during construction.  Disabling buffering of the
  832.      view saves quite a bit of memory when there are multiple editor
  833.      windows open. If screen flicker is a problem, you can always add the
  834.      line:
  835.  
  836.                          EditWin->options |= ofBuffered;
  837.  
  838.      before inserting the edit window into the desktop.  For the systems
  839.      that I have worked with (386's and up), this hasn't been a problem.
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.                             Data and Function Members
  848.                             -------------------------
  849.  
  850.      ---------------------
  851.      TVMFileEditor *editor
  852.      ---------------------
  853.          This is a pointer to the file editor object that is contained
  854.      within the edit window.
  855.  
  856.      --------------------------------------------------------------------
  857.      TVMEditWindow(const TRect &bounds, const char *aFileName, 
  858.          int aNumber = 0, Boolean IndAtTop = True, short bufSizeInK = 20,
  859.          Boolean SuppressLoad = False)
  860.      --------------------------------------------------------------------
  861.          This is the constructor for the TVMEditWindow class.  As you can
  862.      see, the first three parameters match up to the original TEditWindow
  863.      class.  Following those are three additional parameters that you may
  864.      or may not want to specify.  Each has a default value, so it isn't
  865.      necessary to specify them unless you want to alter the default
  866.      behaviour.
  867.  
  868.      IndAtTop      If passed to the constructor as True (the default),
  869.                    the edit window will insert the indicator line just
  870.                    below the top window border. If passed as False, it
  871.                    will insert the indicator just above the bottom
  872.                    window border.
  873.  
  874.      bufSizeInK    This parameter specifies (in Kilobytes) how large
  875.                    the conventional memory buffer will be for the
  876.                    editor object.  This buffer is used to hold the
  877.                    recently used text and internal information
  878.                    necessary for editing the file.  By default, it is
  879.                    20K.  This provides enough of a buffer for editing
  880.                    large files with reasonable speed and swap
  881.                    efficiency.  If you will be editing smaller files or
  882.                    have ample virtual memory in the form of EMS or XMS
  883.                    memory, then you can drop this amount down to
  884.                    further reduce the amount of conventional memory
  885.                    used by each editor instance.
  886.  
  887.      SuppressLoad  If passed in as False, the specified file will be
  888.                    loaded immediately into the editor.  If passed in as
  889.                    True, the load operation will be suppressed until a
  890.                    later time.  This is useful for situations where you
  891.                    might want to perform some special operation such as
  892.                    altering the default swap file name, etc before
  893.                    allowing the editor to load the text.  In such cases,
  894.                    a call to the EditWindow->editor->loadFileNow()
  895.                    function will be required to make the editor load
  896.                    the text.
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.      -------------------------------------------
  905.      virtual const char *getTitle(short maxSize)
  906.      -------------------------------------------
  907.          This function returns the title of the window and, in effect, the
  908.      filename that the window's editor contains.  If the window is for the
  909.      clipboard, it will return the title pointed to by the 'clipboardTitle'
  910.      data member.  If the window contains an unnamed file, it will return
  911.      the title pointed to by the 'untitled' data member.
  912.  
  913.      ------------------------
  914.      virtual void close(void)
  915.      ------------------------
  916.          Under normal circumstances, close() will simply call
  917.      TWindow::close() to shut down the window.  However, if the window is
  918.      the clipboard, it simply hides itself.
  919.  
  920.      ---------------------------------------
  921.      virtual void handleEvent(TEvent &event)
  922.      ---------------------------------------
  923.          This overridden handleEvent() function will recognize and act upon
  924.      the cmEditorPresent event to signal that there is an active editor on
  925.      the desktop.  The window will only respond to the cmEditorPresent
  926.      event if it is not the issuer of the command and is not the clipboard.
  927.          The handleEvent() function will also issue a cmReformatAll event
  928.      to its editor when the cmZoom command is seen.  That way, if the
  929.      window's editor has the efWrapOnResize option bit set, it will
  930.      reformat the text that it contains.  Editors that have that option bit
  931.      disabled will ignore the event.
  932.  
  933.      -------------------------------------------------
  934.      virtual void sizeLimits(TPoint &min, TPoint &max)
  935.      -------------------------------------------------
  936.          This function will limit the minimum size of any edit window to
  937.      six rows and twenty-five columns.  This is done to prevent the window
  938.      from getting too small and obliterating its scrollbars.
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.                                    The Editors
  947.                                    -----------
  948.  
  949.      ===========================================================
  950.      TVMEditor(const TRect &bounds, TScrollBar *aHScrollBar,
  951.          TVMScrollbar *aVScrollBar, TVMIndicator *aIndicator,
  952.          short bufSizeInK = 8)
  953.  
  954.      TVMFileEditor(const TRect &bounds, TScrollBar *aHScrollBar,
  955.          TVMScrollbar *aVScrollBar, TVMIndicator *aIndicator,
  956.          const char *aFileName, short bufSizeInK = 20,
  957.          Boolean SuppressLoad = False)
  958.  
  959.      TVMMemo(const TRect &bounds, TScrollBar *aHScrollBar,
  960.          TVMScrollbar *aVScrollBar, TVMIndicator *aIndicator,
  961.          short bufSizeInK = 1, const char *aFileName = NULL)
  962.      ===========================================================
  963.          These are similar in nature to their standard Turbo Vision
  964.      counterparts.  However, they are passed the size of the buffer
  965.      expressed in KILOBYTES (not just bytes).  They are also passed a
  966.      TVMScrollBar to handle the added ability to have more than 32,767
  967.      lines in an editor.  TVMFileEditor also has the option to suppress
  968.      loading of the text until a later time.  You may also have noticed
  969.      that TVMMemo can be passed a filename.  This will be discussed later
  970.      on.  The following sections will describe each of the editor classes
  971.      in turn.
  972.  
  973.  
  974.                                The TVMEditor Class
  975.                                -------------------
  976.  
  977.          TVMEditor is the root base class for TVMFileEditor and TVMMemo.  A
  978.      full description of the available features is given below.  All
  979.      features described for TVMEditor apply to TVMFileEditor and TVMMemo as
  980.      well.
  981.  
  982.      Design and Implementation Notes
  983.      ===============================
  984.          The new ideas and features found in the TVMEditor classes where
  985.      all taken from various sources (mainly QEdit and TSE (my two favorite
  986.      editors, both by SemWare) and the Borland C++ 3.1 IDE).  I also saw a
  987.      number of messages in the BCPPDOS forum on CompuServe pertaining to
  988.      requested TEditor features.  A majority, if not all, of the requested
  989.      features are now in there along with several excellent suggestions
  990.      from current users of the TVMEditor library.
  991.          For a number of the added features, I based the operating
  992.      characteristics on the above mentioned editors and my own personal
  993.      preferences.  They should operate in a fairly similar manner to other
  994.      editors, but there may be slight deviations here and there.  Word
  995.      wrapping and paragraph reformatting are two areas in which this is
  996.      particularly relevant.  I've used editors that implement these in a
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.      couple of different ways and I chose the methods I preferred.
  1005.  
  1006.      Virtual Memory Support
  1007.      ======================
  1008.          The editor was originally intended to only handle files in the
  1009.      100K to 200K size range.  As I designed and implemented the virtual
  1010.      memory system that handles the text retrieval and storage, it evolved
  1011.      from something that would handle those sizes into its current
  1012.      incarnation that adapts to handle multi-megabyte files.  I have tried
  1013.      to make it as efficient as possible while still keeping its
  1014.      conventional memory requirements to a reasonable minimum.  As it
  1015.      stands, you have the flexibility to specify how large or small the
  1016.      conventional memory buffer is for each editor instance (as little as
  1017.      1K or as large as 60K).  Also, editors viewing the same file can share
  1018.      a buffer reducing the amount of conventional memory required for each
  1019.      editor after the first one by quite a bit.  Virtual memory savings in
  1020.      such a situation can also be quite substantial.
  1021.          The virtual memory manager is in a class totally separate from the
  1022.      editor classes.  This allows the underlying manager to be written for
  1023.      use with whatever type of memory it wants for storage (EMS, XMS, disk,
  1024.      or a combination thereof) without having to alter the actual editor
  1025.      class code or applications that use them.  Changing virtual memory
  1026.      managers for the end user is as simple as relinking with the
  1027.      appropriate library or altering the preference option in the class
  1028.      itself.  You won't need a license to any third-party EMS/XMS
  1029.      libraries.  I built the necessary supporting code into the affected
  1030.      functions with inline assembler.
  1031.          A LIM 4.0 compliant memory manager such as 386MAX, QEMM,
  1032.      EMM386.SYS, etc is required to use expanded memory for swapping.  If
  1033.      no such manager is present or it only supports a version less than LIM
  1034.      4.0, the editor will start using XMS (if available) or disk space for
  1035.      virtual memory when required.
  1036.          An XMS 3.0 compliant memory manager such as 386MAX, QEMM,
  1037.      HIMEM.SYS, etc is required to use extended memory for swapping.  If no
  1038.      such manager is present or it only supports a version less than XMS
  1039.      3.0, the editor will start using EMS (if available) or disk space for
  1040.      virtual memory when required.  The XMS 3.0 Specification warns that at
  1041.      least 256 bytes of stack space must be available for calls to the XMS
  1042.      API functions.  If problems are encountered, try increasing the value
  1043.      of _stklen to provide a larger program stack.
  1044.          For the 16-bit and 32-bit protected mode versions of the library,
  1045.      memory is consumed until a user-definable limit is reached or until
  1046.      the memory block cannot be reallocated to a larger size.  At that
  1047.      time, disk space will be used for additional memory as required.
  1048.          The editors will not initiate virtual memory usage until the
  1049.      contents overflows the conventional memory buffer.  The contents of
  1050.      the editor includes the actual text being edited, internal tracking
  1051.      information, and undo/redo information.  As stated, if there is no
  1052.      available EMS or XMS memory, disk space is automatically used.  If EMS
  1053.      or XMS memory is available, the first type found is consumed as needed
  1054.      until there is no more available (a reallocation attempt fails).  At
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.      that point, the editors will resort to using disk space to contain any
  1063.      additional information.  Note that each open editor will use one EMS
  1064.      or XMS handle in the real mode versions.  By altering the value of a
  1065.      static data member of the virtual memory class used by the editors,
  1066.      you can control what type of memory is used or given preference
  1067.      (available from the registered version only).
  1068.          In the protected mode versions of the library, EMS and XMS memory
  1069.      are managed by the DPMI server as conventional memory.  When compiled
  1070.      for either 16-bit or 32-bit protected mode, the library will use a
  1071.      different method of memory allocation.  Virtual memory is allocated
  1072.      via calls to GlobalAlloc().  Each editor will use one HGLOBAL type
  1073.      handle.  If conventional memory does run out, the editors will start
  1074.      swapping to disk.
  1075.          I obtained all of my information for EMS memory access from the
  1076.      LIM 4.0 Specification document dated October, 1987 and, for XMS memory
  1077.      access, from the XMS 3.0 Specification document dated January, 1991. 
  1078.      If you are interested, you can download the LIM 4.0 Specification
  1079.      document from the LOTUSA forum (library 2, LIM40.ZIP) and the XMS 3.0
  1080.      Specification document from the MSDOS forum (library 10, XMS30.TXT) on
  1081.      CompuServe.  They cover all the necessary details and available
  1082.      function calls associated with each type of memory access.
  1083.  
  1084.      A Note To The Impatient <g>
  1085.      ===========================
  1086.          When working with a large file and you perform an operation such
  1087.      as file insertion, large block edit operations such as delete,
  1088.      reformat, case toggling, etc, or a large block undo/redo, it is
  1089.      possible that the editor will appear to be doing nothing for an
  1090.      extended period of time.  This is especially true when EMS or XMS
  1091.      memory is being used (or simply conventional memory in protected mode)
  1092.      and when a disk cache is in use and the hard drive light isn't doing
  1093.      anything.  Such operations can take a minute or two to finish, so
  1094.      don't think it's locked up when this happens.  Give it a little time
  1095.      to finish what it's doing.  Also see the section on Signs of Life.  It
  1096.      was for this reason that I added this feature.
  1097.  
  1098.      NOTE FOR DEBUGGING WITH EDITOR OBJECTS USING EMS
  1099.      ------------------------------------------------
  1100.          Both the BC++ 3.1 IDE and Turbo Debugger (TD286.EXE in BC++ 3.1
  1101.      and TD.EXE in BC++ 4.xx) may steal all available EMS memory at
  1102.      start-up.  Therefore, if you debug any application with the preference
  1103.      set to use EMS memory, the editors will more than likely start
  1104.      swapping to disk immediately or to XMS if any is still available. 
  1105.      During development, I used XMS memory or the protected mode libraries
  1106.      most of the time.  As a rule, there is usually some XMS memory
  1107.      available so the editors can make use of that until it runs out.  In
  1108.      16-bit and 32-bit protected mode, there is also plenty of memory
  1109.      available.
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.          You can increase the amount of memory available to the real mode
  1118.      editors though.  Set the environment variable DPMIMEM to limit the
  1119.      amount of EMS/XMS memory that TD uses:
  1120.  
  1121.                              SET DPMIMEM=MAXMEM xxxx
  1122.  
  1123.      where 'xxxx' is the amount of memory in kilobytes.
  1124.  
  1125.  
  1126.      Features List
  1127.      =============
  1128.          The basic TVMEditor and derived classes support the following
  1129.      features:
  1130.  
  1131.        * First and foremost, they support virtual memory and can therefore
  1132.          load extremely large files.  The theoretical limit is between 32
  1133.          and 128 Meg (but don't hold me to it <g>).  The maximum editable
  1134.          size is determined by the conventional memory buffer size you
  1135.          specify for the editor in the constructor.  The virtual memory
  1136.          manager will optimize its page size for that buffer.  The page
  1137.          size (1024, 2048, or 4096 bytes) multiplied by 32,767 yields
  1138.          the maximum editable size.
  1139.  
  1140.        * Because they can load large files, they also supports more than
  1141.          32,767 lines in a file. The total number of lines is now limited
  1142.          only by the amount of free virtual memory.
  1143.  
  1144.        * They have all the basic editing features found in the original and
  1145.          numerous extensions have been made to the basic movement and
  1146.          editing keys.  See below for a full list.  Most key sequences are
  1147.          the same but some are different.  Most have been standardized
  1148.          and/or grouped based on what I have seen other editors use.
  1149.  
  1150.        * There is an added capability to alter or extend the keyboard
  1151.          command sets without overriding convertEvent().  The arrays used
  1152.          to hold the key sequences and their associated commands can be
  1153.          swapped with a simple function call.  By default, there is the
  1154.          normal single key command set and four two-key command sets with
  1155.          room to add up to four additional two-key command sets.  If you
  1156.          don't like the default command key mappings, you can change them
  1157.          to suit your preferences.
  1158.  
  1159.        * Additional editor option settings have been added and they have
  1160.          been grouped into a global scope for use by all editors and a
  1161.          local scope for use by each editor instance.  Global options
  1162.          affect all editors and local options affect only the editor they
  1163.          belong to.  Each new editor will inherit the currently defined
  1164.          global options upon being opened.
  1165.  
  1166.        * Line jump: Go to a specific line, +/- a number of lines, previous
  1167.          line, last edited line, and 3 user-definable bookmarks.
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.        * Hard and soft tabs with variable tab size.  Also has the option to
  1176.          convert hard tabs to soft tabs (spaces) at load time.
  1177.  
  1178.        * Support for Enter Matching on (, [, {, ', ", and <.  It can be
  1179.          enabled or disabled for any or all of them through local option
  1180.          settings.
  1181.  
  1182.        * There is also support for Find Matching on (), [], {}, and <>
  1183.          pairs starting on either character in the pair going in either
  1184.          direction across multiple lines.  Find Matching can also be done
  1185.          for " and ' but the matching search will go in the forward
  1186.          direction only and will be limited to the same line.
  1187.  
  1188.        * The selected block of text can be persistent or non-persistent in
  1189.          nature.  A persistent block allows you to mark text and move away
  1190.          from it without losing it.  Either block type can be marked via
  1191.          several different key sequences or the mouse.  A marked block can
  1192.          start and end at any point within a line and may also start and
  1193.          end on the same line so as to mark only a few characters or words.
  1194.          Block extension is also supported via Shift+Clicking the mouse.
  1195.  
  1196.        * Improved search and replace options:  Forward or backward within
  1197.          selected text or the whole file, search from cursor or entire
  1198.          scope (from one end of the file or selected text to the other).
  1199.          Search rates range from less than 150K to more than 650K per
  1200.          second depending upon the PC in use and the location of the
  1201.          virtual memory (EMS/XMS or disk).
  1202.  
  1203.        * Supports word wrapping, paragraph reformatting, character case
  1204.          switching, line centering, and text alignment as needed.  If no
  1205.          block  is selected, the current line is used as the block for
  1206.          certain commands.  This is useful when you only want to operate on
  1207.          one or two lines.
  1208.  
  1209.        * Additional Move Block and Copy Block functions were added that do
  1210.          not require the clipboard.  These are useful in situations where a
  1211.          clipboard may not be available (i.e. a TVMMemo).  Also, secondary
  1212.          keypresses were defined so that the clipboard commands could be
  1213.          used while debugging an application in the DOS IDE which tends to
  1214.          trap the Ctrl/Shift+Ins/Del keypresses.
  1215.  
  1216.        * Supports unlimited Undo/Redo.
  1217.  
  1218.        * Supports color syntax highlighting when used in conjunction with
  1219.          the derived editor class found in the Color Syntax Highlighter
  1220.          add-on (currently CSH 1.00).
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.      Default Editor Command Key Mappings
  1229.      ===================================
  1230.          Below are the default command key mappings.  For a lot of the
  1231.      commands, there is a primary and secondary key sequence defined.  The
  1232.      editor gives no preference to either, and does not care which one you
  1233.      use.  The secondary key sequences generally represent a different
  1234.      approach to getting around in the editor.  The primary key sequences
  1235.      are, in most cases, the most common method of issuing movement and
  1236.      text editing commands.
  1237.          The default key sequences associated with the commands, even if
  1238.      they aren't the most likeable, should be familiar enough that most
  1239.      people who have used an editor before can use this one.  The command
  1240.      key sets can be replaced to suit your personal preferences if so
  1241.      desired.  It's easy to do and doesn't require deriving a new editor
  1242.      class.  You define an array of command keys and command values and
  1243.      call a function to replace a specific key map (more on that later).
  1244.  
  1245.      Function                   Primary              Secondary
  1246.      ---------------------------------------------------------------------
  1247.      Movement:
  1248.        Cursor Left              <LtArrow>            <^S>
  1249.        Cursor Right             <RtArrow>            <^D>
  1250.        Word Left                <^LtArrow>           <^A>
  1251.        Word Right               <^RtArrow>           <^F>
  1252.        Start of Line            <Home>               <^QS>
  1253.        End of Line              <End>                <^QD>
  1254.        Up Line                  <UpArrow>            <^E>
  1255.        Down Line                <DnArrow>            <^X>
  1256.        Top of Window            <^Home>              <^QE>
  1257.        Bottom of Window         <^End>               <^QX>
  1258.        Roll Window Up           <^W>
  1259.        Roll Window Down         <^Z>
  1260.        Page Up                  <PgUp>               <^R>
  1261.        Page Down                <PgDn>               <^C>
  1262.        Top of Text              <^PgUp>              <^QR>
  1263.        Bottom of Text           <^PgDn>              <^QC>
  1264.  
  1265.      Text Insertion/Deletion:
  1266.        Delete Char at Cursor    <Del>                <^G>
  1267.        Delete Char Left (Bkspc) <Backspace>          <^H>
  1268.        Delete Current Line      <^Y>
  1269.        Delete to Start of Line  <^QH>
  1270.        Delete to End of Line    <^QY>
  1271.        Delete Word Right        <^T>
  1272.        Delete Word Left         <^Backspace>
  1273.        Start a New Line         <Enter>              <^M>
  1274.        Insert New Line          <^N>
  1275.        Tab Right (Hard/Soft)    <Tab>                <^I>
  1276.        Tab Left (Delete Tab)    <Shift+Tab>
  1277.        Insert Literal Char      <^P>
  1278.        Restore Contents of Line <^QL>
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285.  
  1286.      Function                   Primary              Secondary
  1287.      ---------------------------------------------------------------------
  1288.       !Undo                     <Alt ->
  1289.       !Redo                     <Alt =>
  1290.  
  1291.      Block Commands:
  1292.       @Mark Block Beginning     <Shift+Movement Keys, Drag Mouse>    <^KB>
  1293.       @Mark Block End           <Release Shift Key/Mouse Button>     <^KK>
  1294.        Hide Block               <^KH>
  1295.       *Copy Block to Cursor     <^KC>
  1296.       *Move Block to Cursor     <^KV>
  1297.        Delete Block             <Ctrl-Delete>        <^KY>
  1298.       -Indent Block             <^KI>
  1299.       -Unindent Block           <^KU>
  1300.        Read Block from File     <^KR>
  1301.        Write Block to File      <^KW>
  1302.       ~Print Block              <^KP>
  1303.       -Toggle Case in Block     <^OO>
  1304.       -Force Uppercase in Block <^OU>
  1305.       -Force Lowercase in Block <^OL>
  1306.      -+Center Lines in Block    <^OC>
  1307.       -Align Text in Block      <^OA>
  1308.       -Reformat Paragraph       <^B>
  1309.  
  1310.      Clipboard Commands:
  1311.        Copy Block to Clipboard  <Ctrl-Insert>        <^JC>
  1312.        Cut Block to Clipboard   <Shift-Delete>       <^JK>
  1313.        Paste from Clipboard     <Shift-Insert>       <^JP>
  1314.  
  1315.        The secondary clipboard key sequences were added for situations
  1316.      where the primary key sequences can't be used (i.e. debugging in the
  1317.      DOS IDE)
  1318.  
  1319.      @ = With a block marked, Shift+Click and drag the mouse or use ^KB/^KK
  1320.          to move the starting or ending position.
  1321.      * = Non-clipboard move and copy.
  1322.      + = Lines are centered based on right margin value
  1323.      - = Command works with current line only if no block is defined.
  1324.          (Reformat Paragraph has special rules.)
  1325.      ~ = To print the entire file issue the command cmPrintFile (See demo
  1326.          menu File | Print construction in BLDRSC.CPP)
  1327.      ! = Note to Super PCKwik users:
  1328.            If you are using the keyboard accelerator, the default hot keys
  1329.            for Repeat Rate Slower and Faster are <Alt -> and <Alt =>.
  1330.            Either change them or hold down the Shift key while pressing
  1331.            them to access Undo or Redo.
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  1338.  
  1339.      Function                   Primary              Secondary
  1340.      ---------------------------------------------------------------------
  1341.      Text Search/Replace:
  1342.        Find Matching            <^[> (Ctrl+Left Bracket)
  1343.        Search for Text          <^QF>
  1344.        Search and Replace Text  <^QA>
  1345.        Repeat Last Srch/Replace <^L>
  1346.           Search/Replace Options:
  1347.              Case Sensitive      Forward     Global          From Cursor
  1348.              Whole Words Only    Backward    Selected Text   Entire Scope
  1349.              Prompt On Replace
  1350.  
  1351.      Positional/BookMark
  1352.        Set Bookmark 1-3         <^K><1-3>
  1353.        Jump to line or +/- cnt  <^JG>
  1354.        Jump to Start of Block   <^JB>
  1355.        Jump to End of Block     <^JE>
  1356.        Jump to Bookmark 1-3     <^J><1-3>
  1357.        Jump to Prev Position    <^JV>
  1358.        Jump to Last Change Line <^JL>
  1359.  
  1360.      Mode Toggles & Other Options:
  1361.        Insert/Overwrite Mode    <Ins>                <^OV>
  1362.        Auto-Indent Mode         <^OI>
  1363.        Word Wrap                <^OW>
  1364.        Automatic Word Wrapping  <^OM>
  1365.        Word Wrap on Win. Resize <^OR>
  1366.        Tab Style (Hard/Soft)    <^OT>
  1367.        Trailing Spaces          <^OS>
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.        Two-Key Commands By First Key
  1376.        -----------------------------
  1377.  
  1378.         ^K - Block Mode Commands              ^Q - Quick Keys
  1379.        ------------------------------        ------------------------------
  1380.        Mark Block Beginning     <^KB>        Start of Line            <^QS>
  1381.        Mark Block End           <^KK>        End of Line              <^QD>
  1382.        Hide Block               <^KH>        Top of Window            <^QE>
  1383.        Copy Block to Cursor     <^KC>        Bottom of Window         <^QX>
  1384.        Move Block to Cursor     <^KV>        Top of Text              <^QR>
  1385.        Delete Block             <^KY>        Bottom of Text           <^QC>
  1386.        Indent Block             <^KI>        Delete to Start of Line  <^QH>
  1387.        Unindent Block           <^KU>        Delete to End of Line    <^QY>
  1388.        Read Block from File     <^KR>        Restore Contents of Line <^QL>
  1389.        Write Block to File      <^KW>        Search for Text          <^QF>
  1390.        Print Block              <^KP>        Search/Replace Text      <^QA>
  1391.        Set Bookmark 1-3         <^K><1-3>
  1392.  
  1393.         ^J - Jump/Secondary Clipboard         ^O - Options/Other
  1394.        ------------------------------        ------------------------------
  1395.        Jump to Line or +/- cnt  <^JG>        Toggle Case in Block     <^OO>
  1396.        Jump to Start of Block   <^JB>        Force Uppercase in Block <^OU>
  1397.        Jump to End of Block     <^JE>        Force Lowercase in Block <^OL>
  1398.        Jump to Bookmark 1-3     <^J><1-3>    Center Lines in Block    <^OC>
  1399.        Jump to Prev Position    <^JV>        Align Text in Block      <^OA>
  1400.        Jump to Last Change Line <^JL>        Insert Mode              <^OV>
  1401.        Copy Block to Clipboard  <^JC>        Auto-Indent Mode         <^OI>
  1402.        Cut Block to Clipboard   <^JK>        Word Wrap                <^OW>
  1403.        Paste from Clipboard     <^JP>        Automatic Word Wrapping  <^OM>
  1404.                                              Word Wrap on Win. Resize <^OR>
  1405.                                              Tab Style (Hard/Soft)    <^OT>
  1406.                                              Trailing Spaces          <^OS>
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.      Local Editor Options
  1415.      ====================
  1416.          This section describes the various local options available to the
  1417.      editor classes.  Some of these have a representation on the indicator
  1418.      line if one is present.  All of these modes are local to each editor. 
  1419.      For example, in one editor view you may have a document file loaded
  1420.      with word wrapping and insert mode enabled, but in another editor
  1421.      view, you may have a source code file loaded with word wrapping and
  1422.      insert mode turned off.  As you switch between editors, these modes
  1423.      come into effect for that view only and won't alter any mode for other
  1424.      editing views that may be loaded.
  1425.  
  1426.      Insert Mode (efInsertMode)
  1427.      --------------------------
  1428.          As always, when insert mode is on, any typed text will be inserted
  1429.      into the current line.  When insert mode is off, typed text overwrite
  1430.      anything currently under the cursor.  The current mode is displayed as
  1431.      "Ins" or "Ovr" on the indicator line.
  1432.  
  1433.      Auto Indent Mode (efAutoIndent)
  1434.      -------------------------------
  1435.          When auto indent mode is on, the cursor will line up under the
  1436.      first non-blank character of the preceding line whenever the ENTER key
  1437.      is pressed.  When off, the cursor will always return to column 1 when
  1438.      the ENTER key is pressed.  Auto indent is useful for aligning blocks
  1439.      of text.  An "A" appears on the indicator line when it is on.
  1440.  
  1441.      Word Wrap Mode - Enabled/Standard (efWordWrap)
  1442.      Automatic Word Wrap (efAutoWrap)
  1443.      ----------------------------------------------
  1444.          When entering text, it is nice to have the cursor automatically
  1445.      advance to the next line when it passes the right margin.  All of the
  1446.      TVMEditor classes support word wrapping.  A word wrap will occur only
  1447.      when the cursor passes the right margin and a non-white space
  1448.      character is typed.  There must also be at least one full word
  1449.      followed by a space prior to the right margin for word wrapping to
  1450.      occur.  When text is word wrapped, the cursor, the word being typed,
  1451.      and any text following the cursor will be moved onto a new line.  If
  1452.      Auto Indent is on, the wrapped portion will also be indented by the
  1453.      appropriate amount to align it with the line above.
  1454.          Note that when automatic wrapping (efAutoWrap) is disabled, a
  1455.      character other than a space or tab must be typed while the cursor is
  1456.      past the right margin for the word wrap to occur.  If you type in a
  1457.      line and then go back to some point prior to the end of the line and
  1458.      start typing again, the end of the line may be pushed out past the
  1459.      right margin.  That part won't get moved to a new line until you type
  1460.      in some text that exceeds the right margin to cause a word wrap, press
  1461.      ENTER, or issue the paragraph reformat command.  Likewise, when you
  1462.      delete text, line shorter than the right margin will not be joined
  1463.      with text from subsequent lines.
  1464.          When efAutoWrap is enabled, automatic word wrapping and paragraph
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.      reformatting will occur as you insert or delete text.  This option bit
  1473.      makes the editor function more like a word processor.  Inserting text
  1474.      at any point in a line causes text past the right margin to word wrap. 
  1475.      Deleting text causes words from subsequent lines to be appended to the
  1476.      shorter lines as required to bring them as close to the right margin
  1477.      as possible.  It's best to play around with these two options to see
  1478.      which you prefer best.
  1479.          When standard word wrapping is on (efWordWrap only), a lowercase
  1480.      "w" will appear on the indicator line.  When automatic wrapping is
  1481.      enabled (efWordWrap | efAutoWrap), an uppercase 'W' appears on the
  1482.      indicator line.  In either case, the letter is followed by the
  1483.      editor's current right margin setting.  The right margin value is
  1484.      controlled separately using another option setting.  If both option
  1485.      bits are turned off, no letter is displayed and no wrapping will
  1486.      occur.
  1487.  
  1488.      Wrap (Reformat) On Window Resize (efWrapOnResize)
  1489.      -------------------------------------------------
  1490.          The editor also supports complete text reformatting when the view
  1491.      changes size.  This is useful for file viewers which need to wrap the
  1492.      text they contain to fit within the window if the user resizes it. 
  1493.      Note that this option is best used in conjuntion with the EOLMarker
  1494.      data member to prevent text from being reformatted incorrectly (i.e.
  1495.      title lines).
  1496.  
  1497.      Trailing Space Retention (efTrailingSpaces)
  1498.      -------------------------------------------
  1499.          Trailing space is defined as any number of spaces or tabs that are
  1500.      after the last non-blank character of a line.  When trailing space
  1501.      retention is disabled, the editor will effectively give you a free
  1502.      roaming cursor.  For example, if you use a movement key to go past the
  1503.      end of the line, it will pad the line with spaces.  Likewise, if you
  1504.      move from a long line up or down onto a shorter one, the short line
  1505.      will be padded with spaces up to the cursor so as to maintain its
  1506.      current horizontal position.  These trailing spaces will be stripped
  1507.      from the line as the cursor moves off of it as will any trailing
  1508.      spaces added by the space bar and/or tab key.
  1509.          With trailing space retention enabled, you no longer have a free
  1510.      roaming cursor.  Horizontal cursor movement will be limited to the
  1511.      extent of the text that is currently in the line.  To add spaces to
  1512.      the end of a line, you must press the space bar or tab key.  If you
  1513.      try to use the right arrow key to move past the end of the line, the
  1514.      cursor will automatically advance to the first column of the next
  1515.      line.  Likewise, if you move from a long line up or down onto a
  1516.      shorter line, the cursor will jump from its current horizontal
  1517.      position to the position after the last non-blank character of the
  1518.      short line.  When enabled, a "T" will appear on the indicator line. 
  1519.      The editing and movement will be similar to the original TEditor which
  1520.      always retained trailing spaces and did not provide for a free roaming
  1521.      cursor.
  1522.          For the most part, disabling the trailing space retention is most
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.      useful while editing source code.  As you move up and down the file,
  1531.      the cursor will maintain its horizontal position no matter how much
  1532.      the lines vary in length.  Enabling trailing space retention is mostly
  1533.      used for document type files where you may wish to keep trailing
  1534.      spaces on a line for formatting purposes.
  1535.          Note that saved files may shrink in size when edited with trailing
  1536.      space retention disabled.  The loss in size is due to the removal of
  1537.      trailing spaces during editing.  Likewise, a file may grow in size
  1538.      when saved if the file is edited with trailing space retention
  1539.      enabled.
  1540.  
  1541.      Hard Tab/Soft Tab (efUseHardTabs)
  1542.      ---------------------------------
  1543.          The hard or soft tab option controls what will happen whenever the
  1544.      tab key is pressed and Insert Mode is enabled.  While in overwrite
  1545.      mode, the tab key serves as a positional command and will simply move
  1546.      the cursor forward or backward.  An "H" for hard tabs or an "S" for
  1547.      soft tabs followed by the current tab size is always displayed on the
  1548.      indicator line.
  1549.          For hard tabs, the actual 0x09 tab character is inserted into the
  1550.      document.  Thus, if the tab size is changed while editing the
  1551.      document, the display will change to reflect this new tab size.  For
  1552.      soft tabs, the appropriate number of spaces are inserted into the
  1553.      current line to advance the cursor to the next tab stop.  Changes in
  1554.      the tab size while editing the document will have no visible effect on
  1555.      the display unless hard tabs were already present in the document.
  1556.  
  1557.      Undo/Redo (efCanUndo)
  1558.      ---------------------
  1559.          When Undo/Redo is enabled, you are able to undo edits and commands
  1560.      performed on the text.  Redo will, of course, put the changes back if
  1561.      you change your mind or undo too much.  The Undo/Redo capacity is only
  1562.      limited by available virtual memory (EMS/XMS + disk space).  It is
  1563.      possible to undo all changes to a file right back to when it was first
  1564.      loaded and then redo every single step.  However, if you edit text
  1565.      after a redo, any undo information after the last redo point will be
  1566.      lost because it is reused to record the undo information for the edits
  1567.      that where just done.
  1568.          Each undo/redo step is grouped based on the command executed.  For
  1569.      example, if you type in some words on a line and then change your
  1570.      mind, Undo will revert the line to the state it was in before you
  1571.      typed all those words.  Likewise, if you reformat a section of text
  1572.      and realize you've included too much, Undo will undo the entire
  1573.      reformat command and return the text to the state it was in before it
  1574.      was issued.  This could involve a few lines or several paragraphs. 
  1575.      Redo works exactly the same way.
  1576.          Some people might not consider Undo/Redo a local option.  This is
  1577.      entirely up to you.  To remove it from the local options is as simple
  1578.      as not offering it as a selection in the checkboxes that control these
  1579.      features.  When it is local, undo/redo can be enabled and disabled as
  1580.      many times as you like.  Keeping it as a local option has its
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.      advantages as you will now see.
  1589.          When Undo/Redo is enabled, the virtual memory manager will take
  1590.      some virtual memory to keep track of this information.  Thus there is
  1591.      some virtual memory overhead when enabled.  It will keep consuming
  1592.      virtual memory for each edited line until you actually close the
  1593.      editor.  With plenty of EMS, XMS, disk space, or a combination
  1594.      thereof, it should not be a problem.  If you need or want to conserve
  1595.      virtual memory, you can disable Undo/Redo.
  1596.          When disabled, the virtual memory manager will recycle any unused
  1597.      portions of virtual memory and place any new edited text in the
  1598.      discarded regions.  This will reduce the total amount of virtual
  1599.      memory used over the course of the editing session.  It will take
  1600.      steps to insure that if you enable Undo/Redo after it has been off, it
  1601.      will not go into these recycled regions.  It is therefore possible to
  1602.      leave Undo/Redo disabled until you need it, enable it for a while, and
  1603.      then disable it again if so desired.  Such a situation might arise
  1604.      while reformatting paragraphs.  It is easy to reformat from the wrong
  1605.      starting point and reformat too much text.  This is when Undo is a
  1606.      very helpful feature to have.
  1607.          Just remember that if you disable Undo/Redo after it has been on,
  1608.      you may not be able to undo or redo changes when it is re-enabled
  1609.      again due to the recycling that goes on behind the scenes.  As a rule,
  1610.      Undo/Redo will only work with changes made from the point it was
  1611.      enabled onward.
  1612.  
  1613.      Persistent, Non-persistent, and Overwriteable Marked Blocks
  1614.      -----------------------------------------------------------
  1615.          efNonPersistentBlocks and efAllowOverwrite (which combine to form
  1616.      the efOverwriteBlocks constant) allow the editor to use non-persistent
  1617.      and, if selected, overwriteable blocks.  A persistent block (used when
  1618.      efNonPersistentBlocks is not set) allows the user to mark a text block
  1619.      and then move away from it.  The user can go anywhere in the file and
  1620.      the block of text will remain marked until deselected by the user or a
  1621.      command that makes use of the block.  A non-persistent block will
  1622.      deselect automatically if the user tries to move away from the block
  1623.      after stopping block selection.  Typing a key or hitting Delete while
  1624.      the text is marked will delete the selected text if the Allow
  1625.      Overwrite option bit is set.
  1626.          If non-persistent blocks are enabled and overwriteable blocks are
  1627.      disabled, inserting text, deleting text, or moving the cursor will
  1628.      simply deselect any currently highlighted block.  Alternately,
  1629.      efAllowOverwrite can be enabled along with efNonPersistentBlocks to
  1630.      delete the selected block under those conditions.  Overwriteable
  1631.      blocks are not possible with persistent blocks because you can move
  1632.      the cursor away from the block.  Inserting text in that case would
  1633.      delete the block and insert the new text at the wrong location (this
  1634.      behaviour conforms to the way the BC++ 3.1 IDE uses these options).
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.      Enter Matching (efParen through efMatchAll)
  1643.      -------------------------------------------
  1644.          Borrowing a feature from my favorite editors (QEdit and TSE), I
  1645.      have enabled enter matching in the editor classes.  What this means is
  1646.      that for the left-hand characters (, [, {, ", ', and <, the editor can
  1647.      automatically enter the appropriate matching right-hand character ),
  1648.      ], }, ", ', or >.
  1649.          This mode can be individually enabled or disabled for each
  1650.      character via local option settings.  It is most useful while entering
  1651.      program source code or equations so that you don't forget a
  1652.      parenthesis or bracket.
  1653.          Of course, Enter Matching would not be complete without its
  1654.      counterpart Find Matching so I added that feature too.  By placing the
  1655.      cursor on either character of a (), [], {}, or <> pair and issuing the
  1656.      Find Matching command, the cursor will jump to the matching character. 
  1657.      When there is a missing or extra matching character, the cursor will
  1658.      either not go anywhere or will end up on an unexpected match.  For
  1659.      each of the listed pairs, the search will go in either direction based
  1660.      on the starting character you are positioned on and can span multiple
  1661.      lines.
  1662.          Find Matching can also be executed for the single and double quote
  1663.      marks.  However, because the character cannot be used to determine in
  1664.      which direction to go, all such matchings will go in the forward
  1665.      direction and are restricted to the current line only.
  1666.  
  1667.      Tab Size, Indent Size, Right Margin
  1668.      -----------------------------------
  1669.          Tab size controls how many spaces a tab represents when the text
  1670.      is displayed or printed.  For soft tabs, it will determine how many
  1671.      spaces are inserted or deleted whenever the Tab or Shift+Tab key is
  1672.      hit.  It should be a value from 2 to 16.
  1673.          Indent size controls how many characters will be inserted or
  1674.      removed from each line of the block when the Indent/Unindent commands
  1675.      are issued.  It should be a value from 1 to 16.  The Indent/Unindent
  1676.      commands are useful for shifting large blocks of text left or right in
  1677.      the editor all at the same time.
  1678.          The right margin value is associated with word wrapping and line
  1679.      centering.  It should be a value from 20 to 250.  Word wrapping will
  1680.      occur as described above with the specified right margin.  Line
  1681.      centering will center text between column 1 and the right margin
  1682.      setting.
  1683.          Note that all of the above commands have *suggested* legal ranges
  1684.      but the editor itself cannot and will not enforce those ranges.  It is
  1685.      up to the programmer to limit the values properly when altering them
  1686.      in source code or with the appropriate edits when they are entered
  1687.      using a dialog box from within an application.
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.      Global Editor Options
  1696.      =====================
  1697.          The following options will control all editors.  Note that there
  1698.      are global counterparts to each of the above described local options. 
  1699.      These serve as the defaults for each new editor object as they are
  1700.      created.  At instantiation, the new editor object will set each of its
  1701.      local options to the value of their global counterparts.  Any
  1702.      modification to the editor's local options will not be reflected in
  1703.      the global options.  Likewise, subsequent changes to the global
  1704.      options will not be reflected in any existing editor object's local
  1705.      options.  For example, if you have word wrapping turned off in the
  1706.      global options and later decide to enable it, any existing editor
  1707.      objects will retain their own setting for word wrapping.  Any new
  1708.      editor objects opened will inherit the new setting.
  1709.          For the following options, there are no local counterparts.
  1710.  
  1711.      Tab Expansion at Load Time (efExpandTabs)
  1712.      -----------------------------------------
  1713.          If enabled, any existing hard tabs in a file will be expanded to
  1714.      the appropriate number of spaces when the text is loaded into the
  1715.      editor.  This applies to the initial opening of the file or text
  1716.      inserted into the file with the Read Block command.
  1717.          This is useful if, like me, you prefer soft tabs to hard tabs. 
  1718.      Just be aware that if the current tab size setting is not the same as
  1719.      it was when the file was created, some text may not line up correctly
  1720.      in the loaded file.  Examples of this might be columnar data that was
  1721.      randomly formatted by separating some columns with spaces and others
  1722.      with tabs.  The loaded text may end up looking a little ragged.  Such
  1723.      files can always be loaded with the appropriate tab size and then you
  1724.      can adjust the editor's local tab size to suit your preferences.
  1725.  
  1726.      Backup File Creation (efBackupFiles)
  1727.      ------------------------------------
  1728.          Pretty much speaks for itself.  When enabled, the original file
  1729.      will be renamed with an extension of your choice (see below) as a
  1730.      backup.  When disabled, no such backup file is created.
  1731.          The TVMFileEditor class performs "safe saves" regardless of this
  1732.      setting.  It will never save directly to the real filename.  It saves
  1733.      the text to a temporary file first and renames it afterwards if all
  1734.      went well.  If there is a problem or error during the save, the
  1735.      original file is untouched and can be retrieved without problems.
  1736.  
  1737.      Use Line Feed (LF) Only When Saved (efUseLFOnly)
  1738.      ------------------------------------------------
  1739.          If this option is disabled, files are saved with each line
  1740.      separated by a carriage return-line feed pair (CR/LF).  This is the
  1741.      normal setting for text files on PC-based systems.  If you enable this
  1742.      option, files will be saved with lines separated by a single line feed
  1743.      (LF).  This is the way UNIX text files are stored.
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.      Files Are Read Only (efReadOnly)
  1752.      Set Read Only On Load (efSetROonLoad)
  1753.      -------------------------------------
  1754.          With the Read Only option enabled (efReadOnly), text is loaded
  1755.      into the editor as read-only.  Any commands that could modify the text
  1756.      within the editor are filtered out.  You are limited to moving around
  1757.      the file and copying sections of it to the clipboard, printing it, or
  1758.      saving marked blocks to a file.  The only thing that can modify the
  1759.      file on disk is to issue a Save As command and then save the file to
  1760.      the name it is currently using.
  1761.          If you set this global option to True and then create a clipboard,
  1762.      it will initially keep the read-only flag set.  If you were to view
  1763.      the clipboard on the desktop, it would display the read-only
  1764.      indicator.  However, as soon as you cut or copy something into it, it
  1765.      is smart enough to turn this bit off for itself and allow the
  1766.      insertion of text.  You don't need to do anything special or check for
  1767.      such a situation.
  1768.          The Set Read Only On Load option (efSetROonLoad), causes the file
  1769.      editor to look at the Read Only file attribute.  If set, the editor
  1770.      will automatically set its own efReadOnly bit to prevent alterations
  1771.      to a file that is marked as Read Only on the disk.
  1772.  
  1773.      Color Syntax Highlighting (efUseCSH)
  1774.      ------------------------------------
  1775.          The basic TVMEditor package does not use this option bit.  It is
  1776.      reserved for the Color Syntax Highlighter add-on (currently CSH 1.00). 
  1777.      The derived editor class uses this option to determine whether its
  1778.      text is drawn in the plain standard color or whether it should use the
  1779.      syntax highlighter to color its text.  See the CSH documentation for
  1780.      more information on this feature.
  1781.  
  1782.      Automatic End Of Line Marker (efAutoEOLMark)
  1783.      --------------------------------------------
  1784.          The efAutoEOLMark is placed with the Enter Matching options
  1785.      although it does not affect how they work.  The Auto End Of Line
  1786.      Marker option is used in conjunction with the TVMEditor class member
  1787.      EOLMarker.  Whenever ENTER is hit and this option is enabled, the
  1788.      EOLMarker character will be inserted.  Subsequent paragraph reformats,
  1789.      automatic word wraps, and wrap on resizes will prevent text from being
  1790.      appended to the line after that point.  For an idea of how this
  1791.      affects the editor, compile the demo with the '-DAUTOEOL' command line
  1792.      option.  It sets the necessary editor options and enables a visible
  1793.      end of line marker that is used whenever the ENTER key is hit.
  1794.  
  1795.      Signs Of Life Initialization and Reporting Intervals
  1796.      ----------------------------------------------------
  1797.          These two options control when Signs of Life are initiated and how
  1798.      often they are reported.  See the section on Signs of Life for more
  1799.      information.
  1800.  
  1801.  
  1802.  
  1803.  
  1804.  
  1805.  
  1806.  
  1807.      Default File Extension and Default Backup Extension
  1808.      ---------------------------------------------------
  1809.          These two options control what default extensions are used by the
  1810.      editor classes.  Currently, TVMFileEditor only makes use of the
  1811.      default file extension for Read and Write Block operations and the
  1812.      default backup extension when saving a file.  The default file
  1813.      extension can be used to store a default extension for use with an
  1814.      Open or Save As dialog box.  See the demo program for an example of
  1815.      this.
  1816.  
  1817.      Default Swap File Path
  1818.      ----------------------
  1819.          The default swap file path specifies the drive and directory in
  1820.      which all editor objects will store their swap file if one is created. 
  1821.      Be sure that there will be enough room on the given drive to hold
  1822.      them.  The swap file is only created when necessary and is removed
  1823.      when the editor object is destroyed.  A RAM drive is the ideal place
  1824.      to send the swap files provided it is large enough to contain files
  1825.      for the maximum number of editors that you may have open at once. 
  1826.      Note that if created, a swap file can grow to be larger than the
  1827.      original file depending upon the amount of editing done.  This is due
  1828.      to the extra information virtualized along with the actual text.  If
  1829.      you set the swap file path variable to an empty string, the swap files
  1830.      will be stored on the current drive in the current directory.
  1831.  
  1832.      Default Print Device
  1833.      --------------------
  1834.           The default print device specifies where printed text is sent. 
  1835.      By default, it is set to LPT1, but it can be changed to LPT2, COM1,
  1836.      COM2, a filename, etc.  This allows the default
  1837.      TVMFileEditor::PrintBuffer() function to be a little more flexible by
  1838.      allowing the user to specify the output device.  It was also written
  1839.      using low level, unbuffered, binary writes so that it stops printing
  1840.      when there is an error and ESC is pressed in the critical error
  1841.      handler.  The fprintf() function didn't always do this properly
  1842.      because it buffered the output.
  1843.  
  1844.  
  1845.      Search and Replace Options
  1846.      ==========================
  1847.          The search and replace features have been expanded to include more
  1848.      useful options.  They are described below.
  1849.  
  1850.      NOTE:  If you are using the search/replace options and the search
  1851.             fails when you didn't expect it to, check the option settings.
  1852.             It might be due to a setting that is not correct such as trying
  1853.             to search a selected block of text when none is selected, an
  1854.             incorrect scope setting, or an incorrect direction setting.
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862.      Find String and Replace String
  1863.      ------------------------------
  1864.          As before, these strings represent the text to search for and the
  1865.      text to be used for replacements.
  1866.  
  1867.      Options: Case Sensitive, Whole Words Only, Prompt On Replace
  1868.      ------------------------------------------------------------
  1869.          If Case Sensitive is selected, the case of the text is considered
  1870.      when searching for the find string.  If left unselected, the search
  1871.      will be case insensitive.
  1872.          If Whole Words Only is selected, the search is limited to finds
  1873.      that have a non-word character on either side.  The word characters
  1874.      are determined by a call to the virtual function isWordChar().  If
  1875.      left unselected, the search will include finds that occur within other
  1876.      words.
  1877.          Prompt on Replace is only available when doing a Search and
  1878.      Replace operation.  If selected, at each find you will be prompted to
  1879.      decide whether or not the replacement should be made.  If left
  1880.      unselected, changes are made without your consent.
  1881.  
  1882.      Direction: Forward or Backward
  1883.      ------------------------------
  1884.          Specifies which way the search will proceed.
  1885.  
  1886.      Scope: Global or Selected Text
  1887.      ------------------------------
  1888.          Due to the selected text block being persistent in nature, there
  1889.      is now a search and replace option that can limit the operations to
  1890.      that block.  If scope is set to Global, then the entire file is
  1891.      searched regardless of whether or not a block is selected.  Note that
  1892.      a Selected Text search will work even if the non-persistent block
  1893.      options are set.  This is done by temporarily disabling those options
  1894.      and then resetting them afterwards.
  1895.  
  1896.      Origin: From Cursor or Entire Scope
  1897.      -----------------------------------
  1898.          Origin specifies where the search will begin.  If From Cursor is
  1899.      selected, the search will proceed from the current cursor position
  1900.      forward or backward depending upon the Direction setting.  If Entire
  1901.      Scope is selected, the cursor is first moved to the appropriate end of
  1902.      the file or block depending on the selected scope and the search
  1903.      direction.  The search will then proceed either forward or backward
  1904.      depending upon the Direction setting.
  1905.          Note that if you use the Repeat Search command (default: ^L), it
  1906.      will automatically go into From Cursor mode and proceed in the
  1907.      appropriate direction until the end of the selected scope is reached.
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.      Command Operation and Implementation
  1916.      ====================================
  1917.          Most of the commands available in the editor speak for themselves
  1918.      as to their purpose.  For those that don't, those that have special
  1919.      rules, or those that need some clarification as to their operation,
  1920.      the following sections will describe them in more detail.
  1921.  
  1922.      Roll Window Up and Roll Window Down
  1923.      ===================================
  1924.          These commands will keep the cursor in its current horizontal and
  1925.      vertical position in the edit window, and will scroll the text up or
  1926.      down by one line.
  1927.  
  1928.      Tab Left and Tab Right
  1929.      ======================
  1930.          I've mentioned it elsewhere, but thought I might as well do it
  1931.      again.  When insert mode is off, the Tab and Shift+Tab key presses
  1932.      will serve as positional commands instead of text insertion/deletion
  1933.      commands.  They will simply move the cursor backwards or forwards by
  1934.      the appropriate tab width.  This was done to prevent accidental
  1935.      erasure of large chunks of text while insert mode is off.  Also be
  1936.      aware that if trailing space retention is enabled, when you press Tab
  1937.      with insert mode off the cursor will not proceed past the end of the
  1938.      line.
  1939.  
  1940.      Insert Literal Character
  1941.      ========================
  1942.          This command will take the next key press and insert it as a
  1943.      literal character into the file.  When ^P (the default key assignment)
  1944.      is pressed, the message <Literal> appears on the indicator line to
  1945.      show you that another key press is expected.  This is useful for
  1946.      inserting control codes into the text that normally cannot be entered
  1947.      such as ESC (Ctrl+P, ESC), end of file (Ctrl+P, Ctrl+Z), form feed
  1948.      (Ctrl+P, Ctrl+L), or the graphics characters used for special symbols
  1949.      and drawing (Ctrl+P, then hold down ALT and type a 3 digit number on
  1950.      the numeric keypad).
  1951.  
  1952.      Copy Block to Cursor and Move Block to Cursor
  1953.      =============================================
  1954.          These are non-clipboard versions of the copy, cut, and paste
  1955.      commands.  They will function even if there is no clipboard defined. 
  1956.      This is useful for applications that use memo fields but not the file
  1957.      editor.  Copy Block and Move Block can still be used.  Be warned that
  1958.      when moving or copying extremely large blocks of text in large files,
  1959.      these two functions tend to cause the virtual memory system to thrash. 
  1960.      In such cases it is better to use the clipboard.  Move Block and Copy
  1961.      Block will ignore requests to move text anywhere inside the marked
  1962.      block.
  1963.  
  1964.      Indent Block and Unindent Block
  1965.      ===============================
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.          The only special thing to note is that indent will not let lines
  1974.      exceed 255 characters and that unindent will continue to unindent
  1975.      blocks until there is nothing left on a line.  For example, if you
  1976.      unindented a block of lines to get rid of the spaces before the lines
  1977.      and then unindented again it would start chopping off the text in the
  1978.      lines too.
  1979.  
  1980.      Align Text
  1981.      ==========
  1982.          This command will align one or more lines of text (depending on
  1983.      whether or not a block is marked) with the first non-blank line above
  1984.      the starting point.  There can be one or more blank lines above the
  1985.      starting point.  It will keep looking for a non-blank line until it
  1986.      hits the top of the file.  If a non-blank line can't be found, no
  1987.      alignment will occur.
  1988.          After the alignment operation, the cursor will automatically
  1989.      advance to the next line ready for another operation.  This makes it
  1990.      easy to align several lines, one after the other, without selecting
  1991.      the block first.
  1992.  
  1993.      Paragraph Reformatting (Wrap Paragraph)
  1994.      =======================================
  1995.          This command will reformat text into paragraphs between the left
  1996.      and right margins.  This is done by aligning text with the effective
  1997.      left margin, extending short lines up to the right margin, and word
  1998.      wrapping long lines at the right margin.
  1999.  
  2000.          During reformatting, the following definitions apply:
  2001.  
  2002.          Space, white space, blanks
  2003.          --------------------------
  2004.              Any string of one or more characters consisting only of
  2005.          spaces, tabs, or the form feed character.  This is what separates
  2006.          the "words" during reformatting.  A line with a single form feed
  2007.          character in the first position is also considered a blank line.
  2008.          This is done to prevent the reformatting code from incorporating
  2009.          the form feed character into the line above it as a "word".
  2010.  
  2011.          Word
  2012.          ----
  2013.              Be aware that what is considered a word here may not be for
  2014.          commands such as Word Left or Word Right.  For the reformatting
  2015.          process, a word is considered to be any string of one or more
  2016.          characters separated by white space as defined above.
  2017.  
  2018.          Indent or Outdent
  2019.          -----------------
  2020.              During reformatting, a line is considered indented if it has
  2021.          more white space before the first word than lines following it.
  2022.          A line is considered to be outdented if it has less white space
  2023.          before the first word than lines following it.
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.              The indent or outdent of the line where reformatting starts
  2032.          is important because it determines when the end of a paragraph
  2033.          is reached in cases where following paragraphs are not separated
  2034.          by blank lines.  The indent or outdent of the second line is
  2035.          important because it determines the effective left margin for the
  2036.          rest of the paragraph.
  2037.  
  2038.          Examples:
  2039.  
  2040.              A.     This line is indented.
  2041.                 The line above is indented when compared to this one.
  2042.  
  2043.              B. This line is outdented.
  2044.                     The line above is outdented when compared to this one.
  2045.  
  2046.              C. This line is indented equally to the next line.
  2047.                 These lines are indented equally when compared to each
  2048.                 other.
  2049.  
  2050.          Effective Left Margin
  2051.          ---------------------
  2052.              The amount of white space up to but not including the first
  2053.          non-space character of a line.  This is the amount of indentation
  2054.          that will be placed on each line of the paragraph as they are
  2055.          formatted.  It is determined for each paragraph by looking at the
  2056.          amount of white space on the line immediately following the one
  2057.          where reformatting will start.
  2058.          Paragraph
  2059.          ---------
  2060.              Blocks of text that are either separated by one or more
  2061.          blank lines or, in the absence of blank lines between them, have
  2062.          a starting line that is indented or outdented an equal amount to
  2063.          other paragraphs.
  2064.  
  2065.      Reformatting Rules
  2066.      ------------------
  2067.          There are a number of rules that the editor will follow when
  2068.      reformatting text.  These rules may not interest you or may not give
  2069.      an entirely clear picture of what happens under all circumstances.  To
  2070.      get a good feel for how paragraph reformatting truly works, it is best
  2071.      to just play with it and see what happens under odd or unique
  2072.      circumstances.  The following paragraphs will try to explain what goes
  2073.      on.  Even if you don't want to know the gory details, at least read
  2074.      the "PLEASE NOTE" section below.  There are situations in which no
  2075.      reformatting will occur or the end of a paragraph cannot be determined
  2076.      with certainty and it may end up reformatting more than you intended.
  2077.  
  2078.          When executed, the reformatting starts at the current cursor line
  2079.      and will continue until a blank line, the end of the file, the end of
  2080.      the selected text block (if any), or a line with an indent or outdent
  2081.      equal to that of the starting line is reached.  The cursor will be
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.      place on the line immediately following the last line of the
  2090.      paragraph.  Note that if a selected text block is defined, the cursor
  2091.      will be moved to the first line of the block and the editor will
  2092.      reformat as many paragraphs as it can find until the end of the block
  2093.      is reached.  If no block is selected, only the paragraph the cursor is
  2094.      in will be reformatted starting at the current cursor line and
  2095.      continuing until one of the above mentioned end conditions is met.
  2096.          The starting line is considered to be the first line of the
  2097.      paragraph and will not have its indentation changed.  The effective
  2098.      left margin is determined by using the indentation on the line
  2099.      immediately after the starting line.  Subsequent lines will be
  2100.      indented or outdented to match the effective left margin.
  2101.          As the text is reformatted, long lines are word wrapped if they
  2102.      exceed the right margin and short lines are extended with words from
  2103.      subsequent lines until they are as close as possible to the right
  2104.      margin.  As words are added to a line, a single separating space is
  2105.      included before the appended word.  Leading and trailing spaces for
  2106.      appended words are stripped out.  When I was taught to type, I was
  2107.      told that two spaces after every period was the standard and I've
  2108.      followed that "rule" ever since.  Therefore, if a period is
  2109.      encountered prior to adding a word, two spaces are inserted before
  2110.      adding the next word to the line.  Reformatting continues until one of
  2111.      the above mentioned end conditions is met.
  2112.  
  2113.      PLEASE NOTE:
  2114.      ============
  2115.          If a line contains no spaces at all or just some indentation
  2116.      followed by a string of non-space characters and it exceeds the right
  2117.      margin, that line will not be wrapped.  However, it will be indented
  2118.      to conform to the effective left margin.  An example might by a drawn
  2119.      box border or one that continuously underlines (i.e. -----) the text
  2120.      above it.  This generally isn't a problem and usually only occurs if
  2121.      you choose to start reformat text in the wrong place.
  2122.          If the effective left margin is past the specified right margin,
  2123.      no word wrapping will occur.  As an example, if the right margin is
  2124.      set at 72 and the first word does not start until column 74 when
  2125.      determining the effective left margin, no word wrapping will occur. 
  2126.      There must also be at least one full word followed by a space prior to
  2127.      the right margin for word wrapping to occur.
  2128.  
  2129.  
  2130.  
  2131.  
  2132.  
  2133.  
  2134.  
  2135.          THIS ONE IS IMPORTANT!  If you start reformatting on a line that
  2136.      has no indentation or one that has an equal amount of indentation as
  2137.      subsequent lines, the editor is only able to determine the end of the
  2138.      paragraph by encountering a blank line, the end of the file, or the
  2139.      end of a defined block.  The matching indent/outdent criteria will be
  2140.      ignored so that it doesn't stop reformatting immediately on the next
  2141.      line.
  2142.          As an example, if you were to start reformatting from the second
  2143.      line of the preceding paragraph instead of the first, this paragraph
  2144.      and the ones following it would be merged into it because the
  2145.      indentation on the next line (third line) matches the starting line
  2146.      (second line).  Reformatting won't stop until the blank line is hit. 
  2147.      Load a copy of this file into the editor and try it out if this isn't
  2148.      clear.  As I said before, playing with this command is the best way to
  2149.      see how it reacts.
  2150.          This problem can also occur if you are not diligent about making
  2151.      all of your paragraph's first lines use a standard amount of
  2152.      indentation.  Remember, if paragraphs aren't separated by a blank
  2153.      line, reformatting will continue until a line is reached that has an
  2154.      indent or outdent *EQUAL* to that of the starting line.
  2155.          If you absolutely need to reformat a paragraph or a portion of one
  2156.      in which the above situation could occur, there is an easy way to
  2157.      avoid it.  The way to do it is with a selected block of text.  Simply
  2158.      block select the portion of text you wish to have reformatted just
  2159.      like you would if you were going to move it or copy it to the
  2160.      clipboard.  Once marked, simply issue the reformat command and it will
  2161.      format the text from the top of the block and stop when it reaches the
  2162.      last line of the block.
  2163.          Marking a block is also the way to get the reformat command to
  2164.      work on multiple paragraphs in one shot.  Simply block select all the
  2165.      paragraphs to reformat and issue the command.  However, be warned that
  2166.      if the selected block's first line has an indent equal to the second
  2167.      line, you will still run into the above described situation.  Not to
  2168.      worry though.  If you make a mistake, the Undo command can always back
  2169.      you out of a botched reformat (provided that you have Undo/Redo turned
  2170.      on first! <g>).
  2171.  
  2172.  
  2173.      Clipboard Commands
  2174.      ==================
  2175.          As noted, secondary keys have been defined for these operations so
  2176.      that they can be used while debugging programs in the BC++ 3.1 DOS
  2177.      IDE.  Many is the time I've seen people on the BCPPDOS forum ask why
  2178.      the clipboard commands didn't work.  The reason is that the IDE traps
  2179.      them and the application being debugged never sees them.  With the
  2180.      secondary commands, this is no longer a problem.  Besides which, it
  2181.      was impossible to debug the clipboard commands when I couldn't access
  2182.      them <g>.
  2183.          One unique characteristic of the clipboard that I have made use of
  2184.      is that when new text is cut or copied to the clipboard, any marked
  2185.      text is deleted but any unmarked text is left untouched.  Knowing
  2186.  
  2187.  
  2188.  
  2189.  
  2190.  
  2191.  
  2192.  
  2193.      this, it is possible to open the clipboard on the desktop, copy or cut
  2194.      a block of text to the clipboard, then change to the clipboard and
  2195.      hide the block.  You can then move the cursor to the end of the
  2196.      clipboard text, go back to another window, and cut or copy another
  2197.      piece of text to the clipboard.  This has the effect of appending the
  2198.      next block to the text already in the clipboard.  You can repeat this
  2199.      process as often as you need to merge several pieces of text into the
  2200.      clipboard.  Finally, you can go into the clipboard and save it as a
  2201.      different file or select the entire contents as a block and paste it
  2202.      into other files.
  2203.  
  2204.      Set Bookmark and Jump to Bookmark
  2205.      =================================
  2206.          By default, I've used <^K1>, <^K2>, <^K3>, <^J1>, ,<^J2>, and
  2207.      <^J3> as the keys to access these commands.  One important thing to
  2208.      note is that if you are still holding down the Ctrl key when you press
  2209.      1, 2, or 3, the editor will not see the command.  This is because the
  2210.      computer won't generate scan codes for Ctrl+1, Ctrl+2, and Ctrl+3. 
  2211.      Let go of the Ctrl key before pressing the 1, 2, or 3.  For that
  2212.      matter, you should be letting go of Ctrl for the second key of any
  2213.      two-key commands unless otherwise noted.  It isn't required on the
  2214.      second key press.
  2215.  
  2216.      Events                                  Commands
  2217.      ================================        ====================
  2218.      Save Modified File Prompt               Read Block
  2219.      Save Untitled File Prompt               Write Block
  2220.      Save File As Prompt                     Find
  2221.      Replace Text Verification Prompt        Find and Replace
  2222.      Search Failed Prompt                    Change Local Options
  2223.                                              Goto Line
  2224.  
  2225.          Just like the original TEditor classes, the TVMEditor classes use
  2226.      an editorDialog() function defined by you to handle user interaction
  2227.      for commands that require some form of acknowledgement or input.  The
  2228.      above listed events and commands require some form of interaction with
  2229.      the user before they can be formally completed.
  2230.          TVMEditor::editorDialog is a static function pointer in the
  2231.      TVMEditor class that points to your function or a default function
  2232.      supplied by me.  To be fully implemented, you must define and replace
  2233.      the function pointer that TVMEditor::editorDialog points to with a
  2234.      pointer to your own handler.
  2235.          In addition to the above listed events and commands, there are
  2236.      several diagnostic or informative messages that editorDialog() will
  2237.      handle too.  Most of these can be safely ignored, but the first eight
  2238.      message types cannot be ignored.  They refer to such things as swap
  2239.      file failure, file save failure, etc.  If you do not replace the
  2240.      default function with your own, these will be handled by the default
  2241.      function with a simple message box that displays the error number that
  2242.      occurred.  A complete list of possible values can be seen in TVMEDIT.H
  2243.      (the edXXXXX constants).  The doEditDialog() function in TVEDIT2.CPP
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.      of the demo program shows you how to handle each of the events.  You
  2252.      may use this one if you like or create your own that handles a subset
  2253.      of the events.
  2254.          Note that the above listed commands will not be accessible unless
  2255.      you replace the default editorDialog() function to handle them as show
  2256.      in TVEDIT2.CPP.  Remember that TVMMemo now has access to all of these
  2257.      features as well, so if you write an application that uses TVMMemo but
  2258.      not TVMFileEditor, you will still need to define an editorDialog()
  2259.      function to handle the commands you want TVMMemo to have access to. 
  2260.      For example, you might let it have access to Goto Line, Find, Find and
  2261.      Replace, and leave out the other commands so that they are ignored.
  2262.  
  2263.      Signs Of Life
  2264.      =============
  2265.           Okay, it sounds strange, but that's exactly what it is.  On
  2266.      really large files, the delay in returning control to the user in
  2267.      conjunction with in-memory swapping (EMS/XMS for real mode or
  2268.      conventional memory for protected mode) gives no indication that
  2269.      anything is really happening.  It is possible that you might think it
  2270.      has locked up when it really hasn't.  Basically, enabling Signs of
  2271.      Life entails adding code to call a user specifiable function that
  2272.      gives you some feedback during potentially long operations such as
  2273.      file load/save, block operations, search/replace, etc so that you know
  2274.      the editor is still alive and kicking.  Even with the additional
  2275.      function call overhead, there is extremely little drop in performance
  2276.      and you have complete control over how often the function is called. 
  2277.      The supplied demo editor contains a simple but effective Signs of Life
  2278.      handler in the TVEDIT3.CPP module.
  2279.  
  2280.      How It Works
  2281.      ------------
  2282.           In general, your Signs of Life function has to handle certain
  2283.      events.  Those events are defined as follows:
  2284.  
  2285.      slInitiate    Get ready to start showing signs of life.  This may
  2286.                    include creating a dialog box and inserting it into
  2287.                    the desktop and initializing any necessary counters,
  2288.                    spinners, progress bars, etc that you may want to
  2289.                    use.  Signs of life are only initiated after the
  2290.                    command in progress has processed a number of lines
  2291.                    specified in the global options structure.
  2292.  
  2293.      slReporting   This is the "heartbeat" event.  It is issued every so
  2294.                    often based on a setting in the global option
  2295.                    structure.  Each time your handler is called with
  2296.                    this event code, it should do something to show
  2297.                    "signs of life".  This might be something like
  2298.                    turning a spinner, showing count information, or
  2299.                    updating a progress bar.
  2300.  
  2301.      slHide        The default editors do not make use of either slHide
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.      slShow        or slShow.  However, they are here in case you need
  2310.                    them.  The intended use of slHide and slShow are to
  2311.                    temporarily suspend signs of life and perhaps hide
  2312.                    the progress dialog box while the user is prompted
  2313.                    for some other input or is asked to confirm some part
  2314.                    of the operation.  Once the interruption is over,
  2315.                    slShow can be used to redisplay the dialog box and
  2316.                    continue on as normal.
  2317.  
  2318.      slDone        This is always called when the event is finished to
  2319.                    terminate the signs of life display.  It is in this
  2320.                    event that you would dispose of any dialog box or
  2321.                    other items that you may have inserted into the
  2322.                    desktop.
  2323.  
  2324.           Installing your Signs of Life handler is as simple as assigning
  2325.      its address to the TVMEditor::signsOfLife data member:
  2326.  
  2327.          TVMEditor::signsOfLife = doSignsOfLife;
  2328.  
  2329.      The function prototype would be something like:
  2330.  
  2331.          void doSignsOfLife(SignsOfLife lifeSign, ushort cmnd,
  2332.                  long count, long total);
  2333.  
  2334.      The parameters passed to it are:
  2335.  
  2336.      SignsOfLife lifeSign    One of the above slXXXXX definitions.
  2337.  
  2338.      ushort cmnd             The command being executed.  The basic
  2339.                              editors will issue signs of life during the
  2340.                              following command events:
  2341.  
  2342.                                  cmMoveBlock     cmClear
  2343.                                  cmCopyBlock     cmUndo
  2344.                                  cmReadFile      cmFind
  2345.                                  cmWriteBlock    cmFindMatching
  2346.                                  cmPrintBlock    cmWrapPara
  2347.  
  2348.                                  All commands handled by the alterText()
  2349.                                  function.
  2350.  
  2351.                              cmCopyBlock is also used to denote
  2352.                              insertion to/from the clipboard.
  2353.                              cmReadFile reports its progress in bytes
  2354.                              read and total bytes instead of lines
  2355.                              processed and total lines.
  2356.                              cmUndo serves the undo and the redo
  2357.                              operations.
  2358.                              See TVMEditor::alterText() for the commands
  2359.                              that it handles.
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.                              NOTE: If you see a deletion taking place at
  2368.                                    the start of a clipboard operation,
  2369.                                    don't panic!  It's just from the
  2370.                                    cmClear issued to erase any marked
  2371.                                    block currently in the clipboard.
  2372.  
  2373.      long count              This is the current number of lines
  2374.                              processed (or bytes for cmReadFile) out of
  2375.                              the total number specified in the 'total'
  2376.                              parameter.
  2377.  
  2378.      long total              This is the total number of lines (or
  2379.                              bytes) that are to be processed.  Using
  2380.                              this information with the 'count'
  2381.                              parameter, it is possible to show progress
  2382.                              either by displaying the actual numbers or,
  2383.                              if you want to get  sophisticated, by
  2384.                              displaying a progress bar.
  2385.  
  2386.      Controlling Signs of Life
  2387.      -------------------------
  2388.           The GlobalEditorOptions structure contains these two fields:
  2389.  
  2390.           short initThreshold;
  2391.           short reportInterval;
  2392.  
  2393.           These two values indicate when signs of life should be issued by
  2394.      the editor.  What this means is that after initThreshold lines, the
  2395.      editor will place an slInitiate call to the signsOfLife() function to
  2396.      let the user know it is still working and hasn't locked up.  After
  2397.      that, it will place an slReporting call (the "heartbeat") every
  2398.      reportInterval lines.  Whenever signs of life has been started and the
  2399.      operation completes, a final call is placed to signsOfLife() with a
  2400.      value of slDone and 'count' and 'total' are equal to the same value.
  2401.  
  2402.      NOTE: If either of the above variables is set to zero, Signs of
  2403.            Life reporting will be disabled and the editors will perform
  2404.            the entire operation with no indication of progress.
  2405.  
  2406.           As stated above, the cmReadFile command reports its progress in
  2407.      bytes.  This is because it has no way of telling how many lines are in
  2408.      a file until it has completely finished processing it.  However, it
  2409.      does count up how many lines it has inserted as it reads the file so
  2410.      that it knows when to start and how often to call the signsOfLife()
  2411.      function.
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419.                               Data and Function Members
  2420.                               -------------------------
  2421.  
  2422.      ----------------------------------------------------------------------
  2423.      struct GlobalEditorOptions
  2424.      {
  2425.          ushort Operation,       // Default operating modes
  2426.                 EnterMatch;      // Default Enter Matching characters
  2427.  
  2428.          short  TabSize,         // Default tab size
  2429.                 IndentSize,      // Default block indent size
  2430.                 RightMargin;     // Default right margin
  2431.  
  2432.          // NOTE: Any changes in the structure ABOVE this point should also
  2433.          //       be taken into account for structure LocalEditorOptions
  2434.          //       below.  The rest of this structure is for global items
  2435.          //       only.
  2436.  
  2437.          // Search options
  2438.          ushort Search;
  2439.  
  2440.          // Signs of Life.
  2441.          // These two values indicate when signs of life should be issued
  2442.          // by the editor.  What this means is that after initThreshold
  2443.          // lines, the editor will place a call to the signsOfLife()
  2444.          // function to let the user know it is still working and hasn't
  2445.          // locked up.  After that, it will place a call to it every
  2446.          // reportInterval lines.
  2447.          short initThreshold;
  2448.          short reportInterval;
  2449.  
  2450.          // Default filename extensions.  These are currently only used by
  2451.          // TVMFileEditor.
  2452.          char   DefaultExt[4], BackupExt[4];
  2453.  
  2454.          // Default drive/dir for swap files.  This can be used by virtual
  2455.          // memory systems needing a swap file for each editor instance.
  2456.          char   DefaultSwapDir[MAXPATH];
  2457.  
  2458.          // Print Device (LPT1, LPT2, COM1, COM2, filename, etc).
  2459.          char   PrintDevice[MAXPATH];
  2460.      }
  2461.      ----------------------------------------------------------------------
  2462.          The GlobalEditorOptions structure contains options used by all
  2463.      editor object instances along with the defaults for the local options
  2464.      structure when a new one is first created.
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.      --------------------------------------------------------
  2473.      struct LocalEditorOptions
  2474.      {
  2475.          ushort Operation,       // Operating modes
  2476.                 EnterMatch;      // Enter Matching characters
  2477.  
  2478.          short  TabSize,         // Tab size
  2479.                 IndentSize,      // Block indent size
  2480.                 RightMargin;     // Right margin
  2481.      }
  2482.      --------------------------------------------------------
  2483.          The LocalEditorOptions structure contains options that are local
  2484.      to each instance and can be changed for each one without affecting any
  2485.      of the other objects.
  2486.  
  2487.      -----------------------------------------
  2488.      static TVMEditorDialog _NEAR editorDialog
  2489.      -----------------------------------------
  2490.          This is a pointer to a function that you can define to handle
  2491.      commands and events that require some form of user interaction or
  2492.      acknowledgement.  The function it points to takes a single type short
  2493.      parameter and a variable number of additional arguments.  The type
  2494.      short parameter is one of the edXXXXX constants described earlier in
  2495.      this file.  A complete list can be found in TVMEDIT.H.  An example of
  2496.      this handler can be found in the demo program in TVEDIT2.CPP.
  2497.  
  2498.      ---------------------------------------
  2499.      static TVMSignsOfLife _NEAR signsOfLife
  2500.      ---------------------------------------
  2501.           This is a pointer to a function that you can define to issue
  2502.      "signs of life" during long operations performed by the editor such as
  2503.      file insertions, printing, saving, loading, etc.  An example of this
  2504.      handler can be found in the demo program in TVEDIT3.CPP.  Also, see
  2505.      the section above on Signs of Life.
  2506.  
  2507.      ----------------------------------
  2508.      static TVMEditor * _NEAR clipboard
  2509.      ----------------------------------
  2510.          This is a pointer used by all editors to access the clipboard.  By
  2511.      default, it is NULL (no clipboard defined).  If you would like your
  2512.      application to have a clipboard, simply create a TVMEditor object and
  2513.      store its address in this data member.
  2514.          Any TVMEditor can be the clipboard.  It just needs to be assigned
  2515.      to this variable.  If you simply want an editor object as the
  2516.      clipboard, use TVMEditor to construct one.  If you would like a
  2517.      viewable clipboard (like the one in the demo program), use
  2518.      TVMEditWindow to create an edit window object and set 'clipboard'
  2519.      equal to the address of the edit window's 'editor' data member:
  2520.  
  2521.                TVMEditWindow *clipWindow = new TVMEditWindow(...);
  2522.                TVMEditor::clipboard = clipWindow->editor;
  2523.  
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.          See the demo program in TVEDIT1.CPP for a more detailed example.
  2531.  
  2532.      -----------------------------------
  2533.      static const char * _NEAR charLeft
  2534.      static const char * _NEAR charRight
  2535.      -----------------------------------
  2536.          These two pointers simply define the left and right-hand Enter
  2537.      Matching and Find Matching characters.  By default, the characters
  2538.      defined are (, [, {, ', ", and < for the left-hand characters and the
  2539.      appropriate match for the right-hand characters.
  2540.  
  2541.      ------------------------------------
  2542.      static const char * _NEAR TwoKeyMsg
  2543.      static const char * _NEAR LiteralMsg
  2544.      ------------------------------------
  2545.          These two pointers are used to define the default Two Key and
  2546.      Literal command flag messages.  Whenever the first key of a two-key
  2547.      command or the Literal command key is pressed, the text pointed to
  2548.      will be displayed on the indicator line if one is present. By default,
  2549.      the messages are set to <Two Key> and <Literal>.
  2550.  
  2551.      ---------------------------
  2552.      static char _NEAR EOLMarker
  2553.      ---------------------------
  2554.          This is the line length inhibitor character (also referred to as
  2555.      the End Of Line marker or hard return).  Set this character to the one
  2556.      you want wrapPara() to use when determining if a line should not be
  2557.      lengthened.  By default it is '\xFF'.  You can make this a visible
  2558.      character if you want to (the left chevron (\xAE) would be a good
  2559.      one).  To enable auto insertion of TVMEditor::EOLMarker whenever a
  2560.      cmNewLine command is seen (i.e. hitting ENTER), set the efAutoEOLMark
  2561.      in Opts.EnterMatch (or GlobalOpts.EnterMatch for global usage by
  2562.      default).  The default TVMFileEditor::PrintBuffer will strip EOLMarker
  2563.      characters automatically before printing to save you from having to do
  2564.      it.
  2565.          The wrapPara() function skips lengthening of lines ending in this
  2566.      character.  This is a form of "hard return" that lets it know when a
  2567.      line should be excluded from reformatting past that point.  This is
  2568.      most useful in Wrap On Resize enabled editors with title lines or
  2569.      section headings which should not be extended.  It can also be used in
  2570.      conjunction with automatic word wrapping so that whenever the user
  2571.      hits ENTER, a "hard return" is inserted.  In all other cases, the
  2572.      editor wraps text at the right margin and reformats it as necessary. 
  2573.      The inhibitors prevent it from wrapping too much text in situations
  2574.      that might otherwise cause it to wrap more than you want it to.  For
  2575.      an idea of what this does, compile the demo with the switch
  2576.      '-DAUTOEOL'.  This sets the necessary option bits in the global
  2577.      options structure and enables a visible EOL marker (\xAE).
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.      -------------------------------------------
  2586.      static GlobalEditorOptions _NEAR GlobalOpts
  2587.      -------------------------------------------
  2588.          This is the global options structure shared by all editor
  2589.      instances.  The values in this structure are used as the defaults for
  2590.      each new editor's local options.  It also contains some of the default
  2591.      search and replace options, the default file extensions, and default
  2592.      swap path.
  2593.  
  2594.      ------------------------------------------------
  2595.      static ushort _NEAR searchDirection
  2596.      static ushort _NEAR searchScope
  2597.      static ushort _NEAR searchOrigin
  2598.      static char   _NEAR findStr[maxFindStrLen]
  2599.      static char   _NEAR replaceStr[maxReplaceStrLen]
  2600.      ------------------------------------------------
  2601.          These data members contain the other search and replace options. 
  2602.      They are also shared by all editor instances.
  2603.  
  2604.      --------------------------------
  2605.      static unsigned short lowMemDesc
  2606.      --------------------------------
  2607.           This static public data member holds the descriptor used to
  2608.      access the BIOS keyboard flags in 32-bit protected mode.  In real mode
  2609.      and 16-bit protected mode, this data member is not defined.  Since it
  2610.      is public, your application is also free to make use of it if you need
  2611.      to.  If you are sure that an editor has been instantiated (either in
  2612.      the desktop or a clipboard during start-up), you don't need to check
  2613.      its contents to verify that a valid descriptor has been assigned.  If
  2614.      you have some doubts about whether or not a descriptor has been
  2615.      assigned yet, you can place a call to the AllocateDescriptor()
  2616.      function at some point to establish a value manually.  Calling it will
  2617.      not harm any currently assigned descriptor.  If one has already been
  2618.      established, the function simply returns.  You can tell if a
  2619.      descriptor has been assigned because lowMemDesc will be non-zero.
  2620.  
  2621.      ----------------------
  2622.      TVirtualMemory *Buffer
  2623.      ----------------------
  2624.          This is a pointer to the virtual memory buffer object.  The
  2625.      virtual memory manager is a separate entity to allow the modification
  2626.      of the underlying virtual memory engine (switch from EMS + disk to XMS
  2627.      + disk, use an alternate method for protected mode, etc).  Also,
  2628.      multiple editors can share the same buffer object to conserve memory. 
  2629.      Note that if no EMS or XMS memory is available, it will go straight to
  2630.      disk for its virtual memory.
  2631.          This is a public member of TVMEditor and some of its functions can
  2632.      be accessed directly by you.  This allows direct storage and retrieval
  2633.      of text on a line-by-line basis.  This makes it easy to work with the
  2634.      text, especially for memo fields.
  2635.  
  2636.  
  2637.  
  2638.  
  2639.  
  2640.  
  2641.  
  2642.      ---------------------------
  2643.      Boolean isValid, LineEdited
  2644.      ---------------------------
  2645.          isValid is used to signal whether or not it is okay to continue
  2646.      using the editor object after construction.  This can be used in
  2647.      conjunction with validView() to see whether or not it should be
  2648.      inserted into the desktop.
  2649.          LineEdited is True when the line that the cursor is on has been
  2650.      modified.  It is used to determine whether or not text should be
  2651.      stored in a new virtual memory location and undo information recorded
  2652.      using the original data.  When False, the line has not been edited and
  2653.      no such operations are performed when the cursor moves to a different
  2654.      location.
  2655.  
  2656.      -----------------------
  2657.      LocalEditorOptions Opts
  2658.      -----------------------
  2659.          This structure holds the local options for the editor instance.
  2660.  
  2661.      ------------------------
  2662.      TScrollBar   *hScrollBar
  2663.      TVMScrollBar *vScrollBar
  2664.      TVMIndicator *indicator
  2665.      ------------------------
  2666.          These three pointers refer to the horizontal and vertical
  2667.      scrollbars and the indicator line passed to the constructor.  If set
  2668.      to NULL, then the associated item will not be used for the given
  2669.      editor instance.
  2670.  
  2671.      ----------------------------
  2672.      char Text[maxLineLength + 1]
  2673.      ----------------------------
  2674.          This is an intermediate editing buffer for the line that the
  2675.      cursor is sitting on.  Changes are made to this line and, when
  2676.      LineEdited is True, this text is used to replace the old text before
  2677.      the cursor moves to a different location.  If LineEdited is False,
  2678.      then any information in this buffer is discarded when moving the
  2679.      cursor to a new line.
  2680.  
  2681.      -----------------------------
  2682.      TVMPoint delta, limit, curPos
  2683.      -----------------------------
  2684.          The TVMPoint 'delta' is used to hold the horizontal and vertical
  2685.      offsets into the buffer text when updating the screen.  It represents
  2686.      the top line and left-most column shown in the view.
  2687.          The TVMPoint 'limit' is used to hold the current horizontal and
  2688.      vertical limits for the buffer.  Currently, the horizontal limit is
  2689.      used only by the horizontal scrollbar.  The vertical limit is always
  2690.      updated as lines are added or deleted in the buffer.  It controls the
  2691.      vertical scrollbar limit and also gives an upper boundary to commands
  2692.      that operate on the entire file.
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.          The TVMPoint 'curPos' is used to record the cursor's current
  2701.      horizontal and vertical position within the text buffer.
  2702.  
  2703.      ------------------------
  2704.      short selStartC, selEndC
  2705.      ------------------------
  2706.           The selStartC and selEndC data members are used to remember the
  2707.      currently marked block's start line column and end line column.  If
  2708.      either selStart or selEnd (the line markers) is zero, then any non-
  2709.      zero value in selStartC and/or selEndC is undefined.  Note that if
  2710.      selStart is equal to selEnd and selStartC is equal to selEndC, the the
  2711.      block starts and end at the same point and will not be visible on
  2712.      screen.  A marked block must be at least one column wide but may be
  2713.      limited to a portion of a single line.
  2714.  
  2715.      --------------------------------------------------
  2716.      long selStart, selEnd, drawLine, findLine, setLine
  2717.      --------------------------------------------------
  2718.          The selStart and selEnd data members are used to remember the
  2719.      currently marked text block (if any).  When either or both are zero,
  2720.      then no marked block is currently defined.  When both are non-zero,
  2721.      they represent the starting and ending lines of the block.
  2722.          The drawLine data member is used only when refreshing the entire
  2723.      screen display.  It defines the line that is currently at the top of
  2724.      the window.
  2725.          The findLine and setLine data members are also used when
  2726.      refreshing the screen display.  findLine is used by the search and
  2727.      replace options to signal which line is currently holding the found
  2728.      text (if any).  setLine is used by the cmSetLine command to signal
  2729.      which line was just moved to.  They are used by the screen draw
  2730.      routines to highlight the necessary text in a different color.
  2731.  
  2732.      ------------------------------------------------
  2733.      SignsOfLife sl_Type
  2734.      long sl_Count, sl_ReportMark, sl_Bytes, sl_Total
  2735.      ------------------------------------------------
  2736.           These are used internally to track if and when signs of life
  2737.      should be issued during lengthy operations.  You are free to use these
  2738.      in derived classes if you need to to set up signs of life in your own
  2739.      operations that may need them.
  2740.  
  2741.      ---------------
  2742.      short curPosx_t
  2743.      ---------------
  2744.          This data member keeps track of the cursor position within the
  2745.      temporary Text[] buffer.  Due to hard tabs, this cursor position and
  2746.      the curPos.x display cursor position may not be identical in value.  A
  2747.      physical hard tab character will represent only one character in
  2748.      Text[].  However, that single character can represent any number of
  2749.      displayed spaces based on the current TabSize setting in the local
  2750.      options data structure.
  2751.  
  2752.  
  2753.  
  2754.  
  2755.  
  2756.  
  2757.  
  2758.      --------------
  2759.      short keyState
  2760.      --------------
  2761.          This data member is used to track the two-key command state.  When
  2762.      zero, the next key press is interpreted using the single key command
  2763.      map.  When non-zero, it indicates that a special key such as Ctrl+K
  2764.      has been pressed.  It's value represents the map to look at when
  2765.      locating a command for the second key press of a two-key command.  For
  2766.      example, when Ctrl+K is pressed, keyState will change from zero to a
  2767.      number that represents the location of the Ctrl+K key's map of valid
  2768.      second key presses.  That map will be used when interpreting the very
  2769.      next key press to see if it matches one of the commands in that map.
  2770.          When the second key press matches a command key in the next map,
  2771.      that command is executed and keyState returns to zero.  If the second
  2772.      key press does not match a command key in the next map, it is ignored
  2773.      and keyState will return to zero.  See changeKeyMap() for more
  2774.      detailed information on how all of this works.
  2775.  
  2776.      ----------------------------
  2777.      uchar lockCount, updateFlags
  2778.      ----------------------------
  2779.          The lockCount data member is used internally by some routines to
  2780.      prevent unnecessary screen updates.  When non-zero, the screen draw is
  2781.      suppressed.  This variable is only modified by the lock() and unlock()
  2782.      member functions.
  2783.          The updateFlags data member determines which parts of the screen
  2784.      will be drawn when lockCount is equal to zero.  One or more of the
  2785.      ufXXXXX constant bits is set based on the operation that requires the
  2786.      screen update.
  2787.  
  2788.      ---------------
  2789.      short selecting
  2790.      ---------------
  2791.          This data member will be set to one of the smXXXXX constants
  2792.      described earlier and indicates the current block marking state of the
  2793.      editor.
  2794.  
  2795.      -----------------
  2796.      Boolean FirstLoad
  2797.      -----------------
  2798.          This is an internal flag used by the editor and the virtual memory
  2799.      buffer to signal that the first text load operation is about to occur. 
  2800.      When True, the virtual memory buffer will take steps to avoid
  2801.      unnecessary thrashing as the text is loaded for the first time and
  2802.      also will not record undo/redo information during that time.  When set
  2803.      to False after the first load, the buffer object will revert to its
  2804.      normal LRU mechanisms and will record undo/redo information if any
  2805.      text is edited.
  2806.  
  2807.  
  2808.  
  2809.  
  2810.  
  2811.  
  2812.  
  2813.      ----------------------
  2814.      Boolean hasChangedSize
  2815.      ----------------------
  2816.          This flag is used in conjunction with the efWrapOnResize option
  2817.      bit to determine if the editor has changed its bounds.  If True and
  2818.      Wrap On Resize is enabled, the editor calls reformatAll() to reformat
  2819.      the text that it contains.  If this flag were not present, resizing an
  2820.      editor would cause a rewrap every single time you moved the window
  2821.      (each character you widened or shortened the view up, down, left, or
  2822.      right).  Not only would this cause it to eat virtual memory in vast
  2823.      quantities, it would be an extremely slow process.  By altering the
  2824.      changeBounds() code to set this flag and checking it in setState()
  2825.      only after the resize has completed, it only has to reformat and
  2826.      redraw once saving lots of virtual memory and lots of time in the
  2827.      process.  Note that if the editor contains a large amount of text,
  2828.      there may still be a delay between the end of the resize operation and
  2829.      when control is returned to you.
  2830.  
  2831.      -------------------------------------------------------
  2832.      long lastChg, prevLine, Bookmark1, Bookmark2, Bookmark3
  2833.      -------------------------------------------------------
  2834.          These data members represent the cursor line position history
  2835.      values.  lastChg records the number of the last changed line, prevLine
  2836.      records the line that the cursor was on prior to the last movement,
  2837.      and the bookmarks represent the lines tagged by the Bookmark command
  2838.      when set by the user.
  2839.  
  2840.      -------------------------------------------------------
  2841.      TVMEditor(const TRect &bounds, TScrollBar *aHScrollBar,
  2842.        TVMScrollBar *aVScrollBar, TVMIndicator *aIndicator,
  2843.        short bufSizeInK = 8)
  2844.      -------------------------------------------------------
  2845.          This is the constructor for the TVMEditor class.  As you can see,
  2846.      the first four parameters match up to the original TEditor class with
  2847.      the exceptions of the vertical scrollbar being a TVMScrollBar and the
  2848.      indicator being a TVMIndicator.  Following those is the additional
  2849.      parameter bufSizeInK that you may or may not want to specify.  This
  2850.      parameter specifies (in Kilobytes) how large the conventional memory
  2851.      buffer will be for the editor object.  This buffer is used to hold the
  2852.      recently used text and internal information necessary for editing the
  2853.      file.  By default, it is 8K.  Derived classes can adjust this upwards
  2854.      or downwards based on their needs.
  2855.          If you do not want one of the optional scrollbars or the
  2856.      indicator, pass a NULL in that parameter's position.  The default
  2857.      editor operating modes are set as follows:
  2858.  
  2859.          All local options       Initialized from the global options
  2860.                                  structure settings
  2861.          growMode                gfGrowHix | gfGrowHiY
  2862.          options                 ofSelectable is OR'ed with existing
  2863.                                  setting
  2864.  
  2865.  
  2866.  
  2867.  
  2868.  
  2869.  
  2870.  
  2871.          eventMask               evMouseDown | evKeyDown | evCommand |
  2872.                                  evBroadcast
  2873.          selecting               smNone
  2874.          keyState                0 (Normal single key command map)
  2875.          Bookmarks etc.          0 (Undefined)
  2876.          curPos etc.             Line 1, column 1
  2877.  
  2878.          If there is not enough memory to get underway, the editorDialog()
  2879.      function is called to notify the user and isValid is set to False.
  2880.      Otherwise, initialization will continue and isValid will be set to
  2881.      True.  In 32-bit protected mode, the constructor will also call
  2882.      AllocateDescriptor() to assign a descriptor to the lowMemDesc data
  2883.      member.
  2884.  
  2885.      -------------------------------------
  2886.      virtual Boolean valid(ushort command)
  2887.      -------------------------------------
  2888.          This function returns True if the virtual memory buffer and
  2889.      TVMEditor object initialized correctly.  If they did not, then it
  2890.      returns False.  The return value is controlled by the setting of the
  2891.      isValid data member.
  2892.  
  2893.      ---------------------------
  2894.      virtual void shutDown(void)
  2895.      ---------------------------
  2896.          This is used internally by TObject::destroy() to insure that the
  2897.      derived and related objects are all destroyed properly. 
  2898.      TVMEditor::shutDown will also disable commands like cmCopy, cmCut,
  2899.      cmFind, etc so that they appear dimmed and unselectable on the menus. 
  2900.      If another edit window is open on the desktop, that one will
  2901.      immediately enable them when it receives the focus.  Otherwise, they
  2902.      will stay disabled until another edit window is created.
  2903.  
  2904.      ----------------------------------------
  2905.      virtual void convertEvent(TEvent &event)
  2906.      ----------------------------------------
  2907.          This virtual function is used by handleEvent() to provide basic
  2908.      editing operations by converting various key events into command
  2909.      events.  To keep backward compatibility with the original TEditor,
  2910.      this function is still virtual.  It was done this way in the original
  2911.      as a means of extending or changing the default key bindings.  This
  2912.      required you to derive a new TEditor class and (just my opinion here
  2913.      <g>) was rather awkward to implement.  The underlying code for
  2914.      TVMEditor is similar to the original, but I have altered it in two
  2915.      major ways and also added a new function that does away with the need
  2916.      to derive a new editor class to extend the key code conversions.
  2917.          Due to the way some of Turbo Vision's kbXXXXX constants are
  2918.      defined and the way the matching code worked in the original TEditor,
  2919.      some keys such as BackSpace, Tab, and Enter would equate to an
  2920.      equivalent Ctrl key combination (Ctrl+H, Ctrl+I, and Ctrl+M).  This
  2921.      prevented those Ctrl keys for being used for other commands.  I
  2922.  
  2923.  
  2924.  
  2925.  
  2926.  
  2927.  
  2928.  
  2929.      altered this behaviour and explicitly scan for an exact keycode match
  2930.      before scanning for the other keycodes.  This will allow BackSpace,
  2931.      Tab, Enter, Ctrl+H, Ctrl+I, and Ctrl+M to function as individual keys
  2932.      unrelated to each other and the Ctrl keys are free to do something
  2933.      else if you want them to.  In the default maps, Ctrl+H, Ctrl+I, and
  2934.      Ctrl+M, are defined so that they still perform BackSpace, Tab, and
  2935.      Enter to emulate the original until you decide to change them.
  2936.          As mentioned before, extending or completely redefining the
  2937.      command key mappings is as simple as a single function call.  There is
  2938.      no longer a need to derive a new editor class in an attempt to solve
  2939.      the problem with more code.  See the changeKeyMap() function
  2940.      definition for information on how all this works.
  2941.  
  2942.      ---------------------------------------
  2943.      virtual void handleEvent(TEvent &event)
  2944.      ---------------------------------------
  2945.          This virtual function provides event handling for the TVMEditor
  2946.      object.  By default, this function calls TView::handleEvent() and then
  2947.      tries to convert all unhandled keyboard events to command events by
  2948.      calling convertEvent().
  2949.          You can override this function to provide new commands and other
  2950.      event handling features to the TVMEditor classes.  I have packed as
  2951.      many basic editing features as I could into the general TVMEditor and
  2952.      its derived classes.  These new features were ones that I found
  2953.      lacking or missing in the original.  The basic classes should stand up
  2954.      quite well on their own except for specialized situations in which
  2955.      there is no other alternative but to derive a new editor class.
  2956.  
  2957.      ----------------------------------------
  2958.      virtual TPalette &getPalette(void) const
  2959.      ----------------------------------------
  2960.          This returns the default TVMEditor palette.  The palette has been
  2961.      extended by one entry to include a highlighting color used whenever a
  2962.      cmSetLine command is received.  The extra color is defined and
  2963.      implemented via the TVCOLR.H file and alternate TView::mapColor()
  2964.      routine.  You must also have defined an appropriate
  2965.      TApplication::getPalette() member function to contain the extra colors
  2966.      used by the editor classes.
  2967.  
  2968.      ----------------------------------------------------
  2969.      virtual void setState(ushort aState, Boolean enable)
  2970.      ----------------------------------------------------
  2971.          This overrides TView::setState() in order to hide and display the
  2972.      scrollbars as well as perform some other behind the scenes operations
  2973.      whenever an editor object gains or loses the focus.
  2974.          If you wish to alter the commands that are enabled or disabled at
  2975.      a given point in time, override updateCommands() instead.  That
  2976.      function gets called whenever the command states should be updated.
  2977.  
  2978.  
  2979.  
  2980.  
  2981.  
  2982.  
  2983.  
  2984.      ---------------------------------
  2985.      virtual void updateCommands(void)
  2986.      ---------------------------------
  2987.          This virtual function is called whenever the command states should
  2988.      be updated.  It is used to enable and disable commands such as cmCut,
  2989.      cmCopy, cmUndo, cmRedo, cmReplace, etc.  Several commands, such as
  2990.      those just listed are only available under certain conditions such as
  2991.      having a marked text block, having undo/redo enabled, being in an
  2992.      editor that isn't read-only, etc.  Others, such as cmFind,
  2993.      cmLocalEditorOpt, cmGotoLine, etc are enabled all the time because
  2994.      they do not depend on other options for their use.
  2995.  
  2996.      ----------------------------------------------
  2997.      virtual void changeBounds(const TRect &bounds)
  2998.      ----------------------------------------------
  2999.          This virtual function changes the view's bounds, adjusts the delta
  3000.      value, and redraws the display when necessary to keep the editor view
  3001.      within its parent view's boundaries.  It also sets the hasChangedSize
  3002.      flag for editors that use the efWrapOnResize option.  The actual
  3003.      reformat call occurs in setState() when sfDragging is finally disabled
  3004.      at the end of the resize operation.
  3005.  
  3006.      -----------------------
  3007.      virtual void draw(void)
  3008.      -----------------------
  3009.          This overrides TView::draw() to draw the editor display.  It
  3010.      places a call to the drawLines() function which does all the work.  If
  3011.      you want an editor class to handle a different drawing method,
  3012.      override the drawLines() function instead of draw().
  3013.  
  3014.      ----------------------------------------------------------
  3015.      virtual void drawLines(short y, short count, long lineNbr)
  3016.      ----------------------------------------------------------
  3017.          This function is used to draw 'count' lines starting at line
  3018.      number 'lineNbr' in the buffer.  The display is updated starting at
  3019.      line 'y' on the screen.  If the data members findLine or setLine are
  3020.      non-zero, the appropriate display line will be highlighted in a
  3021.      different color to draw attention to the specified line's text.  It
  3022.      also takes care of highlighting a selected block of text.  If a find
  3023.      item appears in the selected block, the color is inverted so that it
  3024.      stands out as it would in normal text.
  3025.           If you need to alter the way in which an editor object draws
  3026.      itself, this is the function to override.  The draw() function simply
  3027.      places a call to drawLines().  This function is also called to draw
  3028.      partial screen updates (i.e. one or a few lines only).  By overriding
  3029.      this function, you can be sure that you will have control of all
  3030.      screen updates.
  3031.  
  3032.  
  3033.  
  3034.  
  3035.  
  3036.  
  3037.  
  3038.      --------------------------------------
  3039.      virtual void setXIndex(short newPos)
  3040.      virtual void setScrIndex(short newPos)
  3041.      --------------------------------------
  3042.          The function setXIndex() will synchronize the physical display
  3043.      column (curPos.x) with the index into the edit line Text[]
  3044.      (curPosx_t).  The function setScrIndex() will do the opposite.  It
  3045.      synchronizes the index into the edit line Text[] with the physical
  3046.      display column.  They also insure that curPos.x is not in the middle
  3047.      of a hard tab's whitespace.  Due to hard tabs, curPos.x and curPosx_t
  3048.      may have different values.  These functions are used when moving
  3049.      around within a line and onto other lines.
  3050.           These functions have been made virtual to allow you to embed
  3051.      special codes in the text or to alter the cursor positioning in some
  3052.      custom fashion should you ever need that capability.
  3053.  
  3054.      ------------------------------------------------------
  3055.      virtual const char *getSwapFileName(void)
  3056.      virtual Boolean setSwapFileName(const char *aFileName)
  3057.      ------------------------------------------------------
  3058.          These two functions can be used to get and set the virtual memory
  3059.      buffer's swap filename.  getSwapFileName() simply returns a 'const
  3060.      char *' to the swap filename.  setSwapFileName() takes a 'const char
  3061.      *' to the new name and returns True if it was set.  If False is
  3062.      returned, it means that the buffer is swapping text to a disk file
  3063.      already and the name cannot be changed.  This can be prevented for
  3064.      TVMFileEditor() and TVMEditWindow() with the SuppressLoad constructor
  3065.      parameter.
  3066.  
  3067.      ----------------------------------
  3068.      virtual Boolean isWordChar(int ch)
  3069.      ----------------------------------
  3070.          This virtual function returns True if ch is in the set of defined
  3071.      word characters.  By default, a word character is any alphanumeric
  3072.      character (as returned by the isalnum() function) or the underscore
  3073.      character.
  3074.          This function was not virtual in the original TEditor but I made
  3075.      it this way for TVMEditor.  This makes it easy to derive a new
  3076.      TVMEditor with a custom word character set.  If you decided to derive
  3077.      a new editor used strictly for editing a special type of data file,
  3078.      you could override this function and define a word character set that
  3079.      was unique to that type of file.  For example, you might want to make
  3080.      it consider alphabetic characters only and ignore other characters
  3081.      when determining word boundaries.
  3082.  
  3083.      --------------------------------------------------
  3084.      virutal void doneBuffer(Boolean releaseMem = True)
  3085.      --------------------------------------------------
  3086.           This function simply deletes all text in the buffer and
  3087.      reinitializes the editor to its start-up state.  Note that unlike the
  3088.      original TEditor, this function is not used during shutdown.  It was
  3089.  
  3090.  
  3091.  
  3092.  
  3093.  
  3094.  
  3095.  
  3096.      simply added as a quick way to delete all text in the buffer and reset
  3097.      some of the internal variables.  The releaseMem parameter determines
  3098.      whether or not any allocated virtual memory is released back to the
  3099.      system.  If not specified or passed in as True, the function will
  3100.      deallocate any EMS/XMS in used and remove the swap file if one was
  3101.      created.  Passing in a False for this parameter will retain the
  3102.      virtual memory.  Under normall circumstances, the function should be
  3103.      allowed to release all memory so that it is freed for use by other
  3104.      editors.  If you wish to retain the purged information for undo/redo
  3105.      purposes, pass in False.
  3106.           TVMFileEditor overrides this function to give you the option of
  3107.      reloading the text.  See its description for further details.
  3108.  
  3109.      -------------------------------------------------
  3110.      inline void setOption(ushort efConst, Boolean On)
  3111.      -------------------------------------------------
  3112.          This inline function provides a simple means of altering the
  3113.      editor's local option settings.  Simply pass it one or more of the
  3114.      efXXXXX local option constants (ORed together if necessary) and True
  3115.      to enable them or False to disable them.
  3116.  
  3117.      ----------------------------
  3118.      inline Boolean canUndo(void)
  3119.      ----------------------------
  3120.          This inline function returns True if undo/redo is enabled for the
  3121.      editor or False if it is not.
  3122.  
  3123.      -----------------------------------------
  3124.      inline void cursorPos(short &x, long &y)
  3125.      inline void textLimits(short &x, long &y)
  3126.      -----------------------------------------
  3127.          Cursor position and limits shouldn't be modified directly so they
  3128.      are protected data members.  These two inline functions will let you
  3129.      know what they are currently set to.  The x parameters refer to the
  3130.      horizontal coordinates and the y parameters refer to the vertical
  3131.      coordinates.
  3132.  
  3133.      ---------------------------------
  3134.      inline const char *lineText(void)
  3135.      ---------------------------------
  3136.          It is more expedient in an iterative, line-by-line operation to
  3137.      call the virtual memory buffer text retrieval functions directly and
  3138.      work with the Text[] line buffer.  This returns a const char * to
  3139.      Text[] for those cases.  An example might be a compile operation.  By
  3140.      using the LRU text retrieval mechanisms of TVirtualMemory, the file
  3141.      can be scanned from one end to the other fairly quickly.  There are
  3142.      other non-LRU functions in the TVirtualMemory class, but because they
  3143.      return an address directly into a virtual memory page, they bypass the
  3144.      LRU mechanisms and generally cause thrashing under such conditions
  3145.      which slows performance.
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.      ----------------------------------
  3154.      inline Boolean cursorVisible(void)
  3155.      ----------------------------------
  3156.          This inline function returns True if the cursor is visible on the
  3157.      screen or False if it is not.  Unlike the original TEditor class, this
  3158.      version will check both the horizontal and vertical cursor
  3159.      coordinates.
  3160.  
  3161.      ------------------------
  3162.      inline void lock(void)
  3163.      inline void unlock(void)
  3164.      ------------------------
  3165.          The function lock() increments the lockCount variable and prevents
  3166.      screen updates from occurring.  Its counterpart, unlock(), will
  3167.      decrement the lockCount variable and, if it is zero, perform a screen
  3168.      update.
  3169.  
  3170.      --------------------------------
  3171.      inline Boolean isClipboard(void)
  3172.      --------------------------------
  3173.          This inline function returns True if the associated editor is the
  3174.      clipboard.  If the editor is not the clipboard, it returns False.  To
  3175.      be the clipboard, the address of the TVMEditor object must be assigned
  3176.      to TVMEditor::clipboard.
  3177.  
  3178.      ----------------------------------------------
  3179.      inline void setDefaultMessage(const char *msg)
  3180.      ----------------------------------------------
  3181.           This inline function simply allows you to set the default message
  3182.      for its associated indicator when you are not doing it from inside a
  3183.      TVMEditor derived class.
  3184.  
  3185.      --------------------------------------------------------------
  3186.      static Boolean changeKeyMap(short index, const ushort *newMap)
  3187.      --------------------------------------------------------------
  3188.          This is a static function that allows you to change key maps.  The
  3189.      key maps are shared by all editors.  Therefore, if you change a key
  3190.      map it will affect all open editors.  A key map is simply a list of
  3191.      keys and commands.  The format of the key maps has been changed and is
  3192.      not the same as it was for TEditor.  They now all have the following
  3193.      format:
  3194.  
  3195.          <key1>, <command1>,        <key>     = Key to press
  3196.          <key2>, <command2>,        <command> = cmXXXX command value
  3197.          .                                      or 0xFFnn for a secondary
  3198.          .                                      array.
  3199.          .
  3200.          <keyN>, <commandN>,
  3201.          0                          Arrays MUST be terminated by a zero
  3202.                                     for the key entry!
  3203.  
  3204.  
  3205.  
  3206.  
  3207.  
  3208.  
  3209.  
  3210.      Examples:
  3211.  
  3212.          // Default single key command mappings.
  3213.          const ushort singleKeys[] =
  3214.          {
  3215.              kbCtrlK,     0xFF01,         // Block lead in key
  3216.              kbCtrlQ,     0xFF02,         // Quick lead in key
  3217.              kbCtrlJ,     0xFF03,         // Jump/Secondary clipboard lead
  3218.                                           // in key
  3219.              kbCtrlO,     0xFF04,         // Option/Other lead in key
  3220.              kbLeft,      cmCharLeft,     // Movement
  3221.              kbCtrlS,     cmCharLeft,
  3222.              kbRight,     cmCharRight,
  3223.              kbCtrlD,     cmCharRight,
  3224.                  .
  3225.                  .
  3226.                  .
  3227.                  .
  3228.              kbCtrlB,     cmWrapPara,
  3229.              kbAltMinus,  cmUndo,
  3230.              kbAltEqual,  cmRedo,
  3231.              0
  3232.          };
  3233.  
  3234.          // Default: Ctrl K, 0xFF01
  3235.          const ushort blockKeys[] =
  3236.          {
  3237.              'B', cmStartSelect,
  3238.              'K', cmEndSelect,
  3239.              'H', cmHideSelect,
  3240.              'C', cmCopyBlock,
  3241.              'V', cmMoveBlock,
  3242.              'Y', cmClear,
  3243.              'I', cmIndentBlock,
  3244.              'U', cmUnindentBlock,
  3245.              'R', cmReadFile,
  3246.              'W', cmWriteBlock,
  3247.              'P', cmPrintBlock,
  3248.              '1', cmSetBookmark1,
  3249.              '2', cmSetBookmark2,
  3250.              '3', cmSetBookmark3,
  3251.              0
  3252.          };
  3253.  
  3254.          etc.
  3255.  
  3256.  
  3257.  
  3258.  
  3259.  
  3260.  
  3261.  
  3262.          The addresses of these arrays are then stored in another array
  3263.      like this:
  3264.  
  3265.        const ushort *VMkeyMap[9] = { singleKeys, blockKeys, quickKeys,
  3266.                                      jumpKeys,   optKeys,   NULL,
  3267.                                      NULL,       NULL,      NULL };
  3268.  
  3269.          This is the keyboard command map array.  The zeroeth element's
  3270.      array is always scanned first.  To access the other elements' arrays,
  3271.      a lead-in keypress is needed within that array.  This lead-in key
  3272.      causes a flag to be set (keyState) which sends the editor to look in a
  3273.      different array for the next keypress after the lead-in.
  3274.          The lead-in keys are defined in the singleKeys array by having the
  3275.      command value 0xFFnn where nn is the element number of VMkeyMap[]
  3276.      which will be accessed for the next keypress.  For example, Ctrl+K, H
  3277.      has "kbCtrlK, 0xFF01" defined for Ctrl K in singleKeys and "'H',
  3278.      cmHideSelect" defined in the blockKeys array for the 'H' keypress. 
  3279.      Ctrl+K signals the editor to look in the blockKeys array on the next
  3280.      keypress and, if H is pressed, it will execute the cmHideSelect
  3281.      command.
  3282.          When the second key of a two-key command is pressed, you should
  3283.      let go of the Ctrl key unless it is specifically needed.  Some
  3284.      sequences such as Ctrl+K, 1 will not work if Ctrl is held down while
  3285.      pressing the "1".  That is because Ctrl+1 does not have a scan code on
  3286.      the normal PC keyboard and therefore won't generate a keyboard event.
  3287.          These maps can be replaced by calling the changeKeyMap() function
  3288.      so as to define your own preferences.  There is extra space in the
  3289.      VMkeyMap array to hold up to four additional unique lead-in keys'
  3290.      maps.  This should save you from having to override convertEvent()
  3291.      every time a new keyboard layout is needed or a new lead-in command
  3292.      key is needed.  Note that the maps pointed to can be up to 64K in size
  3293.      so there is no real limit on how many commands can be placed in a
  3294.      single array.
  3295.          To use this function, simply pass in the index number of the array
  3296.      you wish to replace (0-8) and a 'const ushort *' to the new command
  3297.      key map.  changeKeyMap() will return True if the map was replaced or
  3298.      False if it wasn't.  Currently, it will only return False if you
  3299.      specify an invalid index (a number other than 0 to 8).  Note that if
  3300.      you wish to alter the first key of any of the existing two-key
  3301.      commands (Ctrl+K, Ctrl+Q, Ctrl+J, or Ctrl+O) or add a new two-key
  3302.      starter, you will also need to replace the singleKeys array.  Also be
  3303.      aware of the fact that it is up to you to insure that there are no
  3304.      kbXXXX values attached to more than one command in the same array.  If
  3305.      you do have a key attached to more than one command in the same array,
  3306.      the editor will only see the first command it encounters.
  3307.  
  3308.  
  3309.  
  3310.  
  3311.  
  3312.  
  3313.  
  3314.      Examples:
  3315.  
  3316.          const ushort MyBlockKeys[] =
  3317.          {
  3318.              .
  3319.              .
  3320.              .
  3321.          };
  3322.  
  3323.          // Change second key presses for the Ctrl+K block keys.
  3324.          TVMEditor::changeKeyMap(1, &MyBlockKeys[0]);
  3325.  
  3326.          const ushort MySingleKeys[] =
  3327.          {
  3328.              kbCtrlX,     0xFF01,         // Block lead in key changed
  3329.                                           // to Ctrl+X
  3330.              kbCtrlQ,     0xFF02,
  3331.              kbCtrlJ,     0xFF03,
  3332.              kbCtrlO,     0xFF04,
  3333.              kbAltY,      0xFF05,         // A new lead in key.
  3334.              kbLeft,      cmCharLeft,
  3335.              kbCtrlS,     cmCharLeft,
  3336.              kbRight,     cmCharRight,
  3337.              kbCtrlD,     cmCharRight,
  3338.                  .
  3339.                  .
  3340.                  .
  3341.                  .
  3342.              kbCtrlB,     cmWrapPara,
  3343.              kbAltMinus,  cmUndo,
  3344.              kbAltEqual,  cmRedo,
  3345.              0
  3346.          };
  3347.  
  3348.          const ushort MyAltYKeys[] =
  3349.          {
  3350.              .
  3351.              .
  3352.              .
  3353.          };
  3354.  
  3355.          // Changes Ctrl+K to Ctrl+X and adds Alt+Y
  3356.          TVMEditor::changeKeyMap(0, &MySingleKeys[0]);
  3357.  
  3358.          // Defines the second key press actions for Alt+Y
  3359.          TVMEditor::changeKeyMap(5, &MyAltYKeys[0]);
  3360.  
  3361.          To restore a key map to its default settings, simply specify the
  3362.      index number and NULL for the newMap pointer.  For index values
  3363.      greater than 4, the VMKeyMap[] element will be set to NULL and for
  3364.      index values of 4 or less, the VMKeyMap[] element will be reset to
  3365.  
  3366.  
  3367.  
  3368.  
  3369.  
  3370.  
  3371.  
  3372.      point to the original key map.
  3373.  
  3374.          // Return the key maps to their original states.
  3375.          TVMEditor::changeKeyMap(0, NULL);       // Point to default
  3376.                                                  // singleKeys again
  3377.          TVMEditor::changeKeyMap(5, NULL);       // Set to NULL again
  3378.  
  3379.      ------------------------------------------------
  3380.      void setCmdState(ushort command, Boolean enable)
  3381.      ------------------------------------------------
  3382.          This function enables or disables the specified command depending
  3383.      on whether 'enable' is True of False and whether or not the editor is
  3384.      active.  If the editor is not the focused view, the command is always
  3385.      disabled.
  3386.  
  3387.      ------------------------------------------------------------
  3388.      void setSelect(short fromX, long fromY, short toX, long toY,
  3389.           Boolean goTop = False)
  3390.      ------------------------------------------------------------
  3391.           The setSelect() function simply marks the range of text starting
  3392.      at 'fromX, fromY' and going to 'toX, toY' as the currently selected
  3393.      block.  If goTop is False, the cursor is placed at the end of the
  3394.      block.  If True, the cursor is placed at the top of the block.
  3395.  
  3396.      --------------------------------------------------------------------
  3397.      void TVMEditor::putCursorAt(short x, long y, Boolean center = False)
  3398.      --------------------------------------------------------------------
  3399.           The putCursorAt() function will position the cursor at the given
  3400.      coordinates.  This should be used in place of the setCursor() function
  3401.      inherited from TView which only moves the hardware cursor around the
  3402.      screen.  If 'center' is True, the cursor will be placed as close as
  3403.      possible to the center of the screen.  If False, no such attempt is
  3404.      made.
  3405.  
  3406.      ------------------------------
  3407.      void scrollTo(short x, long y)
  3408.      ------------------------------
  3409.          This function moves column X and line Y to the upper left corner
  3410.      of the editor's view.
  3411.  
  3412.      --------------------------------
  3413.      void trackCursor(Boolean center)
  3414.      --------------------------------
  3415.          This function will force the display into a position such that the
  3416.      cursor is visible.  If 'center' is True, the cursor will be placed as
  3417.      close to the center of the view as possible in both the horizontal and
  3418.      vertical directions.
  3419.  
  3420.  
  3421.  
  3422.  
  3423.  
  3424.  
  3425.  
  3426.      -------------------------
  3427.      void update(uchar aFlags)
  3428.      -------------------------
  3429.          This function is used to alter the updateFlags data member.  If
  3430.      lockCount is zero, it will also refresh the display by calling
  3431.      doUpdate().
  3432.  
  3433.      -------------------
  3434.      void doUpdate(void)
  3435.      -------------------
  3436.          This function will update the view's display based on the setting
  3437.      of the updateFlags data member.  If it is zero, nothing happens. 
  3438.      Otherwise, it will update the command set, draw the scrollbars and
  3439.      indicator, and optionally draw a part or all of the editor's view.
  3440.  
  3441.      ----------------------
  3442.      long getTextSize(void)
  3443.      ----------------------
  3444.          This function returns the total number of characters in the editor
  3445.      buffer.  A function by the same name also exists in the TVirtualMemory
  3446.      class.  These can be used to find out how much memory needs to be
  3447.      allocated for text retrieval (i.e.  for TVMMemo).  The difference
  3448.      between the TVMEditor and TVirtualMemory copy is that
  3449.      TVirtualMemory::getTextSize() returns the total size calculated using
  3450.      NULL terminated lines where as TVMEditor::getTextSize() will account
  3451.      for the extra carriage return on each line when the efUseLFOnly option
  3452.      bit is not set.
  3453.  
  3454.      --------------------
  3455.      short pad(short pos)
  3456.      --------------------
  3457.          This function will add trailing spaces to Text[] if needed.  When
  3458.      the cursor moves to a new line, it is padded with spaces so that the
  3459.      cursor maintains its horizontal position.  This provides the editor
  3460.      with a free-roaming cursor.  The trailing spaces are removed before
  3461.      the line is stored if the efTrailingSpaces option is not set.  If
  3462.      efTrailingSpaces is set, then the spaces are not added because in that
  3463.      case, trailing spaces in the input file or those added in editing are
  3464.      permanently retained.  In this mode the cursor can't be moved beyond
  3465.      the rightmost character of a line with the right arrow key.  This
  3466.      function will return the line length with padding (if any).
  3467.  
  3468.      ------------------------------------
  3469.      short trim(char *sline, char *chptr)
  3470.      ------------------------------------
  3471.          This function will strip trailing whitespace (in this case spaces
  3472.      and tabs only) from the end of the line.  The length of the string
  3473.      after stripping is returned.  If *ch is not NULL, it is filled in with
  3474.      the character that the NULL terminator replaced.  This is done so that
  3475.      the whitespace can be added back in by the caller if necessary with a
  3476.      simple sline[pos] = ch.  It is used this way internally by some of the
  3477.  
  3478.  
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.      commands.
  3485.  
  3486.      ------------------------------------------------------
  3487.      void moveChar(short move, Boolean isSelecting = False)
  3488.      ------------------------------------------------------
  3489.          This function will move the cursor by 'move' columns to the right
  3490.      or left.  Trailing spaces are added to the right as needed (and when
  3491.      allowed) to provide a free-roaming cursor.  The isSelecting parameter
  3492.      determines whether or not the block marking mode will start, continue,
  3493.      or finish.
  3494.  
  3495.      ------------------------------------------------------
  3496.      void moveWord(short move, Boolean isSelecting = False)
  3497.      ------------------------------------------------------
  3498.          This function will move the cursor one word to the left when
  3499.      'move' is equal to -1 or one word to the right when 'move' is equal to
  3500.      1.  If the cursor goes past the beginning or the end of the line, it
  3501.      will automatically jump to the word on the previous or next line.  The
  3502.      isSelecting parameter determines whether or not the block marking mode
  3503.      will start, continue, or finish.
  3504.  
  3505.      -----------------------------------------------------
  3506.      void moveLine(long move, Boolean isSelecting = False)
  3507.      -----------------------------------------------------
  3508.          This function will move the cursor up or down by 'move' lines.  If
  3509.      possible, the cursor will maintain its physical screen position
  3510.      relative to the top and bottom of the window when a scroll occurs. 
  3511.      The isSelecting parameter determines whether or not the block marking
  3512.      mode will start, continue, or finish.
  3513.  
  3514.      --------------------------------------------
  3515.      Boolean insertChar(char ch, Boolean insChar)
  3516.      --------------------------------------------
  3517.          This function will take the character passed to it and either
  3518.      insert it at the current cursor location or overwrite the character at
  3519.      the current cursor location.  The cursor position is moved one
  3520.      character to the right.
  3521.  
  3522.      ------------------------------------
  3523.      void insertTab(Boolean centerCursor)
  3524.      ------------------------------------
  3525.          This function will insert the appropriate tab representation into
  3526.      the editor line when insert mode is on.  When insert mode is off, it
  3527.      simply moves the cursor by the appropriate amount of space.  It is
  3528.      passed the value True or False in centerCursor.  This value is then
  3529.      passed to trackCursor() just before returning to insure that the
  3530.      cursor is visible on the screen.
  3531.  
  3532.  
  3533.  
  3534.  
  3535.  
  3536.  
  3537.  
  3538.      -------------------
  3539.      void insertCR(void)
  3540.      -------------------
  3541.          This function handles the insertion of a carriage return.  When
  3542.      the cursor is in the first column of the line, a blank line is
  3543.      inserted above the current line.  If the cursor is somewhere else, the
  3544.      current line is split into two separate parts at the current cursor
  3545.      location.  The cursor always moves down one line.  If a line is split,
  3546.      the second half will be indented accordingly if auto indent mode is
  3547.      enabled.
  3548.  
  3549.      ---------------------------------
  3550.      void deleteChar(Boolean DelRight)
  3551.      ---------------------------------
  3552.          This function will delete a character for Backspace or DEL.  If
  3553.      DelRight is True, the character at the current cursor location is
  3554.      deleted and the remaining text is pulled backwards to fill the gap. 
  3555.      If DelRight is False, the character immediately to the left of the
  3556.      cursor is deleted and the remaining text is pulled backwards to fill
  3557.      the gap.
  3558.          When the cursor is in the first column of the line and Backspace
  3559.      is pressed, the line will be joined to the previous one.  If the
  3560.      cursor is in the last column and DEL is pressed, the line following
  3561.      the current one is appended to it.
  3562.  
  3563.      ------------------------------------
  3564.      void deleteTab(Boolean centerCursor)
  3565.      ------------------------------------
  3566.          This function is simply the reverse of insertTab().  When insert
  3567.      mode is on, it deletes the appropriate tab width.  When insert mode is
  3568.      off, it simply moves the cursor to the left by the appropriate tab
  3569.      width.  The trackCursor() function is called afterwards to insure that
  3570.      the cursor is still visible.
  3571.  
  3572.      ---------------------
  3573.      void deleteLine(void)
  3574.      ---------------------
  3575.          This function deletes the current cursor line as referenced by the
  3576.      value in curPos.y.
  3577.  
  3578.      --------------------------
  3579.      Boolean hasSelection(void)
  3580.      --------------------------
  3581.          This function returns True if there is a currently marked block of
  3582.      text.  If there is no currently marked text block, it returns False. 
  3583.      A block is considered marked when the start and end lines are non-zero
  3584.      and, if the start and end lines are the same, the start and end
  3585.      columns are not equal.
  3586.  
  3587.  
  3588.  
  3589.  
  3590.  
  3591.  
  3592.  
  3593.      ----------------------------------
  3594.      void adjustBlock(short difference)
  3595.      ----------------------------------
  3596.           This function adjusts the block start and end points whenever one
  3597.      or more characters are inserted or deleted from a line.  This was
  3598.      added so that the persistent block would maintain a reasonable start
  3599.      and end point as text is edited instead of remaining fixed at a point
  3600.      that may no longer be valid.
  3601.  
  3602.      ----------------------
  3603.      void deleteBlock(void)
  3604.      void moveBlock(void)
  3605.      void copyBlock(void)
  3606.      ----------------------
  3607.          These three functions control the non-clipboard delete, move, and
  3608.      copy operations.  The deleteBlock() function simply erases the
  3609.      currently selected block of text.  The moveBlock() function will
  3610.      attempt to move the currently selected block of text to the current
  3611.      cursor location.  If the cursor is anywhere inside the selected block,
  3612.      the move operation will be ignored.  This is because moving the text
  3613.      to a point anywhere within the selected text will not make it go
  3614.      anywhere.  The copyBlock() function will copy the currently selected
  3615.      block of text to the current cursor location.
  3616.  
  3617.      ------------------------------------
  3618.      Boolean insertFrom(TVMEditor *insEd)
  3619.      Boolean clipCopy(void)
  3620.      Boolean clipCut(void)
  3621.      Boolean clipPaste(void)
  3622.      ------------------------------------
  3623.          These four functions constitute the clipboard control functions
  3624.      for the editor.  clipCopy() copies the selected text to the clipboard,
  3625.      clipCut() will copy it to the clipboard and delete it from the current
  3626.      editor, and clipPaste() will paste the clipboard's currently selected
  3627.      block of text into the current editor.  All three functions make use
  3628.      of the insertFrom() function by calling clipboard->insertFrom(this)
  3629.      for cut or copy and insertFrom(clipboard) for paste.  insertFrom()
  3630.      simply takes the selected block of text from the insEd editor and
  3631.      starts inserting it into the editor that called it at the current
  3632.      cursor location.  If the insertion was successful, it returns True. 
  3633.      It will return False under any of the following conditions: insEd is
  3634.      NULL, the editor is trying to insert text into itself, the editor is
  3635.      trying to insert text from a linked editor into the same shared
  3636.      virtual memory buffer (same as inserting into itself), there is no
  3637.      selected text in insEd, or the receiving editor is Read Only.
  3638.  
  3639.      ----------------------------------------
  3640.      Boolean insertAtCursor(const char *text)
  3641.      ----------------------------------------
  3642.           This function can be used to insert a string of text at the
  3643.      current cursor location.  It works by calling the insertChar()
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.      function for each character in the string.  Note that the tab and new
  3652.      line characters are processed properly and each will insert the proper
  3653.      amount of spaces or new lines in the text.  Word wrapping will also
  3654.      occur properly as the text is inserted if the word wrap option bits
  3655.      are set.  If the insertion was successful, True is returned.  If there
  3656.      was a problem inserting the text, False is returned.
  3657.  
  3658.      -------------------------------------------------------------------
  3659.      ushort  getSelectedTextSize(char LineTerm)
  3660.      ushort  getSelectedText(char *buffer, ushort length, char LineTerm,
  3661.        Boolean *NotDone)
  3662.      -------------------------------------------------------------------
  3663.          getSelectedTextSize() returns the size of the selected text block.
  3664.      This function repeatedly calls getSelectedText() to determine the
  3665.      actual size of the selected text. This is useful for determining
  3666.      storage requirements prior to actually doing the retrieval.  If the
  3667.      selected text exceeds 60K, the function return the maximum value 60K
  3668.      (61440 bytes).  All you need to do in order to receive a valid count
  3669.      is pass in the line termination character that will be used with the
  3670.      actual getSelectedText() function call (NULL, line feed, or carriage
  3671.      return).
  3672.          getSelectedText() is similar in nature to TVMMemo::RetrieveMemo()
  3673.      but it is in the base TVMEditor class and is used to retrieve the
  3674.      block of selected text to a user-specified buffer.  Pass it a pointer
  3675.      to the buffer, the maximum length (up to 61440 bytes) and the line
  3676.      termination method to use ('\r' = CR/LF, '\n' = LF only, '\x0' =
  3677.      NULL).  The function returns the actual number of bytes stored to the
  3678.      buffer including line terminators.  If 'Boolean *NotDone' is not NULL,
  3679.      the function will return True in that location if all the selected
  3680.      text was returned or False if not.  If False, the function will adjust
  3681.      the selected block so that a subsequent call will return the next
  3682.      block.  This can be repeated until 'NotDone' is returned as True.  If
  3683.      '*buffer' is NULL, the function returns the byte count for the text
  3684.      that would fit in the given length but does not copy any data.
  3685.  
  3686.      ----------------------
  3687.      Boolean wrapLine(void)
  3688.      ----------------------
  3689.          This function controls word wrapping of the current line (as
  3690.      referenced by the curPos.y value).  If word wrapping is enabled in the
  3691.      local options, this is called automatically whenever a word wrap is
  3692.      required.  It is also called by wrapPara() when reformatting blocks of
  3693.      text.
  3694.  
  3695.      Rules for word wrapping:
  3696.          1. Called by the insertChar() function if cursor is past the
  3697.             specified right margin and the inserted character is not a
  3698.             space or tab.
  3699.  
  3700.          2. Called by wrapPara() when reformatting paragraphs.
  3701.  
  3702.  
  3703.  
  3704.  
  3705.  
  3706.  
  3707.  
  3708.          3. Note that if characters are inserted such that text after the
  3709.             cursor exceeds the right margin before the cursor does, the
  3710.             line will still not be wrapped until the cursor passes the
  3711.             right margin or until the line is reformatted as part of a
  3712.             Paragraph Reformat command.
  3713.  
  3714.          4. If the first word starts past the right margin, then no word
  3715.             wrapping will be performed for that line.
  3716.  
  3717.          5. The first word, space, or tab after the right margin is the
  3718.             wrapping point.
  3719.  
  3720.          6. If a word spans the margin, the wrapping point is the first
  3721.             space or tab prior to that word.  If that word is the first
  3722.             word of the line, then no wrapping will occur.
  3723.  
  3724.          7. Text after the wrap point is moved to a new line with the
  3725.             cursor.  Leading spaces are stripped and the line is indented
  3726.             if required.
  3727.  
  3728.      -------------------
  3729.      void wrapPara(void)
  3730.      -------------------
  3731.          This function controls the reformatting of text blocks (referred
  3732.      to as paragraphs for lack of a better term).  This is a text editor
  3733.      and not a word processor, so soft returns are not used to mark
  3734.      wrapping points and this function is only called when the user
  3735.      requests it via the keyboard command (^B by default) or if auto
  3736.      wrapping is enabled (efAutoWrap is set).  It is possible to use
  3737.      EOLMaker to set points in the text where reformatting should stop,
  3738.      thus providing a form of "hard return".  However, when auto wrapping
  3739.      is enabled, wrapPara() reacts differently when called to perfom an
  3740.      automatic wrap and will stop reformatting when it detects any change
  3741.      in indentation.  This prevents the reformatting of too much text that
  3742.      can occur when the manaul (^B) paragraph reformat command is issued. 
  3743.      See the section entitled Paragraph Reformatting for more details on
  3744.      how this works.
  3745.  
  3746.      Rules for reformatting:
  3747.  
  3748.          1. Reformatting starts at the current cursor line.
  3749.  
  3750.          2. Reformatting continues until a blank line, the end of the file,
  3751.             the end of a selected block, or a line with an indent or
  3752.             outdent equal to the starting line is encountered.
  3753.  
  3754.          3. If the indentation of the first and second lines is the same,
  3755.             reformatting will continue until a blank line, the end of the
  3756.             file, or the end of a selected block is encountered (whichever
  3757.             occurs first).
  3758.  
  3759.  
  3760.  
  3761.  
  3762.  
  3763.  
  3764.  
  3765.          4. The indentation for lines after the first is determined by
  3766.             getting the indentation for the second line.  All lines after
  3767.             the first will be indented or outdented by that same amount.
  3768.  
  3769.          5. Reformatting is done by repeatedly word wrapping long lines and
  3770.             appending words to short ones from subsequent lines until an
  3771.             exit condition is met.  Lines that have their text completely
  3772.             assimilated into another line are deleted.
  3773.  
  3774.          6. Word wrapping will not occur for lines that start past the
  3775.             right margin or for lines where there is no place to legally
  3776.             break a line (i.e. no spaces or tabs between words).
  3777.             Such lines may still be indented.
  3778.  
  3779.          7. Regardless of where a block starts or ends, the paragraph
  3780.             reformat command will always work with whole lines only.
  3781.  
  3782.      ----------------------
  3783.      void reformatAll(void)
  3784.      ----------------------
  3785.           This function can be called to unconditionally reformat the
  3786.      entire document.  It is also used to support the efWrapOnResize option
  3787.      bit.  Note that depending upon the size of the document, this function
  3788.      may take a little while to perform its task.
  3789.  
  3790.      ---------------------
  3791.      void doAutoWrap(void)
  3792.      ---------------------
  3793.           This function exists to perform the automatic text wrapping.  It
  3794.      is called after any cmDelXXXXX command and is also called from the
  3795.      insertChar() function.  If required, the text from the line that the
  3796.      cursor is on and as many subsequent lines as needed are reformatted. 
  3797.      See the wrapPara() function for the reformatting rules.
  3798.  
  3799.      -----------------------------------------------
  3800.      void alterText(long from, long to, ushort cmnd)
  3801.      -----------------------------------------------
  3802.           This single function takes care of the following editor commands:
  3803.  
  3804.      cmForceUpper - Force text in the current line or marked block to
  3805.                     upper case.
  3806.  
  3807.      cmForceLower - Force text in the current line or marked block to
  3808.                     lower case.
  3809.  
  3810.      cmToggleCase - Switch the case of the text in the current line or
  3811.                     marked block from upper to lower case or vice versa.
  3812.  
  3813.      cmIndentBlock - Indent the current line or all lines in the marked
  3814.                      block by the size specified in the local options'
  3815.                      IndentSize data member.
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.      cmUnindentBlock - Unindent the current line or all lines in the marked
  3824.                        block by the size specified in the local options'
  3825.                        IndentSize data member.
  3826.  
  3827.      cmCenterLines - Center the current line or all lines in the marked
  3828.                      block between column 1 and the current right margin
  3829.                      as specified in the local options.
  3830.  
  3831.      cmAlignText - Align the current line or all lines in the marked block
  3832.                    with the first non-blank line above the starting point.
  3833.  
  3834.          For cmIndentBlock and cmUnindentBlock, it will either indent or
  3835.      outdent the selected lines by the amount specified by the IndentSize
  3836.      member of the local options structure.  If cmUnindentBlock encounters
  3837.      a hard tab, it will break it into spaces and only remove the necessary
  3838.      number of positions from it.  All characters (whitespace or text) are
  3839.      included when unindenting, so it is possible to truncate the text at
  3840.      the beginning of the line.
  3841.          cmCenterLines will center the text on the selected lines between
  3842.      column 1 and the current RightMargin value in the local options
  3843.      structure.  Trailing spaces will be truncated regardless of the Retain
  3844.      Trailing Spaces setting so that the text can be properly centered.
  3845.          cmAlignText will align the selected lines with the first non-blank
  3846.      line above the starting point.  If a non-blank line isn't found, then
  3847.      no alignment will be performed.  Alignment consists of adjusting the
  3848.      amount of whitespace at the start of the line to match the lines
  3849.      above.
  3850.           Note that regardless of where a block starts or ends, the indent,
  3851.      centering, and alignment commands will always work with whole lines
  3852.      only.  The case toggling commands can work with any type of marked
  3853.      block including ones that start and/or end at points other than the
  3854.      beginning or end of lines.
  3855.  
  3856.      User Defined Text Alterations
  3857.      -----------------------------
  3858.           By passing the alterText() function a command value other than
  3859.      those listed above, you can perform your own custom edits.  If the
  3860.      'cmnd' value is not recognized, a call is placed to the editorDialog()
  3861.      function with a value of edAlterText followed by the command, a
  3862.      pointer to the line's text, and starting and ending column values
  3863.      which denote what part of the line should be affected by the command. 
  3864.      This gives you a "hook" that can be used to alter text in different
  3865.      ways that may not be a standard part of the editor.  If the
  3866.      editorDialog() function returns cmCancel, nothing is changed.  If it
  3867.      returns cmOK, then the altered text is stored.
  3868.  
  3869.  
  3870.  
  3871.  
  3872.  
  3873.  
  3874.  
  3875.      ----------------------------------
  3876.      void SearchDialog(Boolean Replace)
  3877.      void doSearchReplace(void)
  3878.      Boolean search(void)
  3879.      ----------------------------------
  3880.          These three functions control the search and replace features for
  3881.      the editors.  SearchDialog() will create either a Find Dialog if the
  3882.      Replace parameter is False or a Replace Dialog if the Replace
  3883.      parameter is True.  The user is then prompted for the necessary
  3884.      information and, if the user chooses to do so, the operation is then
  3885.      performed.
  3886.          The doSearchReplace() function controls the top level operation of
  3887.      a search or replace,  it calls search() to look for the specified text
  3888.      and then prompts the user if necessary and takes care of replacements.
  3889.          The search() function controls the low level aspects of the
  3890.      search.  It determines where to start and stop, when a match has been
  3891.      found, and movement through the buffer while searching.
  3892.  
  3893.      -----------------------
  3894.      void FindMatching(void)
  3895.      -----------------------
  3896.          This function controls the Find Matching feature of the editor. 
  3897.      It simply takes the character under the cursor and, if it is a
  3898.      matchable character, will try to find its companion.  If its companion
  3899.      cannot be found, the cursor will stay where it is at and nothing will
  3900.      happen.  If a match is found (whether it is correct or not), the
  3901.      cursor will jump to the new location.  If it is not where you expected
  3902.      it, you have a mismatch somewhere between the starting and ending
  3903.      location.  See the section entitled Enter Matching under the Local
  3904.      Editor Options descriptions for more information.
  3905.  
  3906.  
  3907.  
  3908.  
  3909.  
  3910.  
  3911.  
  3912.                              The TVMFileEditor Class
  3913.                              -----------------------
  3914.  
  3915.      Features List
  3916.      =============
  3917.          The basic TVMFileEditor and derived classes support the following
  3918.      additional features:
  3919.  
  3920.          * Recognizes Print File, Print Block, and Save All commands.
  3921.  
  3922.          * A single virtual memory buffer will be shared between two or
  3923.            more editors when they are all looking at the same file.
  3924.  
  3925.          * Buffer clearing and file reload via a single call to the
  3926.            doneBuffer() function.
  3927.  
  3928.          * By adding the necessary code to your editorDialog() function
  3929.            and issuing a broadcast cmReSynch event, you can have the
  3930.            file editors automatically reload their file from disk if it is
  3931.            no longer current after such things as shelling to the DOS
  3932.            prompt.
  3933.  
  3934.          * If the efSetROonLoad bit is set, the editor will check the Read
  3935.            Only access flag on the file and, if set, will make the editor
  3936.            Read Only as well to prevent altering the file.
  3937.  
  3938.          The TVMFileEditor class is almost identical to its normal Turbo
  3939.      Vision counterpart.  However, this file editor supports read block,
  3940.      write block, print block, and printing of the entire file.  I felt
  3941.      that these were more of an I/O nature than a basic editing feature. 
  3942.      The base TVMEditor class will convert the keyboard commands to cmXXXX
  3943.      commands, but will not act on them.  Only TVMFileEditor will.  The
  3944.      Print member function is only defined for TVMFileEditor and is
  3945.      virtual.  It can therefore be overridden if required.  The default
  3946.      function provides basic printing ability.  The only formatting
  3947.      performed is to send hard tabs to the device specified in the global
  3948.      options as the appropriate number of spaces (defined via the local Tab
  3949.      Size option) when the file or a selected block is printed.
  3950.          A big plus to using TVMFileEditors that are looking at the same
  3951.      file is that they will share a common virtual memory buffer.  That
  3952.      way, changes made in one editor will also be reflected in other linked
  3953.      editors.  This will also conserve conventional memory.  Editors that
  3954.      share a common buffer will use about 96% LESS conventional memory than
  3955.      the first one opened for the file.  The amount of virtual memory saved
  3956.      will also be substantial.  Each editor that is sharing the buffer
  3957.      won't have any allocated for it because there is one common buffer
  3958.      object between them.
  3959.          Each editor will still retain its own local options and will
  3960.      function independently of the others.  Changes to the text in one
  3961.      editor will be reflected on screen in the others only when you move
  3962.      between them.  Also, you will not be prompted to save a modified file
  3963.  
  3964.  
  3965.  
  3966.  
  3967.  
  3968.  
  3969.  
  3970.      if you close a linked window.  You are only prompted when you close
  3971.      the very last window that is viewing the modified file.
  3972.  
  3973.  
  3974.                               Data and Function Members
  3975.                               -------------------------
  3976.      ----------------------
  3977.      char fileName[MAXPATH]
  3978.      ----------------------
  3979.          This contains the name of the text file being edited.  The name is
  3980.      displayed on the top border of TVMEditWindow objects.
  3981.  
  3982.      ------------------------------------------------------------
  3983.      TVMFileEditor(const TRect &bounds, TScrollBar *aHScrollBar,
  3984.              TVMScrollbar *aVScrollBar, TVMIndicator *aIndicator,
  3985.              const char *aFileName, short bufSizeInK = 20,
  3986.              Boolean SuppressLoad = False)
  3987.      ------------------------------------------------------------
  3988.          This is the constructor for the TVMFileEditor class.  As you can
  3989.      see, the first five parameters match up to the original TFileEditor
  3990.      class with the exceptions of the vertical scrollbar being a
  3991.      TVMScrollBar and the indicator being a TVMIndicator.  Following those
  3992.      is the additional parameter bufSizeInK that you may or may not want to
  3993.      specify.  This parameter specifies (in Kilobytes) how large the
  3994.      conventional memory buffer will be for the editor object.  This buffer
  3995.      is used to hold the recently used text and internal information
  3996.      necessary for editing the file.  By default, it is 20K.  Derived
  3997.      classes can adjust this upwards or downwards based on their needs.  If
  3998.      you do not want one of the optional scrollbars or the indicator, pass
  3999.      a NULL in that parameter's position.  The last parameter,
  4000.      SuppressLoad, will function just as it does for TVMEditWindow.  When
  4001.      True, it suppresses the loading of text until you call the
  4002.      loadFileNow() function for the editor.
  4003.  
  4004.      -------------------------------------
  4005.      virtual Boolean valid(ushort command)
  4006.      -------------------------------------
  4007.          This overridden valid() function will insure that a modified
  4008.      editor is not closed without first prompting the user to either save
  4009.      it or discard it.  You will not be prompted to save a modified file if
  4010.      it is sharing a buffer with another editor.  Only the last remaining
  4011.      editor attached to the buffer will prompt you to save it upon closing.
  4012.  
  4013.      ---------------------------------------
  4014.      virtual void handleEvent(TEvent &event)
  4015.      virtual void shutDown(void)
  4016.      virtual void updateCommands(void)
  4017.      ---------------------------------------
  4018.           These three functions are overridden to handle the extra commands
  4019.      recognized by the TVMFileEditor class.  Because multiple ownership is
  4020.      a possibility, the cmUpdateTitle command is handled by
  4021.  
  4022.  
  4023.  
  4024.  
  4025.  
  4026.  
  4027.  
  4028.      TVMFileEditor::handleEvent() instead of TVMEditWindow::handleEvent(). 
  4029.      This event is sent to each owner by the buffer object whenever the
  4030.      filename changes for one of its owners.
  4031.  
  4032.      ----------------------------------------------------------------------
  4033.      virtual void doneBuffer(Boolean releaseMem = True, Boolean reloadFile)
  4034.      ----------------------------------------------------------------------
  4035.           This function calls TVMEditor::doneBuffer() and, if reloadFile is
  4036.      True, will reload the file it contains from disk.  An example of when
  4037.      this is used is the cmReSynch command.  The TVMFileEditor class will
  4038.      recognize the cmReSynch command as an evBroadcast event.  When
  4039.      received, it will check the date and time stamp of its associated file
  4040.      on disk (if one exists).  If the date and/or time stamp is different,
  4041.      it will call the editorDialog() function with a value of edReSynch and
  4042.      a pointer to the filename.  You can make the editorDialog() function
  4043.      query the user as to whether or not the file should be reloaded or
  4044.      simply return cmYes to force a reload.  Not handling the event or
  4045.      returning a value other than cmYes will prevent the file from being
  4046.      reloaded.  This is useful after a shell to DOS in which the text files
  4047.      may be altered by an external source.  It is also useful for automatic
  4048.      resynchronization of a file editor.  An example might be if you
  4049.      translate the file on disk in some manner and need to insure that an
  4050.      open editor window always reflects the most recent contents.  Two
  4051.      public unsigned int members (FileDate and FileTime) were added to the
  4052.      TVirtualMemory class to support the date and time stamp checking. 
  4053.      They were added there due to the buffer sharing ability.
  4054.  
  4055.      --------------------------------------------
  4056.      virtual void PrintBuffer(long from, long to)
  4057.      --------------------------------------------
  4058.          This is the default print function for TVMFileEditor objects.  It
  4059.      simply takes each line, formats it for tabs if necessary, and sends it
  4060.      to the printer.  If the EOLMarker character is being used, any
  4061.      occurances of it will also be stripped out before printing the line. 
  4062.      This function is virtual, so it can be overridden in a derived class
  4063.      if necessary to provide more print features.
  4064.  
  4065.      ----------------------
  4066.      void loadFileNow(void)
  4067.      ----------------------
  4068.          This loads the file *after* construction when SuppressLoad was set
  4069.      to True.  This is used in cases where the swap file is placed on
  4070.      another drive and/or directory and the swap filename needs to be
  4071.      changed.  By suppressing the load at construction, the swap filename
  4072.      can be changed with the guarantee that it is not already open.  In
  4073.      such situations, a call to loadFileNow() must be issued after setting
  4074.      the swap filename so that the file text is placed in the buffer for
  4075.      you to edit.
  4076.  
  4077.  
  4078.  
  4079.  
  4080.  
  4081.  
  4082.  
  4083.      -------------------------
  4084.      void readFile(char *name)
  4085.      -------------------------
  4086.          This reads text into the current editor buffer from the named file
  4087.      for a cmReadFile command.  The first inserted line is above the
  4088.      current line.  All inserted text is marked as the active block upon
  4089.      return from this function.
  4090.  
  4091.      ---------------------------------------------------------
  4092.      long readText(char *name, long line, Boolean InitialLoad)
  4093.      ---------------------------------------------------------
  4094.          This function is the main data loading function.  It starts
  4095.      inserting text at the specified line number and will return the number
  4096.      of the last line inserted.  For lines that exceed the maximum width,
  4097.      it will split them into two or more pieces.  A warning is issued if
  4098.      this occurs by calling the editorDialog() function with the value
  4099.      edLinesSplit.  The InitialLoad parameter is used when the object is
  4100.      first created so that the virtual memory buffer fills all conventional
  4101.      memory pages before swapping starts.
  4102.  
  4103.      -------------------------------------------------
  4104.      Boolean writeFile(long from, long to, char *name,
  4105.          Boolean updateTimeStamp = False)
  4106.      -------------------------------------------------
  4107.          This function will write the lines 'from' through 'to' out to the
  4108.      specified filename.  It is used for the main file save commands as
  4109.      well as the write block commands.  To provide the most safety during
  4110.      the save, all text is written to a temporary file.  If the save
  4111.      succeeds, the temporary file is then renamed to the real filename.  If
  4112.      it fails, the original file will be left completely intact.  If
  4113.      enabled, this routine will also rename the original file to have the
  4114.      backup filename extension upon successful completion.  The
  4115.      updateTimeStamp parameter is set to True when saving the loaded file
  4116.      so that the internal date and time stamp values are updated for the
  4117.      cmReSynch event.
  4118.  
  4119.  
  4120.  
  4121.  
  4122.  
  4123.  
  4124.  
  4125.                                   The TVMMemo Class
  4126.                                   -----------------
  4127.  
  4128.          The basic TVMMemo class supports the following additional
  4129.      features:
  4130.  
  4131.          * Derived from TVMFileEditor instead of TVMEditor so it supports
  4132.            TVMFileEditor's ability to print text and read/write blocks of
  4133.            text to/from files.
  4134.  
  4135.          * It has less memory overhead when used in a dialog box than its
  4136.            predecessor.
  4137.  
  4138.          * It has better text storage and retrieval mechanisms.
  4139.  
  4140.          * You can use Scroll Lock to toggle how Tab and Shift+Tab are
  4141.            handled inside a dialog box's memo fields.
  4142.  
  4143.          * When using setData() and getData() for loading and retrieving
  4144.            text, the TVMMemo::valid() member function will check the total
  4145.            length of the text it contains to insure that it will fit inside
  4146.            the destination buffer before a call to getData() would be
  4147.            allowed.  This provides some protection from inadvertent memory
  4148.            overwrite.
  4149.  
  4150.          * Lines inside the buffer are separated in a more natural format
  4151.            for easier parsing by the programmer.  Lines will be separated
  4152.            by NULLs, line feeds, or carriage return-line feed pairs.
  4153.  
  4154.          TVMMemo is similar to its standard Turbo Vision counterpart but it
  4155.      is a lot more flexible in usage.  A majority of that flexibility comes
  4156.      from being derived from TVMFileEditor instead of TVMEditor.  It is a
  4157.      TVMFileEditor object with getData(), setData(), and dataSize() members
  4158.      for insertion into a dialog box.  As such, all functions available to
  4159.      the basic TVMFileEditor are available to the TVMMemo including all
  4160.      formatting commands, the clipboard functions if one is defined, search
  4161.      and replace, local option modification, undo/redo, read block, write
  4162.      block, print block, and line jump when an appropriate editorDialog()
  4163.      function equipped for those events is defined.  The demo program has
  4164.      examples of this functionality.  In addition, the TVMMemo can handle a
  4165.      small, fixed buffer size and start swapping if the text exceeds that
  4166.      buffer size.  Thus, multiple memo fields containing large amounts of
  4167.      text can be used together in one or more open dialog boxes without
  4168.      exhausting available conventional memory.
  4169.          Note that unlike TVMFileEditor, the TVMMemo class does not have a
  4170.      filename associated with it.  However, it can implement buffer sharing
  4171.      between other memos or file editors.  As stated earlier, you can pass
  4172.      a filename to TVMMemo for it to load into the buffer, but this is
  4173.      associated only with its extended text storage and retrieval
  4174.      mechanisms.  If used, the memo will be loaded with the text from this
  4175.      file when constructed.
  4176.  
  4177.  
  4178.  
  4179.  
  4180.  
  4181.  
  4182.  
  4183.          If you haven't looked at the code for the original TMemo, you will
  4184.      not have noticed that when stored to a resource file, the memo will
  4185.      store any text it contains in the resource file too.  Thus with
  4186.      TVMMemo, you can have it load a file into its buffer, stream it to a
  4187.      resource file and it will take the loaded text right along with it. 
  4188.      When the memo is restored from the resource file, it will also restore
  4189.      the text it contains.  This feature can be extremely useful for
  4190.      storing large informational dialog boxes in resource files that may
  4191.      not have been included as part of a context sensitive help file. 
  4192.      Currently, this is the only reason for specifying a filename in the
  4193.      constructor.  The name is discarded after loading.  The memo will
  4194.      respond to the cmSave/cmSaveAs commands if necessary, but if you will
  4195.      be saving data to a file in this manner, it would probably be better
  4196.      to use a true TVMFileEditor.
  4197.          I always found it annoying that the TMemo class let Tab and
  4198.      Shift+Tab change focus from one dialog item to the next.  The only
  4199.      alternative was to use spaces in place of tabs.  I altered this habit
  4200.      by using the Scroll Lock key as a toggle.  When Scroll Lock is off,
  4201.      the Tab and Shift+Tab keys will act as they always have.  When Scroll
  4202.      Lock is turned on, Tab and Shift+Tab are handled by the memo field. 
  4203.      Therefore, you can now insert and delete tabs of the appropriate size
  4204.      with a single press of the Tab or Shift+Tab key instead of using the
  4205.      space bar or backspace key.  If you leave Scroll Lock on, the mouse
  4206.      can still be used to move you from field to field.  Optionally, you
  4207.      can simply toggle Scroll Lock on and off as you need it.  When the
  4208.      memo field is constructed or restored from a resource file, Scroll
  4209.      Lock is toggled off automatically.  The indicator (if you create one
  4210.      for the memo field) will always display the current state of the
  4211.      Scroll Lock key.
  4212.          The TVMMemoData structure used to load the memo field is very
  4213.      different.  In order to minimize memory usage when creating and
  4214.      executing the dialog, TVMMemoData simply has a 'char *' to a buffer
  4215.      instead of an INT_MAX sized char array (or a one byte char array for
  4216.      Turbo Vision 2.0).  This allows for a number of different methods of
  4217.      allocating memory and using it to initialize the memo fields.  One
  4218.      small allocation per memo field can be made or one large allocation
  4219.      for all memos can be made.  You can also pass the address of an
  4220.      existing character array or buffer to the memo field as well.  That
  4221.      way, you don't have to allocate any dynamic memory at all.  A comment
  4222.      field within a record's data structure might be such a case.
  4223.  
  4224.      Standard TVMMemo Usage
  4225.      ======================
  4226.          When using setData(), you will use the TVMMemoData structure to
  4227.      specify the maximum length that the buffer can hold (in characters)
  4228.      and also how many characters are currently stored in the buffer
  4229.      including line terminating characters.  Lines within the buffer can be
  4230.      separated by NULLs, line feeds only, or carriage return/line feed
  4231.      pairs.  The load and retrieve functions will interpret the buffer and
  4232.      break up the lines accordingly.  When text is retrieved, lines will be
  4233.      terminated according to what was found at load time.  Note that all
  4234.  
  4235.  
  4236.  
  4237.  
  4238.  
  4239.  
  4240.  
  4241.      lines must conform to the same termination standard.  Mixing line
  4242.      terminators within the same buffer may result in garbled or
  4243.      inappropriately separated lines.
  4244.           If you only insert a single NULL terminated line into the buffer,
  4245.      the line terminator will be set to the NULL character.  If you would
  4246.      like the lines to be terminated with "\n" or "\r\n" when retrieved,
  4247.      then either append those characters to the line before inserting it or
  4248.      call the setLineTerminator() function before retrieving text from the
  4249.      memo field.  If a memo starts out with a completely empty buffer, the
  4250.      line termination character will default to '\r' for carriage
  4251.      return+line feed.
  4252.          The default valid() function used for TVMMemo will sum up the
  4253.      length of all lines in the memo field whenever the dialog box is
  4254.      closed and data is to be returned.  If the memo contains too much
  4255.      data, it will not allow the dialog box to close.  That way, you are
  4256.      protected from accidental memory overwrite.  To close the dialog, you
  4257.      must either cancel it or shorten the text in the memo field so that it
  4258.      will fit in the specified buffer.  Upon return from getData(), the
  4259.      bytesCopied member of the TVMMemoData structure will contain the
  4260.      number of bytes within the buffer including all line termination
  4261.      characters.
  4262.  
  4263.      Non-standard TVMMemo Usage
  4264.      ==========================
  4265.          You may also call the functions to load and retrieve the text
  4266.      yourself manually.  To do this when other fields are present in the
  4267.      dialog box (i.e. input lines, checkboxes, etc), you simply set the
  4268.      length parameter of the TVMMemoData structure to zero and use the
  4269.      LoadMemo() function to load data before executing the dialog box and
  4270.      the RetrieveMemo() function to get the data after executing it.  When
  4271.      a memo field is all by itself in a dialog box (except for push
  4272.      buttons),  you may not need to use the setData() or getData() at all
  4273.      if you are manually storing and retrieving text with LoadMemo() and
  4274.      RetrieveMemo().  In general, setData() and getData() are simpler to
  4275.      implement and should be used if at all possible
  4276.          The LoadMemo() and RetrieveMemo() functions can be used to load
  4277.      and retrieve large amounts of text to/from a memo field or can be used
  4278.      in situations where the true size of the memo field may be unknown
  4279.      until runtime.  Note that even though you are controlling the loading
  4280.      and retrieval of text for the memo field, you can still use setData()
  4281.      and getData() for any other items in the dialog box including other
  4282.      memo fields.  Setting the 'length' parameter of TVMMemoData to zero
  4283.      will tell the TVMMemo::setData() and TVMMemo::getData() functions for
  4284.      that memo field not to do anything when called.  It is then up to you
  4285.      to load and retrieve the text that it contains.
  4286.  
  4287.  
  4288.  
  4289.  
  4290.  
  4291.  
  4292.  
  4293.                             Data and Function Members
  4294.                             -------------------------
  4295.  
  4296.      ------------------------------------------------------------------
  4297.      struct TVMMemoData
  4298.      {
  4299.          // Maximum length.  Up to 60K or use 0 to signal use of
  4300.          // LoadMemo/RetrieveMemo.
  4301.          ushort   length;
  4302.  
  4303.          // NOTE: This is a pointer now, not an array!
  4304.          char    *buffer;
  4305.  
  4306.          // The amount of data to store by setData().  This is how many
  4307.          // characters are parsed when loading data into the editor.
  4308.          // Also:
  4309.          // The amount of data returned by getData().  This is how much
  4310.          // text was retrieved from the memo editor into the buffer.
  4311.          ushort  copyCount;
  4312.      }
  4313.      ------------------------------------------------------------------
  4314.          This is the field structure to use for a dialog box's data
  4315.      structure.  To use it, you need to set 'length' to the maximum length
  4316.      of the TVMMemo field (or zero if you will be loading the memo
  4317.      yourself).  If you use setData() and getData(), you will also need to
  4318.      set the pointer to the address of the text so that it can be loaded
  4319.      automatically.  For setData(), you will need to set copyCount to the
  4320.      number of characters currently in the buffer.  After a call to
  4321.      getData(), copyCount will contain the new number of characters in the
  4322.      buffer.
  4323.  
  4324.      -------------
  4325.      ushort Length
  4326.      -------------
  4327.          The maximum allowable length for this memo field.  This is set to
  4328.      a non-zero value by setData() when necessary and is used by valid() to
  4329.      see if the text will fit in the user-supplied buffer for getData(). 
  4330.      If set to zero either by default at construction or by setData(), then
  4331.      no such checking is performed and it is assumed that the programmer
  4332.      has taken control of loading and retrieving the text.
  4333.  
  4334.      -------------------
  4335.      char LineTerminator
  4336.      -------------------
  4337.          Line terminator for the load and retrieve functions.  This simply
  4338.      holds a character that will determine how lines are terminated when
  4339.      text is retrieved from the buffer by getData() or RetrieveMemo().  It
  4340.      will be either NULL, line feed, or carriage return (for carriage
  4341.      return-line feed).
  4342.  
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.      -------------------------------------
  4350.      static const char * _NEAR MemoTooLong
  4351.      -------------------------------------
  4352.          This points to the text for the "Memo too long" message displayed
  4353.      by the valid() function.  It is displayed via a call to editorDialog()
  4354.      with the parameters edGeneralMsg and the address in this pointer.
  4355.  
  4356.      -------------------------------------------------------
  4357.      TVMMemo(const TRect &bounds, TScrollBar *aHScrollBar,
  4358.         TVMScrollbar *aVScrollBar, TVMIndicator *aIndicator,
  4359.         short bufSizeInK = 1, const char *aFileName = NULL)
  4360.      -------------------------------------------------------
  4361.          This is the constructor for the TVMMemo class.  As you can see,
  4362.      the first four parameters match up to the original TMemo class with
  4363.      the exceptions of the vertical scrollbar being a TVMScrollBar and the
  4364.      indicator being a TVMIndicator.  Following those is the additional
  4365.      parameter bufSizeInK that you may or may not want to specify.  This
  4366.      parameter specifies (in Kilobytes) how large the conventional memory
  4367.      buffer will be for the editor object.  This buffer is used to hold the
  4368.      recently used text and internal information necessary for editing the
  4369.      file.  By default, it is 1K.  Derived classes can adjust this upwards
  4370.      based on their needs.  If you do not want one of the optional
  4371.      scrollbars or the indicator, pass a NULL in that parameter's position. 
  4372.      The last parameter is the optional filename that can be used to
  4373.      pre-load text into the memo field.  The only purpose for this
  4374.      parameter at the present time is for creating message dialogs like the
  4375.      one in the demo program's resource file.
  4376.          When constructed, the TVMMemo object will adjust the
  4377.      Opts.RightMargin value to be 'bounds.b.x - bounds.a.x - 4' if it is
  4378.      larger than that value.  If this is acceptable, you don't have to do
  4379.      anything to set it yourself.  Also, when constructed or restored from
  4380.      a resource file, the TVMMemo object will turn off the Scroll Lock
  4381.      keyboard flag to emulate the original behaviour of TMemo concerning
  4382.      the handling of Tab and Shift+Tab key presses.
  4383.  
  4384.      ---------------------------------------
  4385.      virtual void handleEvent(TEvent &event)
  4386.      ---------------------------------------
  4387.          This is similar to the original TMemo handleEvent(), but it has
  4388.      the added ability to pass Tab and Shift+Tab key presses on to the
  4389.      editor if Scroll Lock is toggled on.
  4390.  
  4391.      -------------------------------------
  4392.      virtual Boolean valid(ushort command)
  4393.      -------------------------------------
  4394.          This will check the length of the memo when necessary to insure
  4395.      that it will fit in the user-supplied buffer referenced in setData()
  4396.      and getData().  Note that the length check is not performed if the
  4397.      length parameter of the TVMMemoData structure was set to zero or if
  4398.      you are totally bypassing setData()/getData() for the dialog box.
  4399.          NOTE:  If you have an extremely large amount of text in the memo
  4400.  
  4401.  
  4402.  
  4403.  
  4404.  
  4405.  
  4406.  
  4407.      field, it might take a little while for valid() to sum up the total
  4408.      size of the memo text.  If it seems to hang when you select OK to exit
  4409.      the dialog, give it a minute or two.  It may just be totalling the
  4410.      size of a very large amount of text.  This generally isn't a problem
  4411.      as it does stop counting as soon as the limit is exceeded.  The main
  4412.      factors will be the speed of the PC and the location of the virtual
  4413.      memory.
  4414.  
  4415.      -------------------------------
  4416.      virtual void getData(void *rec)
  4417.      -------------------------------
  4418.          The getData() function casts the *rec parameter to a TVMMemoData *
  4419.      called 'data' and handles retrieving the memo text and storing it into
  4420.      the user-supplied buffer.  If data->length is non-zero, it retrieves
  4421.      text into the user-supplied data->buffer.  If data->length is zero, it
  4422.      is the programmer's responsibility to retrieve the data.  The
  4423.      data->copyCount member will contain the actual number of bytes copied
  4424.      to the buffer when data->length is non-zero.  Because valid() will not
  4425.      return True unless the text will fit in the buffer, you can be sure
  4426.      that you have it all.  However, if you derive a new TVMMemo class,
  4427.      override valid(), and forget to call the base TVMMemo::valid(), this
  4428.      might not be the case.  So, you should always remember to call the
  4429.      base TVMMemo::valid() function in any overridden valid() function for
  4430.      a derived TVMMemo class.  This is true of most classes in Turbo Vision
  4431.      that have a valid() member function.
  4432.  
  4433.      -------------------------------
  4434.      virtual void setData(void *rec)
  4435.      -------------------------------
  4436.          The setData() function casts the *rec parameter to a TVMMemoData *
  4437.      called 'data' and handles loading the text from the user-supplied
  4438.      buffer into the memo field.  If data->length is non-zero, it loads
  4439.      data from the specified buffer pointed to by data->buffer.  If
  4440.      data->length is zero, it is the programmer's responsibility to load
  4441.      the memo with text.
  4442.  
  4443.      -----------------------------
  4444.      virtual ushort dataSize(void)
  4445.      -----------------------------
  4446.          This simply returns the size of a TVMMemoData structure.
  4447.  
  4448.      -----------------------------------------------------
  4449.      virtual Boolean LoadMemo(ushort length, char *buffer,
  4450.        Boolean FirstPart)
  4451.      -----------------------------------------------------
  4452.          This function is called by setData() to copy the text from the
  4453.      user-supplied buffer into the memo field for use in the dialog box. 
  4454.      It can also be called by you to manually load text into the memo
  4455.      field.  This is generally needed only when special loading techniques
  4456.      are to be used for your data.  This function is also virtual, so you
  4457.      can override it if necessary to handle your own specialized needs.
  4458.  
  4459.  
  4460.  
  4461.  
  4462.  
  4463.  
  4464.  
  4465.          If used, you must call LoadMemo() with the FirstPart parameter set
  4466.      to True for the very first call.  If there are any subsequent calls
  4467.      (if you are loading data in pieces for example), it should be set to
  4468.      False.  On the first call, LoadMemo() needs to be told to determine
  4469.      how the lines are terminated.  If it can't decide what the lines end
  4470.      with, it will use the default line terminator as set in the
  4471.      constructor or via a setLineTerminator() function call.  This will
  4472.      only happen if it cannot find any normal line termination characters
  4473.      (NULL, line feed, or carriage return).  The first one of the
  4474.      previously listed characters it finds will determine how lines are
  4475.      loaded into the memo and how they are terminated when you retrieve the
  4476.      text from it.
  4477.          On any call to LoadMemo(), *buffer will point to the text that
  4478.      needs loading and length will be the actual length of the data in the
  4479.      buffer (including the line termination characters).  The text to be
  4480.      loaded should be in the form of complete lines separated by NULLs,
  4481.      line feeds, or carriage return-line feed pairs.  Currently, this
  4482.      function always returns True.
  4483.  
  4484.      --------------------------------------------------------
  4485.      virtual ushort RetrieveMemo(ushort length, char *buffer,
  4486.        Boolean FirstPart, Boolean *NotDone = NULL)
  4487.      --------------------------------------------------------
  4488.          This function is called by getData() to move the text from the
  4489.      memo field into the user-supplied buffer.  It can also be called by
  4490.      you to manually retrieve text from the memo.  This is generally needed
  4491.      only when special retrieval techniques are to be used for your data. 
  4492.      This function is also virtual, so you can override it if necessary to
  4493.      handle your own specialized needs.
  4494.          If used, you must call RetrieveMemo() with the FirstPart parameter
  4495.      set to True for the very first call.  If there are any subsequent
  4496.      calls (if you are retrieving data in pieces for example), it should be
  4497.      set to False.  On the first call, RetrieveMemo() needs to be told to
  4498.      start from line 1 of the memo text.  On subsequent calls, it will
  4499.      start retrieving text from where it left off on the last call.
  4500.          On any call to RetrieveMemo(), *buffer will point to the place to
  4501.      store the retrieved text and length will be the actual length of the
  4502.      buffer.  The retrieved text will be in the form of complete lines
  4503.      separated by NULLs, line feeds, or carriage return-line feed pairs
  4504.      (whatever was found when it was loaded into the memo field by
  4505.      LoadMemo() or specified via the setLineTerminator() function).
  4506.          Note that only whole lines are returned by this function, and that
  4507.      the buffer may not be filled to capacity.  RetrieveMemo() will return
  4508.      the actual number of bytes copied into the buffer.  You can also
  4509.      specify the address of a Boolean variable and pass it to the function
  4510.      as the 'NotDone' parameter.  If RetrieveMemo() is unable to return all
  4511.      the remaining text from the memo in the specified buffer, it will set
  4512.      this variable to True.  While NotDone is True, you can be sure that
  4513.      there is more text to retrieve.  When NotDone is False upon return
  4514.      from the function, it means that there is no more text in the memo to
  4515.      be retrieved.  You can also tell that all text has been retrieved when
  4516.  
  4517.  
  4518.  
  4519.  
  4520.  
  4521.  
  4522.  
  4523.      a call to RetrieveMemo() returns zero for the number of bytes copied.
  4524.  
  4525.      -------------------------------------
  4526.      Boolean setLineTerminator(char lTerm)
  4527.      -------------------------------------
  4528.           Use this function to explicitly specify what line termination
  4529.      character you want to use in RetrieveMemo().  This must be called
  4530.      after loading text into the memo field and before any text is
  4531.      retrieved from it.  Pass it '\x0', '\n' (line feed only), or '\r' (for
  4532.      CR+LF) to set the line terminator type.  This is useful for buffers
  4533.      that are (or could be) blank when constructed and executed.  By
  4534.      default, such memo fields default to using '\r' (CR+LF) as the line
  4535.      terminator.
  4536.  
  4537.  
  4538.  
  4539.  
  4540.  
  4541.  
  4542.  
  4543.                                   TVECLEAN.COM
  4544.                                   ------------
  4545.  
  4546.          While developing programs that use EMS memory for the editors, it
  4547.      is possible that if the program crashes or you stop it from exiting
  4548.      normally while using the debugger (program reset), the EMS memory
  4549.      allocated to any open editors will not be freed.  This memory will be
  4550.      unavailable until the machine is rebooted or you run TVECLEAN.COM.
  4551.          TVECLEAN.COM simply searches for any EMS memory handles with a
  4552.      name in the form "nnTVMEDT" and frees them.  This is a simple way to
  4553.      free the memory without having to reboot the PC.  The "nn" will be the
  4554.      handle number in hex.  This is how TVMEditor objects name their EMS
  4555.      handles.
  4556.          Note that there is no counterpart program for XMS memory. 
  4557.      Unfortunately, the XMS driver does not allow the naming of its
  4558.      handles.  Therefore, there is no way to tell who owns the memory.  If
  4559.      your program crashes or you stop if from exiting normally under the
  4560.      debugger, any allocated XMS memory remains unavailable until you
  4561.      reboot the PC.
  4562.  
  4563.                                     TVCOLR.H
  4564.                                     --------
  4565.  
  4566.          This library makes use of a method I developed for extending the
  4567.      colors of Turbo Vision classes without the problems usually associated
  4568.      with such a task.  It involves the simple inclusion of a single header
  4569.      file and an alternate TView::mapColor() routine.  These new colors can
  4570.      be modified through a TColorDialog if so desired and, once defined,
  4571.      will not interfere with any current or future color additions you make
  4572.      using this method.
  4573.          This method requires adding color attributes to the default
  4574.      application palette.  If you are familiar with my TVCOLR.ZIP or
  4575.      TVCLR2.ZIP, then you won't have anything at all to learn.  To use it,
  4576.      you override the TApplication::getPalette() member function for your
  4577.      application (an example can be seen in the demo program), #include
  4578.      <tvcolr.h> in the files that need it, and add the supplied alternate
  4579.      MAPCOLOR.CPP to your project.  Just be sure that MAPCOLOR.CPP gets
  4580.      linked in before TV.LIB (or TVNO.LIB and TVO.LIB if using overlays).
  4581.          Complete details of this method can be found in TVCOLR.ZIP (for
  4582.      Turbo Vision 1.03) or TVCLR2.ZIP (for Turbo Vision 2.0) in library 11
  4583.      (Turbo Vision) in the BCPPDOS forum on CompuServe.  I have submitted
  4584.      the entire TVCOLR concept to the public domain, so it is free and can
  4585.      be used in any of your own projects.  If you don't have access to
  4586.      CompuServe, simply make a note on the registration form when ordering
  4587.      and I'll send you a copy of TVCOLR.ZIP or TVCLR2.ZIP with your
  4588.      registered version.  I think it's an easy way to extend the color
  4589.      palettes used by Turbo Vision (but I designed it so... <g>).
  4590.