home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / sharew / dobject / do.doc < prev    next >
Encoding:
Text File  |  1991-08-23  |  160.7 KB  |  4,621 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.                         dObject Version 1.0 User Guide
  31.               Object-Oriented Programming Language for DBASE(tm)
  32.                 Copyright (c) 1991 Intelligent Systems Research
  33.                               All Rights Reserved
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  63.  
  64.  
  65.                               1.0 Introduction
  66.  
  67.      1.1 Introduction
  68.  
  69.      Welcome to  Object-Oriented programming for DBASE(tm) !  dObject is an
  70.      object-oriented programming language with built-in  base  classes  for
  71.      handling DBASE  data,  memo,  and index files.  Using dObject, you can
  72.      build complex applications that use your existing DBASE  files  and  a
  73.      class library  of  over  15  classes  and 300 methods.  You can define
  74.      your own classes and methods that inherit the  features  of  the  base
  75.      classes.   You  can  create new DBASE data, memo, and index files, and
  76.      you can write graphics and full-color windowed hypertext  applications
  77.      that display your DBASE data.
  78.  
  79.  
  80.      dObject includes the following features:
  81.  
  82.           *   a  fast,  efficient  interpreted  language  for  writing
  83.           object-oriented DBASE applications
  84.  
  85.           * a built-in full screen  text  editor  callable  from  your
  86.           applications with hypertext on-line help
  87.  
  88.           *   over   300   built-in   methods  for  integer  and  real
  89.           arithmetic, characters, strings, and dates
  90.  
  91.           * a text-mode windowing system
  92.  
  93.           * a graphics system based on the Borland BGI
  94.  
  95.           * a pop-up menu facility
  96.  
  97.           * DBASE-like SAY and GET output to windows, and code  for  a
  98.           full screen DBASE field editor
  99.  
  100.           * output logging to printers and DOS text files
  101.  
  102.           * LAN-compatible row and file locking of DBASE files
  103.  
  104.           *   a  powerful  GREP-like  pattern  matching  function  for
  105.           strings and DBASE character fields
  106.  
  107.           * a hypertext facility linked to DBASE
  108.  
  109.           * multi-dimensional arrays
  110.  
  111.           * an advanced Collection class  for  managing  complex  data
  112.           structures
  113.  
  114.           *  a  C-style  preprocesssor  for  constant  definitions and
  115.           program text inclusions
  116.  
  117.  
  118.  
  119.                                      - 2 -
  120.  
  121.  
  122.                                                        Chapter 1: Introduction
  123.  
  124.  
  125.      dObject provides the following advantages over the  DBASE  programming
  126.      language:
  127.  
  128.           *  facilities  for defining classes and methods that are far
  129.           superior to the UDF facility  in  DBASE,  including  support
  130.           for inheritance and polymorphism
  131.  
  132.           *  advanced  date  handling including international formats,
  133.           julian dates, and date arithmetic
  134.  
  135.           * facilities for  providing  sophisticated  user  interfaces
  136.           for  DBASE(tm)  applications,  including  use  of  multiple,
  137.           overlapping full-color windows and pop-up menus
  138.  
  139.           * facilities for building hypertext  applications  that  use
  140.           DBASE data and index files
  141.  
  142.           * graphics
  143.  
  144.      1.2 Manual Overview
  145.  
  146.      This  manual  is  both  a user guide and a reference guide to dObject.
  147.      The chapters include:
  148.  
  149.  
  150.           * Chapter 1 - Introduction
  151.  
  152.           * Chapter 2 - Getting Started
  153.  
  154.           * Chapter 3 - dObject Statements
  155.  
  156.           * Chapter 4 - dObject Classes
  157.  
  158.           * Chapter 5 - Numeric Classes
  159.  
  160.           * Chapter 6 - Logical Operations
  161.  
  162.           * Chapter 7 - Characters and Strings
  163.  
  164.           * Chapter 8 - Dates
  165.  
  166.           * Chapter 9 - Windows and Menus
  167.  
  168.           * Chapter 10 - Arrays and Collections
  169.  
  170.           * Chapter 11 - Files and Devices
  171.  
  172.           * Chapter 12 - DBASE File Programming
  173.  
  174.           * Chapter 13 - BGI Graphics
  175.  
  176.  
  177.  
  178.  
  179.                                      - 3 -
  180.  
  181.  
  182. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  183.  
  184.  
  185.      1.3 How to Contact ISR
  186.  
  187.      If you need technical support or would  like  to  contact  Intelligent
  188.      Systems  Research  with  comments,  suggestions,  or  questions  about
  189.      dObject, please write to us at:
  190.  
  191.  
  192.              Intelligent Systems Research
  193.              P.O. Box 3690
  194.              Chicago IL 60654 USA
  195.              (312)-878-6054
  196.  
  197.              CompuServ: Send E-mail to userid 70304,2520
  198.  
  199.  
  200.      Please include your dObject version number,  your  computer  make  and
  201.      model  number,  and your operating system make and model number if you
  202.      have technical questions or need detailed technical support.
  203.  
  204.  
  205.  
  206.                            2.0 Getting Started
  207.  
  208.      2.1 Hardware Requirements
  209.  
  210.      dObject requires the following minimal hardware configuration:
  211.  
  212.  
  213.           * an 80286, 80386 or 80406 CPU
  214.  
  215.           * 640KB main memory
  216.  
  217.           * a hard disk drive
  218.  
  219.           * MS-DOS 3.0 or above
  220.  
  221.      2.2 Installing dObject
  222.  
  223.      The shareware version of dObject does not need to be installed  beyond
  224.      the "unzip"  of  the  distribution  .ZIP  file.    The  files  DO.EXE,
  225.      HELP.DBF, HELP.DBT, HELP.NDX, ERROR.DBF, ERROR.NDX, and DO.CFG  should
  226.      reside in the hard disk directory "DOBJECT".
  227.  
  228.      The  registered  version  of  dObject comes with an INSTALL program on
  229.      the distribution diskette.  The INSTALL program will  prompt  you  for
  230.      the  name  of  a  directory to create on your hard disk, and then copy
  231.      the dObject distribution files to that directory.  If  you  wish,  you
  232.      can duplicate this yourself by issuing the DOS commands below:
  233.  
  234.  
  235.  
  236.              C:\>md dobject
  237.  
  238.  
  239.                                      - 4 -
  240.  
  241.  
  242.                                                  Chapter 2: Getting Started
  243.  
  244.  
  245.              C:\>cd dobject
  246.              C:\DOBJECT>copy a:do.exe
  247.              C:\DOBJECT>copy a:do.cfg
  248.              C:\DOBJECT>copy a:*.dbf
  249.              C:\DOBJECT>copy a:*.dbt
  250.              C:\DOBJECT>copy a:*.ndx
  251.              C:\DOBJECT>copy a:*.do
  252.              C:\DOBJECT>copy a:*.bgi
  253.              C:\DOBJECT>copy a:*.chr
  254.  
  255.  
  256.      You  should  also  specify  the  DOBJECT  directory as one of the PATH
  257.      options in your DOS AUTOEXEC.BAT file.  dObject will  always  look  in
  258.      the  directory  that  the  DO.EXE  file  is  in for the HELP and ERROR
  259.      databases (including memo and index files).  Make sure that  when  you
  260.      install  dObject,  all  these  files  are in the same directory as the
  261.      executable  file  DO.EXE,  otherwise  the  on-line  help   and   error
  262.      reporting systems will not work properly.
  263.  
  264.  
  265.      Because  dObject  provides  direct access to existing DBASE III format
  266.      files, and becuase  dObject  uses  several  DBASE  III  files  in  its
  267.      runtime  environment,  you should set the DOS FILES and BUFFERS option
  268.      in your config.sys file to at least the following values:
  269.  
  270.  
  271.              FILES=20
  272.              BUFFERS=20
  273.  
  274.  
  275.      To run the BGI demonstration program (BGIDEMO.DO) you must also  first
  276.      define a  DOS  environment variable named BGIPATH.  This variable must
  277.      contain the name of the directory where the supplied BGI  drivers  and
  278.      font files  are  stored.    If  you  install  dObject in the directory
  279.      C:\DOBJECT, you should add this line to your autoexec.bat file:
  280.  
  281.              SET BGIPATH=C:\DOBJECT
  282.  
  283.  
  284.      2.3 Running dObject
  285.  
  286.      To run dObject, at the DOS prompt type "do":
  287.  
  288.  
  289.              C:\>do
  290.  
  291.              dObject Version 1.0 (Shareware)
  292.              Copyright (c) 1991 Intelligent Systems Research
  293.              Please register this version for support and updates
  294.              Press any key to continue...
  295.  
  296.  
  297.  
  298.  
  299.                                      - 5 -
  300.  
  301.  
  302. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  303.  
  304.  
  305.      Pressing any key at  this  point  will  cause  dObject  to  issue  the
  306.      "dObject> "  prompt  and  accept commands.  (The registered version of
  307.      dObject goes directly to  the  "dObject>  "  prompt  without  pausing;
  308.      this is  a  small  reminder  to register the shareware version !).  To
  309.      run a dObject source program directly from the DOS prompt,  type  "do"
  310.      followed  by  the name of the file to run, with a default extension of
  311.      "DO".  For example, to run the dObject program in the  file  "demo.do"
  312.      in the current DOS directory, issue the command:
  313.  
  314.              C:\> do demo
  315.  
  316.  
  317.  
  318.                            3.0 dObject Statements
  319.  
  320.      3.1 Statements
  321.  
  322.      dObject  accepts  statements  at the "dObject>" prompt using free-form
  323.      input.  Statements can be entered in any number of lines but  must  be
  324.      terminated with  a  semicolon.    dObject  will  prompt  for statement
  325.      continuation with the "more>" prompt until  a  semicolon  is  entered.
  326.      dObject accepts the following legal statements:
  327.  
  328.      STATEMENT                       DESCRIPTION
  329.  
  330.      help;                           enter online hypertext help system and
  331.                                      display table of contents
  332.      cls;                            clear screen (current window)
  333.      exit;                           exit dObject and return to DOS (also
  334.                                      recognizes "quit;")
  335.      edit <filename>;                edit file (default extension .DO)  ESC
  336.                                      - exit without saving changes;  F10 -
  337.                                      exit and save changes
  338.      for(statement;exp;statement)    execute statements for range of values
  339.      <statements>
  340.      while <exp> <statements>        while expression is true execute
  341.                                      statements
  342.      if  <exp> <statements> else     conditional execution of statements
  343.      <statements>                    with else clause
  344.      if <exp> <statements>           conditional execution of statements
  345.      do <filename>;                  execute statements in file  (default
  346.                                      extension .DO)
  347.      dos;                            suspend dObject and shell to DOS
  348.      return(<exp>);                  return expression as method result
  349.      show <item>;                    shows internal information about
  350.                                      dObject. "show classes"  shows defined
  351.                                      classes, "show methods" shows defined
  352.                                      methods, "show set" shows SET
  353.                                      variables, "show variables" shows all
  354.                                      defined user  variables
  355.      switch (exp) {<cases>}          conditional execution of cases
  356.      ? <exp>[,<exp>...];             print expression values in current
  357.  
  358.  
  359.                                      - 6 -
  360.  
  361.  
  362.                                                  Chapter 3: dObject Statements
  363.  
  364.  
  365.                                      window
  366.      <exp>;                          evaluate the expression
  367.  
  368.      dObject  accepts comments within source programs using the conventions
  369.      of the "C"  programming  language.    Comments  must  begin  with  the
  370.      characters "/*"  and  end with the characters "*/".  All characters in
  371.      between, including spaces, tabs, and newlines, are treated as  comment
  372.      characters and  are ignored by the interpreter.  The following example
  373.      demonstrates legal dObject comments:
  374.  
  375.  
  376.      /*
  377.              this is a comment
  378.      */
  379.      method Int::zero(self)             /* comments are allowed anywhere */
  380.      {
  381.              return(0); % this is an end-of-line comment
  382.      }
  383.  
  384.  
  385.      To exit from dObject and return to the DOS prompt,  issue  the  "exit"
  386.      command:
  387.  
  388.  
  389.              dObject> exit;
  390.  
  391.  
  392.      To review the on-line hypertext help, issue the "help" command:
  393.  
  394.  
  395.              dObject> help;
  396.  
  397.  
  398.  
  399.      dObject  provides  a way to execute other dObject program source files
  400.      through the use of the  "do"  command  with  a  filename  to  execute.
  401.      dObject  will supply a default extension of ".do" if you do not supply
  402.      one.  For example, to execute the statements in  the  file  "test.do",
  403.      issue the statement:
  404.  
  405.              dObject> do test;
  406.  
  407.  
  408.      3.2 Errors
  409.  
  410.      If  you  make an error in a dObject statement, dObject will attempt to
  411.      locate the  error  and  print  out  the  offending  statement  with  a
  412.      relevant error  message.   The error display will be shown in an Error
  413.      window displayed in  the  lower  left  corner  of  the  screen.    The
  414.      complete  list of error codes generated by dObject is contained in the
  415.      supplied file ERROR.DBF.
  416.  
  417.  
  418.  
  419.                                      - 7 -
  420.  
  421.  
  422. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  423.  
  424.  
  425.      To  produce  the  error   displauy,   dObject   calls   the   built-in
  426.      Int::onError()  method  and passes it the Int error code of the error.
  427.      You can re-define this method in your applications to change  the  way
  428.      that error messages are displayed:
  429.  
  430.  
  431.      /*
  432.              demonstration of the Int::onError() method
  433.              this method is called whenever dObject detects a parse or runtime
  434.              error in a program; normally dObject creates a 1-line window
  435.              at the bottom of the display screen and prints out the error
  436.              number, an error message, and the statement where the error
  437.              was detected.  you can re-define this method to handle errors
  438.              for your own applications
  439.      */
  440.      method Int::onError(self)
  441.      {
  442.              w = new(Window,1,112,112," Error ",10,10,5,50);
  443.              db = new(Dbffile,"error");
  444.              ndx = new(Ndxfile,db,"error");
  445.              seek(db,self);
  446.              ? "ERROR ",self,": ",msg;
  447.              readchar();
  448.              remove(w);
  449.      }
  450.  
  451.      /*
  452.              cause an error
  453.      */
  454.      exit(10002);
  455.  
  456.  
  457.      3.3 Breaks
  458.  
  459.      To  interrupt  a  dObject  program during execution, press the Control
  460.      key and the Break key at the same time (Ctrl-Break).  This will  cause
  461.      dObject  to  issue  an error message for the break, and then return to
  462.      the dObject> prompt.
  463.  
  464.  
  465.  
  466.      3.4 Preprocessor
  467.  
  468.      dObject includes a built-in  preprocessor  for  defining  compile-time
  469.      constants and  file includes.  dObject accepts constant definitions of
  470.      the form:
  471.  
  472.              #define NAME VALUE
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.                                      - 8 -
  480.  
  481.  
  482.                                                  Chapter 3: dObject Statements
  483.  
  484.  
  485.      where NAME is the name of the constant to define,  and  VALUE  is  the
  486.      value to  assign  to  it.   Values can be any single token of text, or
  487.      any string of text delimited with double quotes.    For  example,  the
  488.      following are all legal dObject constant definitions:
  489.  
  490.  
  491.              /*
  492.                      define some commonly used integer codes for characters
  493.              */
  494.              #define ESC 27
  495.              #define CR 13
  496.              #define TRUE "T"
  497.              /*
  498.                      define an alias name for a dObject function
  499.              */
  500.              #define CURRENT_DATE "date()"
  501.  
  502.  
  503.      Whenever  dObject  encounters  a defined constant anywhere in the text
  504.      of a program, it will substitute the defined text before  parsing  and
  505.      executing the  statement.    Use of this technique makes your programs
  506.      more readable and understandable.  For  example,  the  following  code
  507.      uses the constants defined above:
  508.  
  509.              /*
  510.                      read a character from the keyboard
  511.              */
  512.              c = inkey();
  513.              if(c == ESC) ? "the escape key was pressed";
  514.              if(c == CR) ? "the return key was pressed";
  515.  
  516.  
  517.      A  file  can  be  included  in  the source text before it is parsed by
  518.      using the "include" directive:
  519.  
  520.              #include "keydef.do"
  521.  
  522.  
  523.      3.5 Variables
  524.  
  525.      In dObject, variables are used to store any kind of  value  in  memory
  526.      for use  by  your  program.    The names of these variables must begin
  527.      with a lower case alphabetic character (since  upper  case  names  are
  528.      reserved for  class  names);    and  can  then  contain  any number of
  529.      alphabetic or numeric characters, as well  as  the  underscore.    The
  530.      variable  name  must  not  be  one  of  the following dObject reserved
  531.      keywords:  while, for, if, then, else, do, return or method.
  532.  
  533.      For example, the following are legal dObject variable names:
  534.  
  535.           * a
  536.  
  537.  
  538.  
  539.                                      - 9 -
  540.  
  541.  
  542. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  543.  
  544.  
  545.           * a1
  546.  
  547.           * my_variable
  548.  
  549.      The following are NOT legal variable names:
  550.  
  551.           * 1a (begins with a numeric character)
  552.  
  553.           * My_variable (begins with an uppercase character)
  554.  
  555.           * my-variable (uses the '-' character)
  556.  
  557.           * while (uses the reserved dObject keyword while)
  558.  
  559.      Variables use memory space within dObject that can  be  re-used  later
  560.      if your  program no longer needs the variable.  To reclaim the storage
  561.      space for a variable, send the "release"  message  to  an  Exp  object
  562.      containing the name of the variable:
  563.  
  564.              dObject> a = 32;
  565.              dObject> release(#a);
  566.  
  567.  
  568.      3.6 Literals
  569.  
  570.      Literal   values  are  sequences  of  numbers,  letters,  and  special
  571.      characters that are interpreted  as  actual  values  by  dObject,  not
  572.      variable  names.  dObject  accepts  literal  values  in  the following
  573.      formats (note that hex integer constants are defined using  a  leading
  574.      dollar sign):
  575.  
  576.  
  577.      CLASS          FORMAT         EXAMPLE
  578.  
  579.      Nil:           nil            nil
  580.      Date:          mm/dd/yyyy     5/10/1990
  581.      Char:          'c'            'a'
  582.      String:        "ccc"          "this is a string"
  583.      Int (decimal): n              123
  584.      Int (hex):     $n             $1ff
  585.      Long:          nL             123L
  586.      Real:          n.d            12.34
  587.      Logical:       T or F         T
  588.      Collection:    [v1,v2,v3...]  [1,2,$1ff,T,3.3,"four",'5',(1,"one"),5/10/90]
  589.      Exp:           #exp           #date()
  590.  
  591.      3.7 Expressions
  592.  
  593.      Expressions  in  dObject  are combinations of literal values, variable
  594.      names, and "messages". Messages are sent to objects in dObject  either
  595.      as  operators  or  as named messages. Operators are special characters
  596.      (usually one or two characters)  that  have  a  special  meaning  when
  597.  
  598.  
  599.                                      - 10 -
  600.  
  601.  
  602.                                                  Chapter 3: dObject Statements
  603.  
  604.  
  605.      applied  to  values,  and  are  generally used in messages of the form
  606.      "object operator object".  For example, in dObject the expression 1  +
  607.      2 means send the "plus" message to Int 1 with an argument of Int 2.
  608.  
  609.  
  610.      Named  messages are always of the form name(object,args), where "name"
  611.      is the name of the message to send, "object" is  the  object  to  send
  612.      the  message to, and "args" is zero or more values to use as arguments
  613.      to the message.  For example, the  expression  "clear(w)"  in  dObject
  614.      means  send  the  "clear" message to the object stored in the variable
  615.      "w" (presumably a Window object) with no argument. The only  exception
  616.      to  this  convention  are  messages  sent  to  the  Nil  object, which
  617.      effectively have no object or arguments in the calling sequence.   The
  618.      expression  "memory()"  means  send  the  "memory"  message to the Nil
  619.      object.
  620.  
  621.  
  622.      dObject allows the assignment of values and expressions  to  variables
  623.      through  the use of the assignment operator, denoted by the equals (=)
  624.      sign:
  625.  
  626.              dObject> v = 1+2*3;
  627.  
  628.  
  629.      dObject  recognizes  literal  expressions  beginning  with   the   '#'
  630.      character  and  defers  evaluation  of  the  expression until runtime.
  631.      Such  expressions  are  useful  when  you  are  actually  passing   an
  632.      expression  to  a method to evaluate later, such as using the built-in
  633.      "avg" method on a DBASE(tm) file.  The argument to  the  "avg"  method
  634.      is an  expression  to  evaluate  for  each  record  in  the file.  For
  635.      example, the following statements print  the  average  length  of  the
  636.      "lname" field within a DBASE(tm) file:
  637.  
  638.              dObject> db = new(Dbffile,"patient");
  639.              dObject> ? avg(db,#len(trim(lname)));
  640.  
  641.  
  642.      Passing  the  literal  expression #len(trim(lname))) instructs dObject
  643.      to defer evaluating the expression until the "avg" method  runs;    if
  644.      you  forget  the '#' sign before the expression, dObject will evaluate
  645.      the expression and pass the resulting Int value to  the  "avg"  method
  646.      as an argument, which will result in an error !
  647.  
  648.  
  649.      3.8 Program Control Statements
  650.  
  651.      dObject  provides  the  "for",  "while"  and  "switch"  statements  to
  652.      control the flow of program execution, all of  which  are  similar  to
  653.      their counterparts   in   the  C  programming  language.    The  "for"
  654.      statement  executes  a  block  of  statements   while   an   iteration
  655.      expression is true:
  656.  
  657.  
  658.  
  659.                                      - 11 -
  660.  
  661.  
  662. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  663.  
  664.  
  665.              /*
  666.                      demonstrate the for statement
  667.              */
  668.              for(i=0;i<10;i=i+1) ? i;
  669.  
  670.  
  671.      In  this  case,  dObject  will  execute the first statement in the for
  672.      expression, i=0, and then execute the statements in  the  block  after
  673.      the for  expression.  After each pass through the block, the statement
  674.      i=i+1 will be executed, and the expression i<10  evaluated.    If  the
  675.      expression  is  true  dObject  will  continue to execute the statement
  676.      block.  Execution  stops  whenever  the  expression  is  found  to  be
  677.      false.   After  the  for  statement is completed any variables used in
  678.      the statements will still exist;  in the above  example  i  will  have
  679.      the value of 11 after the for statement executes.
  680.  
  681.  
  682.      The  "while"  statement  executes  a  block  of  statements  while  an
  683.      expression evaluates to logical "true":
  684.  
  685.              /*
  686.                      demonstrate the while statement
  687.              */
  688.              i = 1;
  689.              while(i < 10) {
  690.                      ? " i = ",i;
  691.                      i = i+1;
  692.              }
  693.  
  694.  
  695.      The  "switch"  statement  is  similar  to  the  one  found  in  the  C
  696.      programming  language.  An  expression  is  evaluated and then matched
  697.      against the values found in a series of "case" statements.  The  first
  698.      case matching the expression value is executed:
  699.  
  700.  
  701.              /*
  702.                      demonstrate the switch statement
  703.              */
  704.              i = 3;
  705.              switch(i) {
  706.                      case 1:    ? "i is one ";
  707.                      case 2:    ? "i is two ";
  708.                      case 3:    ? "i is three ";
  709.                      case 4:    ? "i is four ";
  710.              }
  711.  
  712.  
  713.      In the  above  example  only  the  statement  ?    "i is three " would
  714.      execute within the switch.
  715.  
  716.  
  717.  
  718.  
  719.                                      - 12 -
  720.  
  721.  
  722.                                                  Chapter 3: dObject Statements
  723.  
  724.  
  725.      3.9 Editing Text Files
  726.  
  727.      dObject provides a built-in full screen text editor for  creating  and
  728.      modifying text  files,  including dObject source files.  To invoke the
  729.      editor, issue the "edit" command followed by the name of the  file  in
  730.      the current  directory  to  edit.    dObject  will  supply  a  default
  731.      extension of ".DO" for the file  to  make  it  easy  to  edit  dObject
  732.      source files.    For  example,  to  edit the file "test.do", issue the
  733.      command:
  734.  
  735.              dObject> edit test;
  736.  
  737.  
  738.      dObject will invoke the text editor in the current  window,  which  by
  739.      default is  the  full  screen.   Editing can occur in other windows by
  740.      first creating the window and the issuing the  "edit"  command.    The
  741.      built-in  editor  is  similar  to  the  WordStar(tm)  text  editor and
  742.      responds to the following keystroke commands:
  743.  
  744.  
  745.      FUNCTION                                          KEY
  746.  
  747.      View dObject help for word at cursor              Ctrl-F1
  748.      Move cursor right one character                   right arrow
  749.      Move cursor left one character                    left arrow
  750.      Move cursor up one line                           up arrow
  751.      Move cursor down one line                         down arrow
  752.      Scroll up one line                                Ctrl-W
  753.      Scroll down one line                              Ctrl-Z
  754.      Move cursor right one word                        Ctrl-Right arrow
  755.      Move cursor left one word                         Ctrl-A
  756.      Move cursor to right end of line                  End
  757.      Move cursor to left end of line                   Home
  758.      Move cursor to top of window                      Ctrl-Home
  759.      Move cursor to bottom of window                   Ctrl-End
  760.      Move cursor up one screen                         PgUp
  761.      Move cursor down one screen                       PgDn
  762.      Move cursor to top of file                        Ctrl-PgUp
  763.      Move cursor to bottom of file                     Ctrl-PgDn
  764.      Delete character at cursor                        Del, Ctrl-G
  765.      Delete character left of cursor                   Backspace
  766.      Delete word at cursor                             Ctrl-T
  767.      Delete line at cursor                             Ctrl-Y
  768.      Delete left from cursor to start of line          Ctrl-Q T
  769.      Delete right from cursor to start of line         Ctrl-Q Y
  770.      Mark beginning of block                           Ctrl-K B
  771.      Mark end of block                                 Ctrl-K K
  772.      Copy (insert) marked block at cursor              Ctrl-K C
  773.      Move (insert) marked block at cursor              Ctrl-K V
  774.      Delete marked block                               Ctrl-K Y
  775.      Write marked block to diskfile                    Ctrl-K W
  776.      Write marked block to printer                     Ctrl-K P
  777.  
  778.  
  779.                                      - 13 -
  780.  
  781.  
  782. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  783.  
  784.  
  785.      Block select on/off                               Ctrl-K M
  786.      Copy block to pastebuffer                         Ctrl-K I
  787.      Move block to pastebuffer                         Ctrl-K Y
  788.      Paste                                             Ctrl-U
  789.      Search                                            Ctrl-F3 or Ctrl-Q F
  790.      Search again                                      Shift-F3 or Ctrl-O
  791.      Replace                                           F4
  792.      Replace again                                     Shift-F4 or Ctrl-L
  793.  
  794.      The key assignments for the editor are contained in the file  "do.cfg"
  795.      that is  loaded  at  runtime by dObject.  You can change these default
  796.      combinations by  calling  the  Nil::setupKeyboard()  method  from  the
  797.      dObject  prompt,  changing  the key assignments using the menu choices
  798.      provided, and then saving the  current  key  configuration  using  the
  799.      String::saveConfig method.    The  following  example illustrates this
  800.      procedure:
  801.  
  802.              dObject> setupKeyboard();
  803.              dObject> saveConfig("new.cfg");
  804.              dObject> exit;
  805.              C:\DOBJECT:> rename do.cfg old.cfg
  806.              C:\DOBJECT:> rename new.cfg do.cfg
  807.  
  808.  
  809.      From within the Nil::setupKeyboard() method, a series of menu  choices
  810.      will  be  presented  that allow you to choose the particular functions
  811.      within  the  editor  to  be  re-assigned  to  a   key   or   keystroke
  812.      combination.   To  redefine  a  command's  keystroke(s), highlight the
  813.      menu item for the command using the arrow keys and press  Enter.    In
  814.      the  input  box  that  appears,  you  can  define  one  or two sets of
  815.      keystrokes for the command.  Press Enter to skip over  the  first  set
  816.      of  keystrokes,  or  press the new key combination for the first setup
  817.      and then press Enter.  When the cursor is in the second column,  press
  818.      Enter  to  skip  the  second  setup,  or  press  a new key combination
  819.      followed by Enter.  To abort this process at any time  press  the  Esc
  820.      key.
  821.  
  822.  
  823.      Your  application  can  load  a special .CFG file at runtime using the
  824.      String::loadConfig method and passing it  the  name  of  the  file  to
  825.      load.   The  file  should be one of the supplied .CFG files that comes
  826.      with dObject, or a .CFG file you  have  created  using  the  procedure
  827.      described above.
  828.  
  829.  
  830.      Comprehensive  on-line  help  for  editor  commands  is available from
  831.      within the  editor  by  pressing  the  F1  key.    Help  for   dObject
  832.      statements  and  built-in classes and methods is available from within
  833.      the editor by placing the cursor on a dObject keyword, class name,  or
  834.      method name and pressing the Ctrl-F1 key.
  835.  
  836.  
  837.  
  838.  
  839.                                      - 14 -
  840.  
  841.  
  842.                                                  Chapter 3: dObject Statements
  843.  
  844.  
  845.      3.10 Input and Output Statements
  846.  
  847.      The  "?"  statement prints the value of an expression onto the current
  848.      window, followed by a carriage return and line feed:
  849.  
  850.              dObject> ? 1+1;
  851.              2
  852.              dObject>
  853.  
  854.  
  855.      The String::accept() method provides a simple way to  write  a  prompt
  856.      and read Strings from the keyboard:
  857.  
  858.              dObject> line = accept("enter value> ");
  859.  
  860.  
  861.      For  a  detailed  description  of the input, output, and file handling
  862.      capabilities of dObject, refer  to  the  chapters  titled  "Files  and
  863.      Devices" and "Windows and Menus" later in this manual.
  864.  
  865.  
  866.      3.11 Output Logs
  867.  
  868.      dObject  will  also  log  the  output  from  the "?" command to a file
  869.      and/or an attached printer using the built-in log feature.    Pressing
  870.      the  ALT-P  key  combination  will  display  a  popup menu showing the
  871.      current on/off status of the logs to  the  printer  and  to  the  file
  872.      PROLOG.LOG.   To  toggle the status from off to on and vice versa, use
  873.      the arrow keys to position the menu bar, and press the RETURN  key  to
  874.      toggle the  value.    Press the ESC key to exit the menu and return to
  875.      the dObject prompt.
  876.  
  877.  
  878.      3.12 Environment Variables
  879.  
  880.      dObject maintains a small set of environment  variables  that  can  be
  881.      set  using  the  String::set()  method  and interrogated by the "show"
  882.      command.  These environment variables are:
  883.  
  884.  
  885.      VARIABLE     DEFAULT     DESCRIPTION
  886.  
  887.      echo         F           when true, causes dObject to echo the
  888.                               statement just about to be executed to the
  889.                               current window
  890.      hyperhelp    T           when true, allows use of Ctrl-F1 key from
  891.                               within editor  to access dObject help stored
  892.                               in HELP.DBF file; when false, disables
  893.                               Ctrl-F1
  894.      newline      nl          dObject will print this value at the end of
  895.                               each "?" statement
  896.      prompt       "dObject>"  the String to be used as the command prompt
  897.  
  898.  
  899.                                      - 15 -
  900.  
  901.  
  902. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  903.  
  904.  
  905.      softseek     F           when true, all String comparisons return true
  906.                               (T) if  a "partial match" occurs; that is if
  907.                               the first string being compared is a
  908.                               substring of second string.  when off,
  909.                               dObject returns true only if the strings
  910.                               being compared are identical, including
  911.                               trailing blanks
  912.      space        ""          dObject will print this value between
  913.                               expressions in the "?"  statement; normally
  914.                               set to a null String
  915.      status       T           when true, status lines appear for text
  916.                               editor,  window resize, etc. when false,
  917.                               turns off display of all status lines
  918.      step         F           when true, causes dObject to pause between
  919.                               executing statements and print the message:
  920.                               Press SPACE to continue, ESC to abort...
  921.                               pressing the space key executes the next
  922.                               statement pressing the ESC key returns to the
  923.                               dObject> prompt
  924.  
  925.      To set an enviroment variable to a value, use the String::set  method,
  926.      with the "self" argument set to the name of the SET variable:
  927.  
  928.              dObject> set("echo",T);
  929.  
  930.  
  931.      For example, to change the dObject prompt, set the prompt variable:
  932.  
  933.              dObject> set("prompt","--> ");
  934.              -->
  935.  
  936.  
  937.      To  show  the  value  of  all the environment variables, use the "show
  938.      set" command:
  939.  
  940.              dObject> show set;
  941.              echo=logical(false)
  942.              step=logical(false)
  943.              softseek=logical(false)
  944.              status=logical(true)
  945.              hyperhelp=logical(true)
  946.              prompt=string("dObject> ")
  947.              space=char(' ')
  948.  
  949.  
  950.      The value of a particular set variable is  available  by  calling  the
  951.      String::set()  method with self set to the name of the set variable to
  952.      retrieve and with no other arguments:
  953.  
  954.              dObject> ? set("echo");
  955.              F
  956.  
  957.  
  958.  
  959.                                      - 16 -
  960.  
  961.  
  962.  
  963.                                                  Chapter 3: dObject Statements
  964.  
  965.  
  966.      To show all the currently defined dObject  variables,  use  the  "show
  967.      variables" command:
  968.  
  969.              dObject> a = 1;
  970.              dObject> b = 2;
  971.              dObject> show variables;
  972.              a=1
  973.              b=2
  974.  
  975.  
  976.      To  show  all the classes you have defined in a dObject session beyond
  977.      the built-in classes, use the "show classes"  command  (refer  to  the
  978.      next chapter for a description of how to create these classes):
  979.  
  980.              dObject> show classes;
  981.  
  982.  
  983.      To  show  all  the  methods  currently defined, use the "show methods"
  984.      command.
  985.  
  986.  
  987.      3.13 The RETURN Statement
  988.  
  989.      The return statement is used to return a value from a  dObject  method
  990.      back to   a  calling  program.    The  format  of  this  statement  is
  991.      return(exp), where exp is any dObject expression as  described  above.
  992.      The  use  of  this statement is appropriate only when defining you own
  993.      dObject classes and methods, a topic that is described  in  detail  in
  994.      the next chapter.
  995.  
  996.  
  997.  
  998.  
  999.                              4.0 dObject Classes
  1000.  
  1001.      4.1 Objects
  1002.  
  1003.      dObject  provides  a  powerful  facility  for  you  to  write  complex
  1004.      applications using the "Object" paradigm.  With this way of  thinking,
  1005.      you  define  an  object as something within the problem you are trying
  1006.      to  solve  that  you  want  the  computer  to  represent   and   store
  1007.      information about.    For  example,  in  a  small  business  accouting
  1008.      system, the objects might include Companies,  Departments,  Employees,
  1009.      Products, and  Accounts, to name but a few.  Each of these objects has
  1010.      a certain correct behavior in the computer, such as a behavior to  add
  1011.      a  new Employee to a Company, or a behavior for calculating the profit
  1012.      from the sale of a Product to a Customer.
  1013.  
  1014.  
  1015.      In dObject,  the  object  types  within  the  application  are  called
  1016.      "Classes",  and  the  rules  that  tell the computer how a class is to
  1017.      behave are called "Methods".  Each class has a set of methods that  it
  1018.  
  1019.  
  1020.                                      - 17 -
  1021.  
  1022.  
  1023. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1024.  
  1025.  
  1026.      knows  about  that  allow  it  to  perform  calculations on the class.
  1027.      dObject provides a large library of built in classes,  each  with  its
  1028.      own  set  of  methods,  that  allow you to create complex applications
  1029.      right away.  However, to fully exploit the  power  of  object-oriented
  1030.      programming,  you  will eventually want to create your own classes and
  1031.      methods that apply directly to the problems you want to  solve.    You
  1032.      create  these  new  classes and methods by building them on top of the
  1033.      existing classes and methods.
  1034.  
  1035.  
  1036.      4.2 Class Definitions
  1037.  
  1038.      To create a new object class, use the "inherit" message on an  already
  1039.      existing dObject class:
  1040.  
  1041.              inherit(Parentclass,Newclass,variables);
  1042.  
  1043.  
  1044.      where   "Newclass"   is   the   name  of  the  new  class  to  define,
  1045.      "Parentclass" is the class to inherit  from,  and  "variables"  is  an
  1046.      array of  strings  that  name instance variables within the class.  In
  1047.      dObject, the names of classes must  always  begin  with  an  uppercase
  1048.      letter, followed  by  upper or lower-case characters or numerals.  For
  1049.      example, the statement:
  1050.  
  1051.              inherit(Date,Mydate,["julian"]);
  1052.  
  1053.  
  1054.      You should use the "Nil"  class  as  a  parent  class  that  does  not
  1055.      inherit data or methods from any parent.
  1056.  
  1057.  
  1058.      To create a variable of a given class type, use the "new" message:
  1059.  
  1060.              v = new(Class,arguments)
  1061.  
  1062.  
  1063.      where  "v"  is  the name of the variable to create, and "Class" is the
  1064.      object class of the variable.  For example, to create a  new  instance
  1065.      of  the "Mydate" class and store it into a variable named "d", use the
  1066.      statement:
  1067.  
  1068.              d = new(Mydate);
  1069.  
  1070.  
  1071.      dObject  provides  a  number  of  base  classes  as  building  blocks,
  1072.      including:
  1073.  
  1074.           * Nil - an empty class
  1075.  
  1076.           * Int - 2-byte signed integers
  1077.  
  1078.  
  1079.  
  1080.                                      - 18 -
  1081.  
  1082.  
  1083.                                                     Chapter 4: dObject Classes
  1084.  
  1085.  
  1086.           * Long - 4 byte signed integers
  1087.  
  1088.           * Real - floating point numbers
  1089.  
  1090.           * Char - single characters
  1091.  
  1092.           * String - strings of characters (up to 64K in length)
  1093.  
  1094.           * Logical - true (T) or false (F)
  1095.  
  1096.           * Date - dates
  1097.  
  1098.           *  Array  -  an array of object at locations indicated by an
  1099.           index
  1100.  
  1101.           * Collection - an ordered collection of objects
  1102.  
  1103.           * File - DOS ASCII text  files  and  devices  (such  as  the
  1104.           printer)
  1105.  
  1106.           *  Exp  -  literal dObject expressions that can be passed as
  1107.           arguments
  1108.  
  1109.           * Dbffile - DBASE files
  1110.  
  1111.           * Ndxfile - DBASE index files
  1112.  
  1113.           * Address - addresses of other objects
  1114.  
  1115.      The class of any dObject variable can always be found by  sending  the
  1116.      object the built-in "class" message:
  1117.  
  1118.              dObject> ? class(5/10/91);
  1119.              Date
  1120.              dObject> ? class("this is a test");
  1121.              String
  1122.              dObject> ? class(T);
  1123.              Logical
  1124.  
  1125.  
  1126.      4.3 Method Definitions
  1127.  
  1128.      To create a named method for a class, use the format:
  1129.  
  1130.              method Class::name(self,arguments)
  1131.              {
  1132.                      statements...
  1133.              }
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.                                      - 19 -
  1141.  
  1142.  
  1143. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1144.  
  1145.  
  1146.      Values  are  returned  to  the  calling program through the use of the
  1147.      "return" statement.  This should be the last statement  executed  from
  1148.      within a  method.  Methods that do not use a "return" statement have a
  1149.      return value of Nil.
  1150.  
  1151.  
  1152.      The special variable "self" always refers to the specific instance  of
  1153.      the object  that  the  method  is  being  performed on.  You can treat
  1154.      "self" as any other argument in the calling sequence.  For example:
  1155.  
  1156.              method Mydate::asString(self)
  1157.              {
  1158.                      return(asString(slot(self,"julian"));
  1159.              }
  1160.  
  1161.  
  1162.      defines a method for  the  "Mydate"  class  to  convert  itself  to  a
  1163.      String.
  1164.  
  1165.  
  1166.      To  define an operator for a class, use the character representing the
  1167.      operator as the method name.  For example, to define the '+'  operator
  1168.      for the Mydate class:
  1169.  
  1170.              method Mydate::+(self,d)
  1171.              {
  1172.                      return(asDate(julian(self) + julian(d)));
  1173.              }
  1174.  
  1175.  
  1176.      Variables  within  a  class  can be set by using the "replace" method,
  1177.      and referenced by the "slot" method. However, these  two  methods  are
  1178.      only available  from  within  methods  defined  for  the  class!  This
  1179.      implements an important feature of object-oriented programming:   data
  1180.      hiding.   Using  data hiding, it is good programming form to provide a
  1181.      method that returns the value of a variable within  a  class,  instead
  1182.      of allowing  a calling program to access that variable directly.  That
  1183.      way, if the implementation of the object changes at some  later  date,
  1184.      and  the  variables  within the class change, only the methods for the
  1185.      class need to understand the change  !    The  "outside  world"  still
  1186.      accesses information about the class through the methods.
  1187.  
  1188.  
  1189.      4.4 Private Methods
  1190.  
  1191.      By  default,  methods  defined  using  the  syntax described above are
  1192.      "public" in scope - they are available to any  other  method  or  main
  1193.      program that  wants to use them.  In some cases, however, you may wish
  1194.      to define methods that are hidden from other methods in the  same  way
  1195.      that variables  are  hidden.  dObject lets you do this by substituting
  1196.      the keyword "private" for "method" in  the  method  definition.    The
  1197.      following example shows how to define a private method for a class:
  1198.  
  1199.  
  1200.                                      - 20 -
  1201.  
  1202.  
  1203.                                                     Chapter 4: dObject Classes
  1204.  
  1205.  
  1206.              private Mydate::yearPlusOne(self)
  1207.              {
  1208.                      return(year(self)+1);
  1209.              }
  1210.  
  1211.  
  1212.  
  1213.      In  the  example  above, the "yearPlusOne" method is only available to
  1214.      other methods of the Mydate class.  Attempts to call it from a  method
  1215.      of  another  class  or  from  a  main  program  will generate an error
  1216.      message.
  1217.  
  1218.  
  1219.      The following example illustrates the use of a private method:
  1220.  
  1221.  
  1222.      /*
  1223.              demo of a private method for a class
  1224.              private methods are only callable from within a method for a class
  1225.      */
  1226.      inherit(Nil,Temp,[]);
  1227.  
  1228.      private Temp::testPrivate(self)
  1229.      {
  1230.              ? "within testPrivate";
  1231.      }
  1232.  
  1233.      method Temp::test(self)
  1234.      {
  1235.              ? "enter Temp::test";
  1236.              testPrivate(self);
  1237.              ? "exit Temp::test";
  1238.      }
  1239.  
  1240.      v = new(Temp);
  1241.      test(v); % this will work, Temp::testPrivate will be called by Temp::test
  1242.      ? "the next statement will cause an error !...";
  1243.      testPrivate(v); % this will cause an error !
  1244.  
  1245.  
  1246.      4.5 Friend Classes
  1247.  
  1248.      In some cases, you may wish to share the variables and/or the  private
  1249.      methods defined  for  a  class  with  another  class.    In this case,
  1250.      dObject provides the Exp::friend() method to allow such access.    The
  1251.      following  example  shows  how  to  define  one  class  as a friend of
  1252.      another:
  1253.  
  1254.      /*
  1255.              demo of a private method for a class
  1256.              private methods are only callable from within a method for a class
  1257.      */
  1258.  
  1259.  
  1260.                                      - 21 -
  1261.  
  1262.  
  1263. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1264.  
  1265.  
  1266.      inherit(Nil,Temp,[]);
  1267.      inherit(Nil,Temp2,[]);
  1268.  
  1269.      /*
  1270.              defining class Temp2 as a friend of class Temp
  1271.              means that methods of Temp2 can access variable and private
  1272.              methods of Temp
  1273.      */
  1274.      friend(Temp,Temp2);
  1275.  
  1276.      /*
  1277.              define a private method for Temp
  1278.      */
  1279.      private Temp::testPrivate(self)
  1280.      {
  1281.              ? "within Temp::testPrivate()";
  1282.      }
  1283.  
  1284.      /*
  1285.              define a public method for Temp2 that creates a variable of
  1286.              type Temp and calls a private method for it
  1287.      */
  1288.      method Temp2::test(self)
  1289.      {
  1290.              ? "enter Temp2::test";
  1291.              v = new(Temp);
  1292.              testPrivate(v); % this won't work unless Temp2 is a friend of Temp !
  1293.              ? "exit Temp2::test";
  1294.      }
  1295.  
  1296.      v = new(Temp2);
  1297.      test(v);
  1298.  
  1299.  
  1300.      4.6 Inheritance
  1301.  
  1302.      dObject stores variables for classes you define by allocating  storage
  1303.      for  a  variable  of  its  parent  class type, and storage for all the
  1304.      variables defined in the "inherit"  statement  for  its  class.    For
  1305.      example,  consider  a  class  called "Time" that inherits its behavior
  1306.      from the  Date  class.    The  "Time"  class  also  contains  internal
  1307.      variables   for  hours,  minutes,  and  seconds,  as  defined  in  the
  1308.      following statement:
  1309.  
  1310.  
  1311.              dObject> inherit(Date,Time,["hours","minutes","seconds"]);
  1312.  
  1313.  
  1314.      A new variable of type "Time" can be constructed as follows:
  1315.  
  1316.  
  1317.              dObject> t = new(Time,7/20/1990,1,2,3);
  1318.  
  1319.  
  1320.                                      - 22 -
  1321.  
  1322.  
  1323.                                                     Chapter 4: dObject Classes
  1324.  
  1325.  
  1326.      Internally, the variable "t" would be stored as  an  object  of  class
  1327.      "Time", with  4  internal  variables.    The first variable is of type
  1328.      Date (the parent class), with the value of 7/20/1990.   The  remaining
  1329.      variables  are  the  values  for  "hours", "minutes", and "seconds" as
  1330.      defined in the inherit statement above, with values of  1,  2,  and  3
  1331.      respectively.
  1332.  
  1333.  
  1334.      dObject  classes  "inherit"  all  the variables and methods from their
  1335.      parent class.  If you send a message to a  variable  of  a  class  you
  1336.      create  and  a  method  for  the message has not been defined, dObject
  1337.      will begin searching backwards through the parent class(es) to try  to
  1338.      find a  method  definition  it  can  use.    If a method is found, the
  1339.      variable storing the parent class  value  is  passed  to  the  method,
  1340.      without any  of  the  variables  for the original class.  This process
  1341.      continues until no more parent classes are found.
  1342.  
  1343.  
  1344.      For example, if you send the "asString" message to a Time variable  as
  1345.      defined  below,  and  you have not defined a version of "asString" for
  1346.      the Time class, then dObject will take the parent Date value and  send
  1347.      it the "asString" message:
  1348.  
  1349.  
  1350.              dObject> inherit(Date,Time,["hours","minutes","seconds"]);
  1351.              dObject> t = new(Time,7/20/1991,1,2,3);
  1352.              dObject> ? asString(t);
  1353.              7/20/1991
  1354.  
  1355.  
  1356.      4.7 Parameter Passing
  1357.  
  1358.      dObject  normally  passes arguments to methods by creating an internal
  1359.      stack and pushing the value for all the arguments to the  method  onto
  1360.      it.   This  is  exactly  the  way  the  C  language  calls  functions.
  1361.      However, in dObject, this implies that you  cannot  internally  change
  1362.      the  value  of  a  variable  within a class, but must instead return a
  1363.      copy of the variable containing the change.  This  leads  to  an  easy
  1364.      error to make:
  1365.  
  1366.      /*
  1367.              define a class for Money
  1368.      */
  1369.      inherit(Int,Money,["cents"]);
  1370.  
  1371.      method Money::setCents(self,c)
  1372.      {
  1373.              return(replace(slot(self,"cents"),i));
  1374.      }
  1375.  
  1376.  
  1377.      /*
  1378.  
  1379.  
  1380.                                      - 23 -
  1381.  
  1382.  
  1383. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1384.  
  1385.  
  1386.              create a variable of type Money
  1387.      */
  1388.      m = new(Money);
  1389.      setCents(m,100); % this is wrong !
  1390.  
  1391.  
  1392.      While  it  may appear simple to set a Money variable to a value from a
  1393.      calling program, be  careful  !    You  must  remember  to  store  the
  1394.      returned copy of the variable back into itself:
  1395.  
  1396.      /*
  1397.              assign "m" a value the wrong way
  1398.      */
  1399.      setCents(m,100); % this returns a copy of m with "cents"=100 that is lost
  1400.  
  1401.      /*
  1402.              assign "m" a value the right way
  1403.      */
  1404.      m = setCents(m,100); % this stores the copy back in m !
  1405.  
  1406.  
  1407.      dObject  allows a program to circumvent the need to always pass copies
  1408.      of variables around through the use of the Address class.   Using  the
  1409.      "address-of"  operator (the "&" symbol, as in C), you can instead pass
  1410.      the address of a variable to a method:
  1411.  
  1412.              setCents(&m,100);
  1413.  
  1414.  
  1415.      However, to do  this  correctly,  the  method  must  be  expecting  an
  1416.      address of  a variable and not a copy of the variable itself.  This is
  1417.      done by using an asterik before the argument in the method  definition
  1418.      wherever an  address  is  to be used.  The following example shows how
  1419.      to define and use a method that replaces  the  value  of  an  internal
  1420.      class variable directly in memory:
  1421.  
  1422.  
  1423.      /*
  1424.              define a new version of the setCents method that
  1425.              replaces a memory location and does not return a copy
  1426.      */
  1427.      method Money::setCents(*self,c)
  1428.      {
  1429.              replace(slot(*self,"cents"),c);
  1430.      }
  1431.  
  1432.      /*
  1433.              now this is OK !
  1434.      */
  1435.      m = new(Money);
  1436.      setCents(&m,100); % m will be updated in-place
  1437.  
  1438.  
  1439.  
  1440.                                      - 24 -
  1441.  
  1442.  
  1443.                                                     Chapter 4: dObject Classes
  1444.  
  1445.  
  1446.      To  access  the  contents  of  an address, use the "contents" operator
  1447.      (the asterik character), again just like in the C language:
  1448.  
  1449.              dObject> ?class(&1);
  1450.              Address
  1451.              dObject> ? *&1;
  1452.              1
  1453.  
  1454.  
  1455.      4.8 Space Management
  1456.  
  1457.      To  reclaim  the  space  used  by  a  variable,  send  an   expression
  1458.      containing the name of the variable the "release" message:
  1459.  
  1460.              dObject> a = 1;
  1461.              dObject> release(#a);
  1462.  
  1463.  
  1464.      To  reclaim the space used by a method definition once it is no longer
  1465.      needed by your program, use the "release" method  of  the  Exp  class.
  1466.      Send  the message to the Class name for the method you wish to delete,
  1467.      and pass the message a String argument containing the method name:
  1468.  
  1469.              dObject> release(Myint,"value");
  1470.  
  1471.  
  1472.      To reclaim all the space used by a class,  including  its  definition,
  1473.      its methods, and any variables, use the releaseClass method:
  1474.  
  1475.              dObject> releaseClass(Mydate);
  1476.  
  1477.  
  1478.      4.9 Input and Output
  1479.  
  1480.      To  print the value of an object (while executing the "?" command, for
  1481.      example), dObject first sends the object the "asString" method to  try
  1482.      to convert  it to a String.  If this succeeds, the resulting String is
  1483.      printed and the next object to  print  is  processed.    Each  of  the
  1484.      built-in  classes  provided  in dObject has an asString method defined
  1485.      for it.  If there is no such method for the  class,  dObject  attempts
  1486.      to print  a  representation  of  the internal form of the object.  For
  1487.      user defined classes, this printout will be of the form:
  1488.  
  1489.              object(Class,[slot(Name,Value)...])
  1490.  
  1491.  
  1492.      4.10 Sample Application
  1493.  
  1494.      As a  final  example  of  how  to  create  classes  and  methods,  the
  1495.      following  program  completes the implementation of the abstract class
  1496.      "Money" used in the examples above:
  1497.  
  1498.  
  1499.  
  1500.                                      - 25 -
  1501.  
  1502.  
  1503. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1504.  
  1505.  
  1506.      /*
  1507.              this is an example of a class to handle money as an abstract type
  1508.              first, define a Money class with a variable to hold an
  1509.              integer number of cents; this will be converted into
  1510.              dollars and cents whenever the Money variable is converted to a String
  1511.      */
  1512.      inherit(Int,Money,[]);
  1513.  
  1514.      /*
  1515.              set the number of cents in self
  1516.              NOTE: self must be passed by address for this to work !
  1517.      */
  1518.      method Money::setCents(*self,c)
  1519.      {
  1520.              replace(parent(*self),c);
  1521.      }
  1522.  
  1523.      /*
  1524.              return the number of dollars in self
  1525.      */
  1526.      method Money::dollars(self)
  1527.      {
  1528.              return(self/100);
  1529.      }
  1530.  
  1531.      /*
  1532.              return the number of cents in self
  1533.      */
  1534.      method Money::cents(self)
  1535.      {
  1536.              return(self - (dollars(self)*100));
  1537.      }
  1538.  
  1539.      /*
  1540.              the "asString" method allows a Money variable to be converted
  1541.              to a String and/or printed
  1542.      */
  1543.      method Money::asString(self)
  1544.      {
  1545.              return("$ "+asString(dollars(self))+"."+format(cents(self),"%02d"));
  1546.      }
  1547.  
  1548.      method Int::asMoney(self)
  1549.      {
  1550.              return(new(Money,self));
  1551.      }
  1552.  
  1553.      /*
  1554.              test case
  1555.      */
  1556.      m = new(Money,100);
  1557.      setCents(&m,104);
  1558.  
  1559.  
  1560.                                      - 26 -
  1561.  
  1562.  
  1563.                                                     Chapter 4: dObject Classes
  1564.  
  1565.  
  1566.      ? m;
  1567.      ? asMoney(m+1);
  1568.      ? asMoney(m*10);
  1569.  
  1570.  
  1571.  
  1572.  
  1573.                              5.0 Numeric Classes
  1574.  
  1575.      5.1 Numeric Classes
  1576.  
  1577.      dObject supports three types of  numeric  classes:    Int,  Long,  and
  1578.      Real.   Class  Int  supports  signed  2-byte  integer  values  between
  1579.      -32,768 to 32,767.  Long values are signed 4-byte integer  numbers  in
  1580.      the range  -2147483648  to  2147483647.  Real numbers are 8 bytes long
  1581.      and in the range -1e+307 to 1e+308.  dObject  provides  operators  for
  1582.      performing arithmetic  on Int, Long and Real classes.  For example, to
  1583.      add two integers together to get a third, send the "plus"  message  to
  1584.      the first  integer,  using the second integer as an argument.  This is
  1585.      accomplished in the statement:
  1586.  
  1587.              dObject> n = 1+2;
  1588.              dObject> ? n;
  1589.              3
  1590.  
  1591.  
  1592.      where the variable "n" will be  assigned  the  value  Int  3.  dObject
  1593.      responds  to  the  '+'  (plus),  '-'  (minus), '*' (multiply), and '/'
  1594.      (divide) operators on  both  Int  and  Real  variables.    Mixed  mode
  1595.      arithmetic  is  also  supported  for  calculations  involving Ints and
  1596.      Reals, in  which  case  the  result  is  always  Real.    Mixed   mode
  1597.      arithmetic involving Long values is not supported.
  1598.  
  1599.  
  1600.      A  wide  variety  of  named messages are supplied for numeric classes,
  1601.      including:
  1602.  
  1603.  
  1604.           * max(self,Int), max(self,Real),  max(self,Long)  -  returns
  1605.           max value of self and arg
  1606.  
  1607.           *  min(self,Int),  min(self,Real),  min(self,Long) - returns
  1608.           min value of self and arg
  1609.  
  1610.           * abs(self) - returns absolute value of self (Int or Real)
  1611.  
  1612.           * log(self) - returns log base e of self (Real)
  1613.  
  1614.           * log10(self) - returns log base 10 of self (Real)
  1615.  
  1616.           * sqrt(self) - returns square root of self(Real)
  1617.  
  1618.  
  1619.  
  1620.                                      - 27 -
  1621.  
  1622.  
  1623. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1624.  
  1625.  
  1626.           * sin(self) - returns sine of self (Real, self in radians)
  1627.  
  1628.           * cos(self) - returns cosine of self(Real, self in radians)
  1629.  
  1630.           * tan(self)  -  returns  tangent  of  self  (Real,  self  in
  1631.           radians)
  1632.  
  1633.      Refer   to   the  accompanying  file  "CLASSLIB.DOC"  for  a  complete
  1634.      description of the built-in numeric methods and operators.
  1635.  
  1636.  
  1637.      Of course, you can define new methods for the numeric classes  if  you
  1638.      so choose.    This  example show defining a new method "factorial" for
  1639.      the Long class, which calls itself recursively:
  1640.  
  1641.      /*
  1642.              define a recursive factorial method for the "Long" class
  1643.      */
  1644.      method Long::factorial(self)
  1645.      {
  1646.              if(self <= 1L) return(self);
  1647.              else return(self*factorial(self-1L));
  1648.      }
  1649.  
  1650.      /*
  1651.              calculate some factorials
  1652.      */
  1653.      i = 0;
  1654.      while(i < 10) {
  1655.              ? i," ",factorial(asLong(i));
  1656.              i = i+1;
  1657.      }
  1658.  
  1659.  
  1660.  
  1661.                            6.0 Logical Operations
  1662.  
  1663.      6.1 Logical Operations
  1664.  
  1665.      dObject provides the built-in class  "Logical"  for  representing  the
  1666.      boolean values  of "true" and "false".  dObject also provides built-in
  1667.      operators for a variety of comparison operations between classes  that
  1668.      result in a Logical value:
  1669.  
  1670.  
  1671.      OPERATOR  NAME           CLASS(ES)                DESCRIPTION
  1672.  
  1673.      [eq][eq]  equal          all                      returns true if self
  1674.                                                        and arg are equal
  1675.      !=        not equal      all                      returns true if self
  1676.                                                        and arg are not
  1677.                                                        equal
  1678.  
  1679.  
  1680.                                      - 28 -
  1681.  
  1682.  
  1683.                                                  Chapter 6: Logical Operations
  1684.  
  1685.  
  1686.      >         greater than   Int,Real,Char,String     returns true if self
  1687.                                                        greater than arg
  1688.      >=        greater than/eqInt,Real,Char,String     returns true if self
  1689.                                                        greater than  or
  1690.                                                        equal to arg
  1691.      <         less than      Int,Real,Char,String     returns true if self
  1692.                                                        less than arg
  1693.      <=        less than/eq   Int,Real,Char,String     returns true if self
  1694.                                                        less than or  equal
  1695.                                                        to arg
  1696.  
  1697.      To  create  a  logical  value, use the "new" method, a literal Logical
  1698.      value, or make an assignment using one  of  the  comparison  operators
  1699.      above:
  1700.  
  1701.              dObject> l = new(Logical);
  1702.              dObject> l = T;
  1703.              dObject> l = 1 < 2;
  1704.  
  1705.  
  1706.  
  1707.                          7.0 Characters and Strings
  1708.  
  1709.      7.1 Characters and Strings
  1710.  
  1711.      dObject   provides  the  built-in  classes  "Char"  and  "String"  for
  1712.      handling character calculations.  A Char literal should  be  a  single
  1713.      character  surrounded  by single quotes, while a String literal can be
  1714.      any number of characters delimited by the double quote character.
  1715.  
  1716.  
  1717.      To create a string, use the "new" method or make an  assignment  using
  1718.      a literal:
  1719.  
  1720.              dObject> s = new(String);
  1721.              dObject> s2 = "this is a string";
  1722.  
  1723.  
  1724.      To find the length of a String, use the "len" method:
  1725.  
  1726.              dObject> ? len(String);
  1727.              16
  1728.  
  1729.  
  1730.      Strings  respond  to the normal set of comparison operators (==,!=, <,
  1731.      <=,>, >=).  Trailing blanks can  be  removed  from  a  String  by  the
  1732.      "trim" method:
  1733.  
  1734.              dObject> ?  len(trim("aaa "));
  1735.              3
  1736.  
  1737.  
  1738.  
  1739.  
  1740.                                      - 29 -
  1741.  
  1742.  
  1743. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1744.  
  1745.  
  1746.      Strings can be concatenated together using the "+" operator:
  1747.  
  1748.              dObject> a = "string1";
  1749.              dObject> b = "string2";
  1750.              dObject> ? a + " and " + b;
  1751.              "string1 and string2"
  1752.  
  1753.  
  1754.      To access a particular character in a String, use the "at" method:
  1755.  
  1756.              dObject> c = at("test",2);
  1757.              dObject> ? c;
  1758.              e
  1759.  
  1760.  
  1761.      The  same  built-in  text editor that is used by the "edit" command to
  1762.      edit text files is callable as a method of the  String  class.    This
  1763.      causes  the contents of the string to be edited in the current window,
  1764.      and returns the value of the edited string.  For a  read-only  display
  1765.      of  the string contents in the current window with no editing allowed,
  1766.      use the "display" method:
  1767.  
  1768.              dObject> s = "this is a string";
  1769.              dObject> edited_string = edit(s);
  1770.              dObject> display(edited_string);
  1771.  
  1772.  
  1773.      dObject also provides String methods to interface directly  with  DOS.
  1774.      A  DOS  command  within  a  String  can be executed using the "system"
  1775.      method, passing it the command string in the "self"  argument  and  an
  1776.      Int  indicator  for  resetting the screen to the state it was in prior
  1777.      to executing the command string (0=do not reset, 1=reset):
  1778.  
  1779.              dObject> cmd = "dir *.do";
  1780.              dObject> system(cmd,0);
  1781.  
  1782.  
  1783.      The value of a DOS environment variable can be  accessed  through  the
  1784.      "envSymbol" method:
  1785.  
  1786.              dObject> s = envSymbol("path");
  1787.  
  1788.  
  1789.      A named file can be edited using the "editFile" method:
  1790.  
  1791.              dObject> editFile("test.txt");
  1792.  
  1793.  
  1794.      The  contents  of  an existing DOS file can be placed in a String very
  1795.      quickly by the "fileString" method, where "self" is the  name  of  the
  1796.      file:
  1797.  
  1798.  
  1799.  
  1800.                                      - 30 -
  1801.  
  1802.  
  1803.                                              Chapter 7: Characters and Strings
  1804.  
  1805.  
  1806.              dObject> text = fileString("test.do");
  1807.              dObject> edit(text);
  1808.  
  1809.  
  1810.      String  values can be converted to Int, Real, Date, and Logical values
  1811.      using  the  "asInt",  "asReal",  "asDate",  and  "asLogical"   methods
  1812.      respectively:
  1813.  
  1814.              dObject> s = "123";
  1815.              dObject> ? class(asInt(s))," ",asInt(s);
  1816.              Int 123
  1817.  
  1818.  
  1819.      String  values  can  be  forced  to  upper  or  lower  case  using the
  1820.      "asUpper" and "asLower" methods:
  1821.  
  1822.              dObject> s = "This is a Test";
  1823.              dObject> ? asUpper(s);
  1824.              THIS IS A TEST
  1825.              dObject> ? asLower(s)
  1826.              this is a test
  1827.  
  1828.  
  1829.      dObject provides a  pattern  match  function  in  the  String::match()
  1830.      method.   This method matches a pattern against the string and returns
  1831.      a Int index specifying the portion of  the  string  that  matched  the
  1832.      pattern:
  1833.  
  1834.              dObject> s = "This is a test";
  1835.              dObject> ? match(s,"is a test");
  1836.              6
  1837.  
  1838.  
  1839.      The  special  codes  recogized by the String::match() method are those
  1840.      recognized by the UNIX GREP utility and include:
  1841.  
  1842.  
  1843.           * ' start-of-line anchor
  1844.  
  1845.           * '$' end-of-line anchor
  1846.  
  1847.           * '.' matches any character
  1848.  
  1849.           * '[' start a character class
  1850.  
  1851.           * ']' end a character class
  1852.  
  1853.           * ' negates character class if 1st char
  1854.  
  1855.           * '*' Keene closure (matches 0 or more)
  1856.  
  1857.           * '+' positive closure (1 or more)
  1858.  
  1859.  
  1860.                                      - 31 -
  1861.  
  1862.  
  1863. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1864.  
  1865.  
  1866.           * '?' optional closure (0 or more)
  1867.  
  1868.      There are other String methods provided by dObject that are  described
  1869.      in CLASSLIB.DOC.
  1870.  
  1871.  
  1872.  
  1873.                                   8.0 Dates
  1874.  
  1875.      8.1 Dates
  1876.  
  1877.      dObject  provides  a  rich set of methods for handling dates using the
  1878.      built-in "Date" class.  To create a new date variable, use  the  "new"
  1879.      method, or a date literal:
  1880.  
  1881.              dObject> d = new(Date);
  1882.              dObject> d = 5/1/91;
  1883.  
  1884.  
  1885.  
  1886.      The  built  in Nil::date() method returns the current system date as a
  1887.      Date variable.
  1888.  
  1889.  
  1890.      You can access the month, day, and year parts  of  a  date  using  the
  1891.      "month", "day",  "year",  and  "century"  methods.    For example, the
  1892.      expression below will return just the year of the current date  as  an
  1893.      Int:
  1894.  
  1895.              dObject> ? year(date());
  1896.  
  1897.  
  1898.      You  can  also  set  the  values  of these parts of the date using the
  1899.      "setMonth", "setDay", "setYear", and "setCentury" methods:
  1900.  
  1901.              dObject> d = date();
  1902.              dObject> d = setMonth(d,1);
  1903.  
  1904.  
  1905.      dObject supports the addition and subtraction of an integer number  of
  1906.      days  to  and  from  a  Date variable, and also supports conversion of
  1907.      Dates to a julian value.  For example, to find the  date  that  is  30
  1908.      days from the current date:
  1909.  
  1910.              dObject> future_date = date()+30;
  1911.  
  1912.  
  1913.      The  "asJulian"  method  returns  a Real value that is the julian date
  1914.      for a Date value.    The  Real::asDate  method  performs  the  inverse
  1915.      operation, returning a Date for a given julian number:
  1916.  
  1917.              dObject> j = asJulian(date());
  1918.              dObject> d = asDate(j);
  1919.  
  1920.  
  1921.                                      - 32 -
  1922.  
  1923.  
  1924.                                                               Chapter 8: Dates
  1925.  
  1926.  
  1927.      Dates  can be formatted into and from String variables in a variety of
  1928.      formats, including  international  formats.    dObject  provides   the
  1929.      "asString"  method  for the Date class and the "asDate" method for the
  1930.      String class to accomplish these format conversions.  In both cases  a
  1931.      format  String  is  passed to the method indicating how the date is to
  1932.      be formatted or scanned:
  1933.  
  1934.      /*
  1935.              test the dObject date conversion functions
  1936.      */
  1937.      ? date();
  1938.      s = asString(date(),"MMM DD/YY");
  1939.      ? s;
  1940.      d = asDate(s,"MMM DD/YY");
  1941.      ? d;
  1942.  
  1943.  
  1944.      The valid date format codes recognized by dObject are:
  1945.  
  1946.           * CC 2-digit century
  1947.  
  1948.           * YY 2-digit year
  1949.  
  1950.           * MM 2-digit month
  1951.  
  1952.           * MMM 3-char month (JAN, FEB, etc.)
  1953.  
  1954.           * DD 2-digit day
  1955.  
  1956.      These codes can be used in format strings to  indicate  how  the  date
  1957.      should be  formatted  or  scanned.    For  example,  the following are
  1958.      typical date formats:
  1959.  
  1960.           * YY.MM.DD
  1961.  
  1962.           * CCYY.MM.DD
  1963.  
  1964.           * MM/DD/YY
  1965.  
  1966.           * DD-MM/YY
  1967.  
  1968.           * DD-MM/CCYY
  1969.  
  1970.           * MMM DD/YY
  1971.  
  1972.      As a final example, the following code implements the  "cday"  method,
  1973.      which  returns  a  String  that  contains  the name of the day for the
  1974.      date:
  1975.  
  1976.      /*
  1977.              this is an example of how to define methods for the built-in
  1978.              Date class
  1979.  
  1980.  
  1981.                                      - 33 -
  1982.  
  1983.  
  1984. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1985.  
  1986.  
  1987.              "cday" returns a character string naming the day
  1988.      */
  1989.      method Date::cday(self)
  1990.      {
  1991.              if(dow(self) == 1) return("Sunday");
  1992.              if(dow(self) == 2) return("Monday");
  1993.              if(dow(self) == 3) return("Tuesday");
  1994.              if(dow(self) == 4) return("Wednesday");
  1995.              if(dow(self) == 4) return("Thursday");
  1996.              if(dow(self) == 5) return("Friday");
  1997.              if(dow(self) == 6) return("Saturday");
  1998.      }
  1999.  
  2000.  
  2001.      /*
  2002.              define the same function, using the "switch" statement
  2003.      */
  2004.      method Date::cday2(self)
  2005.      {
  2006.              switch(dow(self)) {
  2007.                      case 1:    return("Sunday");
  2008.                      case 2:    return("Monday");
  2009.                      case 3:    return("Tuesday");
  2010.                      case 4:    return("Wednesday");
  2011.                      case 5:    return("Thursday");
  2012.                      case 6:    return("Friday");
  2013.                      case 7:    return("Saturday");
  2014.              }
  2015.      }
  2016.  
  2017.      /*
  2018.              call the methods defined above
  2019.      */
  2020.      ? cday(date());
  2021.      ? cday2(date());
  2022.  
  2023.  
  2024.  
  2025.                             9.0 Windows and Menus
  2026.  
  2027.      dObject provides classes that allow you to write  professional-looking
  2028.      applications that  use  character-cell  windows and pop-up menus.  The
  2029.      "?" command, the "say" method of the Window class,  and  the  built-in
  2030.      "Field" base class all send their output to a specified window.
  2031.  
  2032.  
  2033.      9.1 Windows
  2034.  
  2035.      Windows  are created using the "new" method, and passing it the window
  2036.      number, window attribute, frame  attribute,  title,  left  corner  y,x
  2037.      position, and  the  y and x lengths for the window as parameters.  The
  2038.      x,y co-ordinates of a window or  other  object  within  a  window  are
  2039.  
  2040.  
  2041.                                      - 34 -
  2042.  
  2043.  
  2044.                                                   Chapter 9: Windows and Menus
  2045.  
  2046.  
  2047.      always  counted down and right from the (0,0) origin in the upper left
  2048.      corner.  For example, to create a new window that is the size  of  the
  2049.      entire  screen,  contains  the title "test window", and has a white on
  2050.      blue display color and a lite blue border:
  2051.  
  2052.              dObject> w = new(Window,1,31,3,"test window",0,0,24,80);
  2053.  
  2054.  
  2055.      Color attributes can be calculated from the following formula:
  2056.  
  2057.           * Choose one foreground color and one background color
  2058.  
  2059.           * Add the corresponding integer values below.
  2060.  
  2061.           * Add 128 if  you  want  whatever  is  displayed  with  that
  2062.           attribute to blink
  2063.  
  2064.      BACKGROUND               FOREGROUND
  2065.  
  2066.      Black          0         Black          0
  2067.      Blue           16        Blue           1
  2068.      Green          32        Green          2
  2069.      Cyan           48        Cyan           3
  2070.      Red            64        Red            4
  2071.      Magenta        80        Magenta        5
  2072.      Brown          96        Brown          6
  2073.      White          112       White          7
  2074.      Grey           8
  2075.      Light Blue     24
  2076.      Light Green    40
  2077.      Light Red      72
  2078.      Light Magenta  88
  2079.      Yellow         104
  2080.      White (High    120
  2081.      Intensity)
  2082.  
  2083.      You  can  also  include  the  supplied  file  "COLORS.DO" that defines
  2084.      symbolic names for the colors.
  2085.  
  2086.  
  2087.      When  the  "new"  method  creates  the  window  it  also  displays  it
  2088.      immediately  and  makes  the  new  window the current window. To write
  2089.      output to a window, you must first make the window current.   You  can
  2090.      do this explicitly by sending the window the "shiftwindow" message:
  2091.  
  2092.              dObject> shiftwindow(w);
  2093.  
  2094.  
  2095.      You  can always obtain the current window as a Window object through a
  2096.      call to the Nil::currentWindow() method:
  2097.  
  2098.              dObject> shiftwindow(currentWindow());
  2099.  
  2100.  
  2101.                                      - 35 -
  2102.  
  2103.  
  2104. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2105.  
  2106.  
  2107.      You can clear the contents of a window with the "clear" message.    To
  2108.      remove a window from the screen, send it the "remove" message:
  2109.  
  2110.              dObject> remove(w);
  2111.  
  2112.  
  2113.      To  interactively  resize  or  setup  the  color for a window, use the
  2114.      "resize" and  "setupColor"  methods.     These   methods   allow   for
  2115.      interactive  resizing  and  color  setup  using  the cursor keys and a
  2116.      color  display  that  shows  the  foreground  and  background   colors
  2117.      available as  well  as the color attribute number.  When interactively
  2118.      resizing a window, use the  following  keys  to  change  the  window's
  2119.      size:
  2120.  
  2121.  
  2122.           *  Width  -  Press  the  left  arrow  key to make the window
  2123.           narrower or the right arrow key to make it wider.   To  make
  2124.           changes  in larger increments, hold down the Ctrl key at the
  2125.           same time.  Use the end key to  expand  the  window  at  the
  2126.           start of the screen.
  2127.  
  2128.           *  Length  -  Press the up arrow key to decrease or the down
  2129.           arrow key to increase the length of the  window.    Use  the
  2130.           page  down  key  to  extend  the window to the bottom of the
  2131.           screen and the page up key to extend the window to  the  top
  2132.           of the screen.
  2133.  
  2134.      To  change the position of the window on the screen, use the following
  2135.      keys:
  2136.  
  2137.           * Shift-Up Up one row
  2138.  
  2139.           * Shift-Down Down one row
  2140.  
  2141.           * Shift-Right Right one column
  2142.  
  2143.           * Shift-left Left one column
  2144.  
  2145.           * Shift-Home To left screen edge
  2146.  
  2147.           * Shift-End To right screen edge
  2148.  
  2149.           * Shift-PgUp To top of screen
  2150.  
  2151.           * Shift-PgDn To bottom of screen
  2152.  
  2153.           * Ctrl-Home To top left screen corner
  2154.  
  2155.           * Ctrl-End To bottom left screen corner
  2156.  
  2157.           * Ctrl-PgUp To top right screen corner
  2158.  
  2159.  
  2160.  
  2161.                                      - 36 -
  2162.  
  2163.  
  2164.                                                   Chapter 9: Windows and Menus
  2165.  
  2166.  
  2167.           * Ctrl-PgDn To bottom right screen corner
  2168.  
  2169.      To setup the color for the window text, pass the setupColor method  an
  2170.      Int argument  of  0;   to setup the color of the frame, pass it an Int
  2171.      argument of 1.  For  example,  the  following  statement  invokes  the
  2172.      setup display for the color of the current window:
  2173.  
  2174.              dObject> setupColor(currentWindow(),0);
  2175.  
  2176.  
  2177.      dObject   creates  windows  with  a  default  frame  consisting  of  a
  2178.      single-width line border, and with the  window  title  centered  above
  2179.      the  window  in the border. to change this, you can use the "setFrame"
  2180.      message.  The first argument to setFrame is  the  color  attribute  of
  2181.      the  frame,  followed  by the title of the frame, the integer position
  2182.      to place the title counting from the left-hand  side  (a  value  of  0
  2183.      instructs   dObject  to  center  the  title),  and  finally  a  String
  2184.      containing 6 characters  to  build  frame  with  using  the  following
  2185.      convention:
  2186.  
  2187.           * 1st char:  Upper left corner
  2188.  
  2189.           * 2nd char:  Upper right corner
  2190.  
  2191.           * 3rd char:  Lower left corner
  2192.  
  2193.           * 4th char:  Lower right corner
  2194.  
  2195.           * 5th char:  Horizontal line
  2196.  
  2197.           * 6th char:  Vertical line
  2198.  
  2199.      For  example, to frame a window with the title "My Window" starting at
  2200.      position 3, with a white frame and a the '#' character for  a  border,
  2201.      use the message:
  2202.  
  2203.              dObject> setFrame(w,7,"My Window",3,"######");
  2204.  
  2205.  
  2206.      9.2 Output using SAY and GET
  2207.  
  2208.      dObject  provides  methods  to build full-screen data entry and review
  2209.      forms through the Int::say() and Window::say()  methods,  and  through
  2210.      the built-in  Field  base  class.   The SAY/GET facility in dObject is
  2211.      similar in function to the @ say and @ get commands  provided  by  the
  2212.      DBASE language.    In  dObject  these  methods  work  within a window,
  2213.      providing a way to create very sophisticated data handling forms.
  2214.  
  2215.  
  2216.      To produce output from an expression at a y,x point within  a  window,
  2217.      send  the  window  the  Int  y  coordinate,  the Int x coordinate, the
  2218.      expression to output, an Int length of the field to  display,  and  an
  2219.  
  2220.  
  2221.                                      - 37 -
  2222.  
  2223.  
  2224. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2225.  
  2226.  
  2227.      Int color attribute to display the expression in:
  2228.  
  2229.              dObject> say(currentWindow(),5,5,"this is a test",14,7);
  2230.  
  2231.  
  2232.      To  set  up  a  get  field for input, call the Exp::new method for the
  2233.      class "Field", and send it the Window to place the field in,  the  Int
  2234.      y  coordinate,  the Int x coordinate, a String name of the variable to
  2235.      place the result into, an Int length of the field to display, and  Int
  2236.      color attribute.    Make  sure  that  the  variable you will store the
  2237.      value into is already defined:
  2238.  
  2239.              dObject> a = "this is a test";
  2240.              dObject> new(Field,currentWindow(),6,6,"a",14,112);
  2241.  
  2242.  
  2243.      Alternatively, the field name can be the name of a DBASE field in  the
  2244.      currently active DBF file:
  2245.  
  2246.              dObject> db = new(Dbffile,"patient");
  2247.              dObject> new(Field,currentWindow(),6,6,"lname",14,112);
  2248.  
  2249.  
  2250.      The  Exp::new(Field,...)  method returns a variable of type Field that
  2251.      represents the field within the window.  Once defined, a list  of  get
  2252.      variables   can  be  read  in  a  full-screen  input  mode  using  the
  2253.      Window::read() method:
  2254.  
  2255.              dObject> read(currentWindow());
  2256.  
  2257.  
  2258.      Entering this mode causes  dObject  to  position  the  cursor  at  the
  2259.      beginning  of the first get field defined, and to wait for the user to
  2260.      enter new values for data fields and scroll  through  records  in  the
  2261.      current Dbffile.  The specific keys recognized are:
  2262.  
  2263.  
  2264.      KEY       ACTION         DESCRIPTION
  2265.  
  2266.      Esc       Escape         exits the form and returns to dObject>
  2267.                               prompt
  2268.      Home      Goto top       Positions the current DBF file at the
  2269.                               first record and displays it
  2270.      End       Goto bottom    Positions the current DBF file at the
  2271.                               last record and displays it
  2272.      PgUp      Prev  Record   Positions the current DBF file at the
  2273.                               previous record and displays it
  2274.      PgDn      Next Record    Positions the current DBF file at the
  2275.                               next record and displays it
  2276.      Tab       Next Field     Positions the cursor at the beginning of
  2277.                               the next display field
  2278.      Up        Up cursor      Positions the cursor up one line
  2279.  
  2280.  
  2281.                                      - 38 -
  2282.  
  2283.  
  2284.                                                   Chapter 9: Windows and Menus
  2285.  
  2286.  
  2287.      Down      Down cursor    Positions the cursor down one line
  2288.      Right     Right cursor   Positions the cursor right one space
  2289.                               within current display field
  2290.      Left      Left cursor    Positions the cursor left one space
  2291.                               within the current display field
  2292.      F10       Quit           exits the form and returns to dObject>
  2293.                               prompt
  2294.  
  2295.      You  can  modify  the  actions  associated with these or any other key
  2296.      while in read mode by calling the Int::onKey() method and  passing  it
  2297.      an expression  to  evaluate.  For example, the following example shows
  2298.      how to call the built-in text editor to edit the  contents  of  a  GET
  2299.      field by pressing the F8 key while in read mode:
  2300.  
  2301.  
  2302.      /*
  2303.              this method implements a callable text editor for the contents of
  2304.              a field
  2305.      */
  2306.      method Window::myEdit(self)
  2307.      {
  2308.              f = currentField(self);
  2309.              s = eval(asId(name(f)));
  2310.              if(class(s) == "String") {
  2311.                      w = new(Window,1,31,3,name(f),5,5,10,40);
  2312.                      display(s);
  2313.                      remove(w);
  2314.                      gotoField(self,f);
  2315.              }
  2316.      }
  2317.  
  2318.      db = new(Dbffile,"patient");
  2319.      new(Field,currentWindow(),6,6,"lname",14,112);
  2320.      onKey(w,F8,#myEdit(w));
  2321.      read(currentWindow());
  2322.  
  2323.  
  2324.      To  clear  the  existing  list of get variables from future reads, use
  2325.      the Window::clearGets() method:
  2326.  
  2327.              dObject> clearGets(currentWindow());
  2328.  
  2329.  
  2330.      The following example program shows setting up  two  get  fields  with
  2331.      prompts:
  2332.  
  2333.      /*
  2334.              sample full screen field output
  2335.      */
  2336.      w = new(Window,1,31,3,"",0,0,24,80);
  2337.      clearGets(2);
  2338.      a = "test";
  2339.  
  2340.  
  2341.                                      - 39 -
  2342.  
  2343.  
  2344. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2345.  
  2346.  
  2347.      b = "test2";
  2348.      say(w,5,5,"field a",7,7);
  2349.      say(w,6,5,"field b",7,7);
  2350.      new(Field,w,5,20,"a",10,112);
  2351.      new(Field,w,6,20,"b",10,112);
  2352.      read(w);
  2353.      remove(w);
  2354.  
  2355.  
  2356.      9.3 Pictures
  2357.  
  2358.      You  can  assign  a  picture  template  to a GET field that will cause
  2359.      dObject to  format  the  value  being  displayed  in  the  field,  and
  2360.      validate keystrokes  upon  entry to the field.  Do this by calling the
  2361.      Field::setPicture() method, and passing it  a  String  containing  the
  2362.      picture:
  2363.  
  2364.  
  2365.              dObject> a = "test";
  2366.              dObject> f = new(Field,w,5,20,"a",10,112);
  2367.              dObject> setPicture(f,"!!!!!!!!!!");
  2368.  
  2369.  
  2370.      dObject recognizes the following picture code characters:
  2371.  
  2372.           * !    -   Converts  letters  to  uppercase;    accepts  all
  2373.           characters
  2374.  
  2375.           * A - Allows letters only
  2376.  
  2377.           * L - Translates characters to logical values (T, t,  F,  f,
  2378.           Y, y, N, n)
  2379.  
  2380.           * N - Allows letters and numbers
  2381.  
  2382.           * 9 - Allows digits only
  2383.  
  2384.           *  X  -  Allows  numbers,  spaces, signs, and decimal points
  2385.           only
  2386.  
  2387.           * Other characters are copied literally into  the  displayed
  2388.           value
  2389.  
  2390.      The following example demonstrates the use of picture clauses:
  2391.  
  2392.  
  2393.      /*
  2394.              demonstrate the use of a picture within a GET field
  2395.      */
  2396.      w = currentWindow();
  2397.      clearGets(w);
  2398.      cls;
  2399.  
  2400.  
  2401.                                      - 40 -
  2402.  
  2403.  
  2404.                                                   Chapter 9: Windows and Menus
  2405.  
  2406.  
  2407.      a = "test";
  2408.      prompt = "Enter a value: ";
  2409.      say(w,5,5,prompt,len(prompt),7);
  2410.      f = new(Field,w,5,len(prompt)+5,"a",10,112);
  2411.      setPicture(f,"!!!!!!!!!!");
  2412.      read(w);
  2413.      ? "the value you entered was ",a;
  2414.  
  2415.  
  2416.      9.4 Key Codes
  2417.  
  2418.      The   special   key   codes   recognized  by  the  Window::read()  and
  2419.      Nil::inkey() methods are defined in the supplied file  KEYDEF.DO  (you
  2420.      can  include  this file in programs by using the #include preprocessor
  2421.      statement):
  2422.  
  2423.      #define   BACK_SPACE   "$08"
  2424.      #define   TAB          "$09"
  2425.      #define   ESC          "$1B"
  2426.      #define   CTRL_A       "$01"
  2427.      #define   CTRL_B       "$02"
  2428.      #define   CTRL_C       "$03"
  2429.      #define   CTRL_D       "$04"
  2430.      #define   CTRL_E       "$05"
  2431.      #define   CTRL_F       "$06"
  2432.      #define   CTRL_G       "$07"
  2433.      #define   CTRL_H       "$08"
  2434.      #define   CTRL_I       "$09"
  2435.      #define   CTRL_J       "$0A"
  2436.      #define   CTRL_K       "$0B"
  2437.      #define   CTRL_L       "$0C"
  2438.      #define   CTRL_M       "$0D"
  2439.      #define   CTRL_N       "$0E"
  2440.      #define   CTRL_O       "$0F"
  2441.      #define   CTRL_P       "$10"
  2442.      #define   CTRL_Q       "$11"
  2443.      #define   CTRL_R       "$12"
  2444.      #define   CTRL_S       "$13"
  2445.      #define   CTRL_T       "$14"
  2446.      #define   CTRL_U       "$15"
  2447.      #define   CTRL_V       "$16"
  2448.      #define   CTRL_W       "$17"
  2449.      #define   CTRL_X       "$18"
  2450.      #define   CTRL_Y       "$19"
  2451.      #define   CTRL_Z       "$1A"
  2452.      #define   RETURN       "$D"
  2453.      #define   HOME         "$4700"
  2454.      #define   END          "$4F00"
  2455.      #define   PGUP         "$4900"
  2456.      #define   PGDN         "$5100"
  2457.      #define   UP           "$4800"
  2458.      #define   DOWN         "$5000"
  2459.  
  2460.  
  2461.                                      - 41 -
  2462.  
  2463.  
  2464. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2465.  
  2466.  
  2467.      #define   RIGHT        "$4D00"
  2468.      #define   LEFT         "$4B00"
  2469.      #define   SHIFT_TAB    "$0F00"
  2470.      #define   INS          "$5200"
  2471.      #define   DEL          "$5300"
  2472.  
  2473.      #define   CTRL_HOME    "$7700"
  2474.      #define   CTRL_END     "$7500"
  2475.      #define   CTRL_PGUP    "$8400"
  2476.      #define   CTRL_PGDN    "$7600"
  2477.      #define   CTRL_RIGHT   "$7400"
  2478.      #define   CTRL_LEFT    "$7300"
  2479.  
  2480.      #define   ALT_1       "$7800"
  2481.      #define   ALT_2       "$7900"
  2482.      #define   ALT_3       "$7A00"
  2483.      #define   ALT_4       "$7B00"
  2484.      #define   ALT_5       "$7C00"
  2485.      #define   ALT_6       "$7D00"
  2486.      #define   ALT_7       "$7E00"
  2487.      #define   ALT_8       "$7F00"
  2488.      #define   ALT_9       "$8000"
  2489.      #define   ALT_0       "$8100"
  2490.      #define   ALT_MINUS   "$8200"
  2491.      #define   ALT_EQUAL   "$8300"
  2492.  
  2493.      #define   ALT_Q       "$1000"
  2494.      #define   ALT_W       "$1100"
  2495.      #define   ALT_E       "$1200"
  2496.      #define   ALT_R       "$1300"
  2497.      #define   ALT_T       "$1400"
  2498.      #define   ALT_Y       "$1500"
  2499.      #define   ALT_U       "$1600"
  2500.      #define   ALT_I       "$1700"
  2501.      #define   ALT_O       "$1800"
  2502.      #define   ALT_P       "$1900"
  2503.  
  2504.      #define   ALT_A       "$1E00"
  2505.      #define   ALT_S       "$1F00"
  2506.      #define   ALT_D       "$2000"
  2507.      #define   ALT_F       "$2100"
  2508.      #define   ALT_G       "$2200"
  2509.      #define   ALT_H       "$2300"
  2510.      #define   ALT_J       "$2400"
  2511.      #define   ALT_K       "$2500"
  2512.      #define   ALT_L       "$2600"
  2513.  
  2514.      #define   ALT_Z       "$2C00"
  2515.      #define   ALT_X       "$2D00"
  2516.      #define   ALT_C       "$2E00"
  2517.      #define   ALT_V       "$2F00"
  2518.      #define   ALT_B       "$3000"
  2519.  
  2520.  
  2521.                                      - 42 -
  2522.  
  2523.  
  2524.                                                   Chapter 9: Windows and Menus
  2525.  
  2526.  
  2527.      #define   ALT_N       "$3100"
  2528.      #define   ALT_M       "$3200"
  2529.  
  2530.      #define   F1           "$3B00"
  2531.      #define   F2           "$3C00"
  2532.      #define   F3           "$3D00"
  2533.      #define   F4           "$3E00"
  2534.      #define   F5           "$3F00"
  2535.      #define   F6           "$4000"
  2536.      #define   F7           "$4100"
  2537.      #define   F8           "$4200"
  2538.      #define   F9           "$4300"
  2539.      #define   F10          "$4400"
  2540.  
  2541.      #define   CTRL_F1      "$5E00"
  2542.      #define   CTRL_F2      "$5F00"
  2543.      #define   CTRL_F3      "$6000"
  2544.      #define   CTRL_F4      "$6100"
  2545.      #define   CTRL_F5      "$6200"
  2546.      #define   CTRL_F6      "$6300"
  2547.      #define   CTRL_F7      "$6400"
  2548.      #define   CTRL_F8      "$6500"
  2549.      #define   CTRL_F9      "$6600"
  2550.      #define   CTRL_F10     "$6700"
  2551.  
  2552.      #define   SHIFT_F1     "$5400"
  2553.      #define   SHIFT_F2     "$5500"
  2554.      #define   SHIFT_F3     "$5600"
  2555.      #define   SHIFT_F4     "$5700"
  2556.      #define   SHIFT_F5     "$5800"
  2557.      #define   SHIFT_F6     "$5900"
  2558.      #define   SHIFT_F7     "$5A00"
  2559.      #define   SHIFT_F8     "$5B00"
  2560.      #define   SHIFT_F9     "$5C00"
  2561.      #define   SHIFT_F10    "$5D00"
  2562.  
  2563.      #define   ALT_F1       "$6800"
  2564.      #define   ALT_F2       "$6900"
  2565.      #define   ALT_F3       "$6A00"
  2566.      #define   ALT_F4       "$6B00"
  2567.      #define   ALT_F5       "$6C00"
  2568.      #define   ALT_F6       "$6D00"
  2569.      #define   ALT_F7       "$6E00"
  2570.      #define   ALT_F8       "$6F00"
  2571.      #define   ALT_F9       "$7000"
  2572.      #define   ALT_F10      "$7100"
  2573.  
  2574.  
  2575.      9.5 Menus
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.                                      - 43 -
  2582.  
  2583.  
  2584. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2585.  
  2586.  
  2587.      dObject provides a pop-up menu  facility  in  the  built-in  Menu  and
  2588.      Linemenu classes.    Menus are created by passing the "new" method the
  2589.      Int y,x location of the upper left corner of the menu, the Int  length
  2590.      of  the  menu  (number of lines to show), the Int text and frame color
  2591.      attributes, a Collection of menu choices, and a String title.    Menus
  2592.      are  executed  using  the  "choice"  method containing an Int argument
  2593.      that specifies what choice to highlight upon entry to the menu.    The
  2594.      "choice"  method  returns the index of the menu item chosen within the
  2595.      Collection;  the calling program can retrieve the actual value  chosen
  2596.      by indexing the Collection with the "at" method.
  2597.  
  2598.      Menus  remain  displayed  in  the  current  Window  until the "remove"
  2599.      message is sent to them.  The following example  shows  putting  up  a
  2600.      menu of numeric values and asking the user to choose:
  2601.  
  2602.      /*
  2603.              create a menu using a Collection of choices
  2604.      */
  2605.      myCollection = [1.0,2.0,3,4,5,6,7,8,9];
  2606.      a= new(Menu,3,3,5,31,3,myCollection," test ");
  2607.      b = choice(a,1);
  2608.      remove(a);
  2609.      ? "result of menu is ",b;
  2610.  
  2611.      /*
  2612.              the actual value chosen is found by getting the value
  2613.              in the collection at index "b"
  2614.      */
  2615.      value = at(myCollection,b);
  2616.  
  2617.  
  2618.      To  exit the menu without making a choice, press the ESC key while the
  2619.      menu is active.  This causes the Menu::choice() method to return 0  as
  2620.      the chosen value.
  2621.  
  2622.  
  2623.      The  number  of  values in the Collection in a Menu can be much larger
  2624.      than the display size of the Menu.  When this  occurs,  the  user  can
  2625.      press  the  up  and  down arrow keys to scroll through the menu before
  2626.      making a choice with the "Enter" key.
  2627.  
  2628.  
  2629.  
  2630.      9.6 Line Menus
  2631.  
  2632.      dObject also provides a "Linemenu" class that  implements  lotus-style
  2633.      line menus  with  optional  help  lines.    You can create a line menu
  2634.      using the "new" method, and passing it the Int window  number  of  the
  2635.      window  to  create  for  the menu, an Int row and column for the upper
  2636.      left corner of the menu, an Int width of the  menu,  a  Collection  of
  2637.      values  to  put  in the menu, and a corresponding Collection of status
  2638.      lines to show for each menu choice.  When  the  menu  is  created  and
  2639.  
  2640.  
  2641.                                      - 44 -
  2642.  
  2643.  
  2644.                                                   Chapter 9: Windows and Menus
  2645.  
  2646.  
  2647.      shown  using the Linemenu::choice() method, the choices will be evenly
  2648.      spaced across the width of the menu in the first  line  of  the  menu,
  2649.      and  the  status line text for a given choice will be displayed on the
  2650.      second line, much  like  the  style  of  a  Lotus  1-2-3  menu.    The
  2651.      following example illustrates the use of the Linemenu class:
  2652.  
  2653.  
  2654.      /*
  2655.              demo of the Linemenu class
  2656.      */
  2657.      color = 54;
  2658.      width = 40;
  2659.      m = new(Linemenu,1,5,width,color,color,[1,2,3,4,5,6],
  2660.              ["first","second","third","fourth","fifth","sixth"]);
  2661.      c = choice(m);
  2662.      remove(m);
  2663.      ? "your choice was ",c;
  2664.  
  2665.  
  2666.      You  can  create  a  Linemenu  that  does  not  display  status  lines
  2667.      underneath the choices by passing an empty  Collection  to  "new"  for
  2668.      the status line text.  In this case a one-line menu will be created:
  2669.  
  2670.  
  2671.              m = new(Linemenu,1,5,5,54,54,[1,2,3,4,5,6],[]);
  2672.  
  2673.  
  2674.      9.7 Hypertext
  2675.  
  2676.      dObject  provides  the  capability  to  use the Window class described
  2677.      above to display hypertext built from DBASE data and index files.   To
  2678.      build  a  hypertext  string  that can be displayed or edited using the
  2679.      built-in text editor, use the Dbffile::htExpand() method.  The  "self"
  2680.      argument  to  this  method  is a Dbffile object that contains at least
  2681.      two text fields:  one field containing a one-word  topic  string,  and
  2682.      one  field containing the text to show whenever that topic is selected
  2683.      from within a display.    For  example,  the  supplied  dObject  files
  2684.      HELP.DBF,  HELP.DBT, and HELP.NDX are DBASE files that are used as the
  2685.      dictionary for the on-line help within the  text  editor  and  are  an
  2686.      example of suitable hypertext files:
  2687.  
  2688.              dObject> db = new(Dbffile,"help");
  2689.              dObject> displayStructure(db);
  2690.              Structure for:             HELP.DBF
  2691.              Number of records: 8
  2692.              Last update:               6/2/91
  2693.              Version:                   3
  2694.              Number of fields:  2
  2695.              Field              Field Name      Type    Width   Dec
  2696.              0          TOPIC           C           8       0
  2697.              1          TEXT            M          10       0
  2698.  
  2699.  
  2700.  
  2701.                                      - 45 -
  2702.  
  2703.  
  2704. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2705.  
  2706.  
  2707.      You  must  also  pass  an  Ndxfile object that is a DBASE index on the
  2708.      topic field, a String name of the text field to  use  in  the  Dbffile
  2709.      for  the text to show for a topic, an Int color to highlight the words
  2710.      in the string being converted that have topic entries in the  Dbffile,
  2711.      and a  String  containing  the  text to convert.  The method returns a
  2712.      String containing embedded control codes telling the  built-in  editor
  2713.      to highlight  the  topic  words  in  the  color  you have chosen.  The
  2714.      following example illustrates the proper calling sequence:
  2715.  
  2716.              dObject> db = new(Dbffile,"help");
  2717.              dObject> ndx = useIndex(db,"help");
  2718.              dObject> keylen = 32; % length of the topic field
  2719.              dObject> htext = htExpand(db,ndx,"text",31,keylen,
  2720.                      "this is some text");
  2721.  
  2722.  
  2723.      To  display  the  hypertext  within  the  current  window,   use   the
  2724.      String::display() method:
  2725.  
  2726.              dObject> display(htext);
  2727.  
  2728.  
  2729.      Calling  this  method  will display the text within the current window
  2730.      with words that have matching  entries  in  the  topic  field  of  the
  2731.      Dbffile highlighted  with  the  color attribute chosen above.  You can
  2732.      position the  cursor  using  the  normal  editor  keys,  and  you  can
  2733.      "follow"  the  hypertext link for a highlighed word by positioning the
  2734.      cursor on that word and pressing the CTRL-F1 key.  Pressing  this  key
  2735.      causes  dObject  to  execute  the String::onHyperKey() method with the
  2736.      contents of the "text" field for the  topic  that  was  found  in  the
  2737.      Dbffile.   You should always supply a version of String::onHyperKey as
  2738.      part of your hypertext application;   If  you  do  not,  pressing  the
  2739.      CTRL-F1  key  will have no effect will look for the word at the cursor
  2740.      in the HELP.DBF file.
  2741.  
  2742.  
  2743.      The following example shows how  to  define  the  String::onHyperKey()
  2744.      method  and  build  a  small  hypertext application using the supplied
  2745.      dObject HELP.DBF, HELP.NDX, and HELP.DBT files:
  2746.  
  2747.      /*
  2748.              this is a demo of dObject's hypertext display feature
  2749.              first, define a method to handle the "follow hyper link"
  2750.              key when it is pressed from a window
  2751.      */
  2752.      method String::onHyperKey(self)
  2753.      {
  2754.      /*
  2755.              create a window for the text
  2756.      */
  2757.              w = new(Window,1,31,31,"",8,8,10,40);
  2758.      /*
  2759.  
  2760.  
  2761.                                      - 46 -
  2762.  
  2763.  
  2764.                                                   Chapter 9: Windows and Menus
  2765.  
  2766.  
  2767.              the color attribute is the first character token in the string
  2768.      */
  2769.              color = asInt(token(self,#s));
  2770.      /*
  2771.              turn off the dObject hypertext help key (CTRL-F1) from within
  2772.              the display
  2773.      */
  2774.              set("hyperhelp",F);
  2775.      /*
  2776.              display the text
  2777.              to follow the link for a highlighted field, hit the SHIFT-F8 key
  2778.      */
  2779.              display(htExpand(db,index,"text",32,color,s));
  2780.              remove(w);
  2781.      }
  2782.  
  2783.      /*
  2784.              demo hypertext
  2785.      */
  2786.      #define COLOR 79
  2787.      db = new(Dbffile,"help");
  2788.      index = useIndex(db,"help");
  2789.      w = new(Window,1,31,31," Hypertext ",5,5,10,50);
  2790.      display(htExpand(db,index,"text",COLOR,32,":while for if then else dos"));
  2791.      remove(w);
  2792.      close(db);
  2793.  
  2794.  
  2795.  
  2796.                          10.0 Arrays and Collections
  2797.  
  2798.      10.1 Arrays
  2799.  
  2800.      dObject provides  classes  for  handling  Arrays  and  Collections  of
  2801.      objects.   The primary difference between an Array and a Collection is
  2802.      that a Collection can be considered an ordered  list  of  values  that
  2803.      can  easily be inserted into, appended to , and deleted from, while an
  2804.      Array is similar to a DBASE array that can be easily indexed by a  set
  2805.      of  integer indexes, but not easily ordered, inserted into, or deleted
  2806.      from.  Both Collections and Arrays can contain  any  kind  of  dObject
  2807.      class, including   other   Collections   and  Arrays.    There  is  no
  2808.      pre-defined limit on the size of an Array or Collection, but  attempts
  2809.      to use more memory than is available will cause an error message.
  2810.  
  2811.  
  2812.      Arrays  are  similar  to  those  provided  in  the  DBASE  programming
  2813.      language.  An  array  element  can  be  stored  or  retrieved  from  a
  2814.      specific  location  within  an  array through the use of the "replace"
  2815.      and "at" messages, passing a  Collection  of  integer  indexes  as  an
  2816.      argument.
  2817.  
  2818.  
  2819.  
  2820.  
  2821.                                      - 47 -
  2822.  
  2823.  
  2824. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2825.  
  2826.  
  2827.      For  example,  to  create  an  array of 10 elements and store a String
  2828.      value in the first location:
  2829.  
  2830.              dObject> a = new(Array,[10]);
  2831.              dObject> replace(a,[1],"this is the first element");
  2832.              dObject> ? at(a,[1]);
  2833.              t
  2834.  
  2835.  
  2836.      To create multi-dimensional arrays, create the array  with  more  than
  2837.      one  dimension  in  the dimension Collection, and address it with more
  2838.      than one element in the index Collection:
  2839.  
  2840.              dObject> a = new(Array,[3,3,3]);
  2841.              dObject> replace(a,[1,1,1],"this is the first element");
  2842.  
  2843.  
  2844.      /*
  2845.              this is a test of dObject's Array class
  2846.      */
  2847.      method Array::print(self)
  2848.      {
  2849.              i = 0;
  2850.              while(i < len(self)) {
  2851.                      print(at(self,i));
  2852.                      print(' ');
  2853.                      i = i+1;
  2854.              }
  2855.      }
  2856.  
  2857.      /*
  2858.              create a single-dimension array of 4096 locations
  2859.      */
  2860.      a = new(Array,[4096]);
  2861.      i = 0;
  2862.      while(i < 4096) {
  2863.              replace(a,[i],i);
  2864.              i = i+1;
  2865.      }
  2866.      ? a;
  2867.  
  2868.  
  2869.      10.2 Collections
  2870.  
  2871.      dObject's Collection class provides an advanced way to  store  ordered
  2872.      collections of   objects.      The   Collection  class  comes  with  a
  2873.      comprehensive set of built-in methods for adding,  deleting,  finding,
  2874.      and replacing  members  within  the  collection.  Collections are most
  2875.      easily  created  using  the  literal  convention  of   surrounding   a
  2876.      comma-separated list of literal values with brackets:
  2877.  
  2878.              dObject> myCollection = [1,2,3,4,5];
  2879.  
  2880.  
  2881.                                      - 48 -
  2882.  
  2883.  
  2884.                                             Chapter 10: Arrays and Collections
  2885.  
  2886.  
  2887.      Empty Collections can also be created using the Exp::new() method:
  2888.  
  2889.  
  2890.              dObject> myCollection = new(Collection);
  2891.              dObject> ? myCollection;
  2892.              []
  2893.  
  2894.  
  2895.      As  with  Arrays,  members  of  a  Collection can be any valid dObject
  2896.      class, including other Collections:
  2897.  
  2898.              dObject> myCollection = [[1,2,3],[4,5,6],[7,8,9]];
  2899.  
  2900.  
  2901.      To add a value to the end of a Collection, use the "append" method:
  2902.  
  2903.              dObject> myCollection = [1,2,3];
  2904.              dObject> myCollection = append(myCollection,4);
  2905.              dObject> ? myCollection;
  2906.              [1,2,3,4]
  2907.  
  2908.  
  2909.      To replace an existing value within a Collection,  use  the  "replace"
  2910.      method,  passing it a value to replace and the new value to replace it
  2911.      with:
  2912.  
  2913.              dObject> myCollection = [1,2,3];
  2914.              dObject> myCollection = replace(myCollection,1,32);
  2915.              dObject> ? myCollection;
  2916.              [32,2,3]
  2917.  
  2918.  
  2919.      The number of values within a Collection can be  found  by  the  "len"
  2920.      method:
  2921.  
  2922.              dObject> ? len([1,2,3,4,5]);
  2923.              5
  2924.  
  2925.  
  2926.      The  first  value  in  a  Collection  is  called  the  "head"  of  the
  2927.      Collection, and the remaining Collection without the  head  is  called
  2928.      the "tail":
  2929.  
  2930.              dObject> ? myCollection = [1,2,3];
  2931.              dObject> ? head(myCollection);
  2932.              1
  2933.              dObject> ? tail(myCollection);
  2934.              [2,3]
  2935.  
  2936.  
  2937.  
  2938.  
  2939.  
  2940.  
  2941.                                      - 49 -
  2942.  
  2943.  
  2944. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2945.  
  2946.  
  2947.      Individual  values  within  a Collection can be retrieved using an Int
  2948.      index, but this is not nearly as efficient as using an Array for  this
  2949.      purpose:
  2950.  
  2951.              dObject> ? at(["one","two","three"],2);
  2952.              two
  2953.  
  2954.  
  2955.      The  last  element  in  a  collection  is  available  using the "last"
  2956.      method:
  2957.  
  2958.              dObject> ? last([1,2,3,4]);
  2959.              4
  2960.  
  2961.  
  2962.      The maximum and minimum values from within a Collection can  be  found
  2963.      with the "max" and "min" methods respectively:
  2964.  
  2965.              dObject> ? max([1,2,3]);
  2966.              3
  2967.  
  2968.  
  2969.      A  Collection  can  be  filtered into another Collection by the "sort"
  2970.      and "unique" methods.  The "sort" method returns a Collection that  is
  2971.      the sorted  version  of  the  variable  it  is called on.  The sort is
  2972.      accomplished using the ">"  operator  on  whatever  class  is  in  the
  2973.      Collection, and is done in ascending order:
  2974.  
  2975.              dObject> ? sort([3,1,4,6,5,2]);
  2976.              [1,2,3,4,5,6]
  2977.  
  2978.  
  2979.      The  "unique"  method  returns  a  Collection consisting of the unique
  2980.      elements in the Collection it is called on:
  2981.  
  2982.              dObject> ? unique([1,1,2,2,3,3,4,4,5,5,6,6]);
  2983.              [1,2,3,4,5,6]
  2984.  
  2985.  
  2986.      The following example demonstrates many of the methods  available  for
  2987.      handling Collections:
  2988.  
  2989.  
  2990.      /*
  2991.              this is a demonstration of dObject's Collection class
  2992.      */
  2993.      a = [5,3,9,5,100,44,5];
  2994.      ? "Collection is ",a;
  2995.      ? "length is ",len(a);
  2996.      ? "reversed is ",reverse(a);
  2997.      ? "third element is ",at(a,3);
  2998.      ? "last element is ",last(a);
  2999.      ? "with 100 removed is ",remove(a,100);
  3000.  
  3001.  
  3002.                                      - 50 -
  3003.  
  3004.  
  3005.                                             Chapter 10: Arrays and Collections
  3006.  
  3007.  
  3008.      ? "substitute 1005 for 5 is ",replace(a,5,1005);
  3009.      ? "is 44 in collection ?: ",44 $ a;
  3010.      ? "sorted array is ",sort(a);
  3011.      ? "unique array is ",unique(a);
  3012.      ? "unique sorted Collection is ",sort(unique(a));
  3013.      ? "sum of elements is ",sum(a);
  3014.      ? "minimum value is ",min(a);
  3015.      ? "maximum value is ",max(a);
  3016.      ? "average value is ",avg(a);
  3017.  
  3018.      /*
  3019.              fill a collection
  3020.      */
  3021.      a = [];
  3022.      i = 0;
  3023.      while(i < 10) {
  3024.              a = append(a,i);
  3025.              i = i+1;
  3026.      }
  3027.      ? a;
  3028.  
  3029.  
  3030.  
  3031.                            11.0 Files and Devices
  3032.  
  3033.      11.1 Files and Devices
  3034.  
  3035.      dObject  allows  output  to  DOS text files and to devices such as the
  3036.      printer through the built-in "File"  class.    Files  are  created  by
  3037.      passing  the  "new"  method  the  name  of  the file to create, an Int
  3038.      switch indicating if the file is to  be  opened  in  read,  write,  or
  3039.      append  mode  (1,2,  or  3  respectively),  an  Int containing the DOS
  3040.      attributes of the file, and an Int specifying what to do if  the  file
  3041.      already exists:
  3042.  
  3043.              dObject> f = new(File,"new.out",1,0,0);
  3044.  
  3045.  
  3046.      Constant  definitions  for the open mode, the DOS file attributes, and
  3047.      the creation option flag are provided in the file IODEF.DO:
  3048.  
  3049.      /*
  3050.              some constant definitions for new(File,...)
  3051.      */
  3052.      /* File Attributes */
  3053.      #define FA_RDONLY "$01"    /* Read only file       */
  3054.      #define FA_HIDDEN "$02"    /* Hidden file          */
  3055.      #define FA_SYSTEM "$04"    /* System file          */
  3056.      #define FA_SUBDIR "$10"    /* Subdirectory         */
  3057.      #define FA_ARCH   "$20"    /* Archive file         */
  3058.      #define FA_NORMAL "$40"    /* Normal file - No read/write restrictions */
  3059.  
  3060.  
  3061.  
  3062.                                      - 51 -
  3063.  
  3064.  
  3065. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3066.  
  3067.  
  3068.      /* File usage Modes */
  3069.      #define FM_ACCESS_WO "$0001"  /* write only           */
  3070.      #define FM_ACCESS_RW "$0002"  /* read/write           */
  3071.      #define FM_ACCESS_RO "$0004"  /* read only            */
  3072.      #define FM_SH_DENYRW "$0010"  /* deny read/write mode */
  3073.      #define FM_SH_DENYWR "$0020"  /* deny write mode      */
  3074.      #define FM_SH_DENYRD "$0030"  /* deny read mode       */
  3075.      #define FM_SH_DENYNO "$0040"  /* deny none mode       */
  3076.  
  3077.      /* Exclusively for OS2 and DOS >4.0 */
  3078.      #define FM_RETURNERR "$2000"  /* return error rather than call crit hand. */
  3079.      #define FM_WRITETHRU "$4000"  /* write through        */
  3080.  
  3081.      /* Creation Flags */
  3082.      /* Actions if file exists (low nibble) :   */
  3083.      #define CR_EX_FAIL "$00"
  3084.      #define CR_EX_OPEN "$01"
  3085.      #define CR_EX_REPLACE      "$02"
  3086.  
  3087.      /* Actions if file doesn't exist (high nibble):    */
  3088.      #define CR_NOEX_FAIL       "$00"
  3089.      #define CR_NOEX_CREATE     "$10"
  3090.  
  3091.  
  3092.      dObject  maintains  "current"  input  and  output  devices  which  are
  3093.      normally the  keyboard and the screen respectively.  These devices can
  3094.      be redirected to files  through  the  "readDevice"  and  "writeDevice"
  3095.      methods:
  3096.  
  3097.              dObject> writeDevice(f);
  3098.  
  3099.  
  3100.      Files  can  be  flushed  and  closed  through  the "flush" and "close"
  3101.      methods.  For example, to open a file and write a line  of  output  to
  3102.      it:
  3103.  
  3104.  
  3105.      You  can  read  a  character  from  the current input device using the
  3106.      Nil::readchar() method, which returns the next  character  as  a  Char
  3107.      variable.   To  read  a  complete keycode from the keyboard as an Int,
  3108.      use the  Nil::inkey()  method.    The  key  definitions  returned   by
  3109.      Nil::inkey() are defined in the include file "keydef.do".
  3110.  
  3111.      If  you  use  Nil::readchar()  to read characters, you can "push back"
  3112.      characters into the input  buffer  using  the  Char::unread()  method.
  3113.      This  method pushes its Char argument back into the input buffer where
  3114.      it can be read later using Nil::readchar().
  3115.  
  3116.  
  3117.      The following example describes how to create a file and write  output
  3118.      to it:
  3119.  
  3120.  
  3121.  
  3122.                                      - 52 -
  3123.  
  3124.  
  3125.                                                  Chapter 11: Files and Devices
  3126.  
  3127.  
  3128.      /*
  3129.              this is a demonstration of dObject's file handling capabilities
  3130.      */
  3131.      f = new(File,"new.out",1,0,0);
  3132.      writeDevice(f);
  3133.      ? "this is a test";
  3134.      close(f);
  3135.  
  3136.  
  3137.      When  opening  a file in the "new" command, the filename can also be a
  3138.      device name, such as "prn:".  The printer can be accessed as shown  in
  3139.      the following example:
  3140.  
  3141.  
  3142.      /*
  3143.              this is a demonstration of dObject's printer handling features
  3144.              open the printer and print 10 lines to it without echoing the
  3145.              lines to the screen
  3146.      */
  3147.      p = new(File,"prn:",1,0,0);
  3148.      writeDevice(p);
  3149.      i = 1;
  3150.      while(i < 10) {
  3151.              ? "printing line ",i;
  3152.              i = i+1;
  3153.      }
  3154.  
  3155.      /*
  3156.              note: on some printers (HP II, Epson EPL-6000) it is necessary
  3157.              to send an ESC E to flush the printer... consult your printer
  3158.              manual to see if the next line is necessary, otherwise the
  3159.              "flush" method should work OK by itself
  3160.      */
  3161.      ? chr(27),'E';
  3162.      flush(p);
  3163.      close(p);
  3164.      ? "printout is done";
  3165.  
  3166.  
  3167.  
  3168.                          12.0 DBASE File Programming
  3169.  
  3170.      12.1 DBASE File Programming
  3171.  
  3172.      dObject  provides  an  extensive  set of built-in methods for handling
  3173.      DBASE data, memo, and index files.    You  can  create  your  own  new
  3174.      DBASE-format  files for storing data, or use existing files already in
  3175.      the DBASE format.  You can also use  and  create  DBASE  index  (.NDX)
  3176.      files.
  3177.  
  3178.  
  3179.  
  3180.  
  3181.  
  3182.                                      - 53 -
  3183.  
  3184.  
  3185. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3186.  
  3187.  
  3188.      12.2 Creating DBASE Files
  3189.  
  3190.      The  following  example  demonstrates  how to create a .DBF file using
  3191.      the String::createDbf() method.  The argument  to  "createDbf"  is  an
  3192.      Collection of  Collections of field defintions.  Each field definition
  3193.      Collection should contain a string that is the  DBASE  field  name,  a
  3194.      character  field  type  ('C'  = char, 'N' = numeric, 'D' = date, 'M' =
  3195.      memo), an Int length, and an Int number of decimals for numerics:
  3196.  
  3197.      /*
  3198.              create a new Dbffile
  3199.      */
  3200.      db = createDbf("test",[
  3201.              ["cfield",'C',32,0],
  3202.              ["nfield",'N',5,0],
  3203.              ["dfield",'D',0,0],
  3204.              ["mfield",'M',512,0]);
  3205.      displayStructure(db);
  3206.  
  3207.  
  3208.      dObject will create a .DBT file for each MEMO field specified  in  the
  3209.      Collection of field definitions.
  3210.  
  3211.  
  3212.      To  set  the  value  of  a  field within the current DBASE file, set a
  3213.      variable with the same name as the field to  a  value,  just  like  in
  3214.      DBASE.   Once  set,  the  field  value  can  be updated in the current
  3215.      record by the "write" method, or a new record can be appended  to  the
  3216.      file using the "write" method:
  3217.  
  3218.  
  3219.      /*
  3220.              store some test data to the database
  3221.  
  3222.      */
  3223.      select(db); % make sure the Dbffile to process is the "current" file
  3224.      i = 1;
  3225.      while(i < 10) {
  3226.              cfield = "test"+asString(i);
  3227.              nfield = i;
  3228.              dfield = date();
  3229.              mfield = "memo" + asString(i);
  3230.              write(db,0L);
  3231.              i = i+1;
  3232.      }
  3233.  
  3234.  
  3235.      The  structure  (field definitions) from a DBF file can be obtained by
  3236.      using the Dbffile::structure() method.  This returns a  Collection  of
  3237.      field definitions  like  the one described above.  The following is an
  3238.      example of how to use the structure method  to  simulate  some  common
  3239.      DBASE commands:
  3240.  
  3241.  
  3242.  
  3243.                                      - 54 -
  3244.  
  3245.  
  3246.                                             Chapter 12: DBASE File Programming
  3247.  
  3248.  
  3249.      /*
  3250.              Dbffile::copyStructure(self,newname)
  3251.              this method copys the structure of self to a new database
  3252.              with name of "newname"
  3253.              only the structure of self is copied; no records are copied
  3254.      */
  3255.      method Dbffile::copyStructure(self,newname)
  3256.      {
  3257.              l = structure(self);
  3258.              createDbf(newname,l);
  3259.      }
  3260.  
  3261.      /*
  3262.              Dbffile::list(self)
  3263.              this method lists the records in a Dbffile to the screen
  3264.      */
  3265.      method Dbffile::list(self)
  3266.      {
  3267.              top(self);
  3268.              fields = structure(self);
  3269.              newline = set("newline");
  3270.              set("newline","");
  3271.              while(!eof(self)) {
  3272.                      for(i=1;i<numFields(self);i=i+1) {
  3273.                              f = at(fields,i);
  3274.                              name = at(f,1);
  3275.                              ? eval(asId(name))," ";
  3276.                      }
  3277.                      ? "\n";
  3278.                      skip(self,1L);
  3279.              }
  3280.              set("newline",newline);
  3281.      }
  3282.  
  3283.  
  3284.              dObject> db2 = copyStructure(db,"test2");
  3285.  
  3286.  
  3287.      12.3 Reading DBASE Files
  3288.  
  3289.      DBF  files can be opened through the use of the "new" message with the
  3290.      name of the DBF file passed as an argument.  Once opened, the  records
  3291.      and  fields within a DBF file are available for reading and for update
  3292.      by your dObject program.   For  example,  to  open  the  "patient.dbf"
  3293.      file, use the statement:
  3294.  
  3295.              dObject> db = new(Dbffile,"patient");
  3296.  
  3297.  
  3298.      The  number  of  records  and  fields  defined  within  a DBF file are
  3299.      available through calls to the "numRecords" and "numFields" methods:
  3300.  
  3301.  
  3302.  
  3303.                                      - 55 -
  3304.  
  3305.  
  3306. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3307.  
  3308.  
  3309.              dObject> ? numFields(db);
  3310.              6
  3311.              dObject> ? numRecords(db);
  3312.              20
  3313.  
  3314.  
  3315.      The current record number is available as a  Long  using  the  "recno"
  3316.      method:
  3317.  
  3318.              dObject> top(db);
  3319.              dObject> ? recno(db),class(recno(db));
  3320.              1 Long
  3321.  
  3322.  
  3323.      Dbffiles   can  be  positioned  by  sending  them  the  "top",  "bot",
  3324.      "locate", and "seek" messages. The  "eof"  method  returns  logical  T
  3325.      when  a  Dbffile is positioned beyond the last record in the file (and
  3326.      otherwise returns logical F).  The following  example  demonstrates  a
  3327.      program that loops over all the records in a DBF file:
  3328.  
  3329.  
  3330.              db = new(Dbffile,"patient");
  3331.              top(db);
  3332.              while(!eof(dbf)) {
  3333.                      ? "at record ",recno(db);
  3334.                      skip(db,1L);
  3335.              }
  3336.  
  3337.  
  3338.      The  "locate"  method  can  be used to locate specific field values of
  3339.      type Int, Real, Char, String, Date, or Logical.   The  first  argument
  3340.      to  the  method  should  be  the  name  of  the  field  to perform the
  3341.      comparison on, and the second the value to  find.    The  search  will
  3342.      always  start  at the current record, so to always search from the top
  3343.      of the database, the "top" method can be used to position the  Dbffile
  3344.      first:
  3345.  
  3346.              dObject> db = new(Dbffile,"patient");
  3347.              dObject> locate(top(db),"lname","lname6");
  3348.  
  3349.  
  3350.      Fields  within  DBF  files  are accessed by using a variable name with
  3351.      the same name as a field in the currently  selected  database,  as  in
  3352.      DBASE:
  3353.  
  3354.              dObject> db = new(Dbffile,"patient");
  3355.              dObject> top(db);
  3356.              dObject> ? lname;
  3357.              lname0
  3358.  
  3359.  
  3360.              dObject> select(db);
  3361.  
  3362.  
  3363.                                      - 56 -
  3364.  
  3365.  
  3366.                                             Chapter 12: DBASE File Programming
  3367.  
  3368.  
  3369.      The  currently  selected  Dbffile  is  available through a call to the
  3370.      Nil::currentDbffile() method:
  3371.  
  3372.              dObject> top(currentDbffile());
  3373.  
  3374.  
  3375.      You can also perform sophisticated calculations over all  the  records
  3376.      in  a  DBASE  file  using  the built-in "sum", "max", "min", and "avg"
  3377.      methods.  These methods accept a  literal  dObject  expression  as  an
  3378.      argument,   and  evaluate  the  sum,  max,  min,  or  average  of  the
  3379.      expression over all  the  records  in  the  file.    For  example,  to
  3380.      calculate  the  minimum and maximum length of a DBASE char field named
  3381.      "lname", your need to evaluate the length of the trimmed  field  value
  3382.      across all  the  records  in the file.  The following commands perform
  3383.      this task:
  3384.  
  3385.              dObject> ? db = new(Dbffile,"patient");
  3386.              dObject> ? min(db,#len(trim(lname)));
  3387.              dObject> ? max(db,#len(trim(lname)));
  3388.  
  3389.  
  3390.      These methods always start from the top of the file.
  3391.  
  3392.  
  3393.      12.4 Using Filters
  3394.  
  3395.      dObject allows you to specify an expression as a "filter" for  a  .DBF
  3396.      file  to  make  it  appear to your application that certain records do
  3397.      not exist.  The expression is evaluated for each record within a  .DBF
  3398.      file,  and unless the expression evaluates to logical true for a given
  3399.      record, the record appears as if it does not  exist.    To  create  an
  3400.      expression   filter   for  a  database,  call  the  Dbffile::setFilter
  3401.      method:
  3402.  
  3403.              dObject> setFilter(db,#(recno(db) > 5L) & (recno(db) < 15L));
  3404.  
  3405.  
  3406.      The above example creates a filter for  a  Dbffile  making  it  appear
  3407.      that  only  the  records  having  record  numbers  between  6  and  14
  3408.      inclusive actually exist in the file.    The  expression  can  be  any
  3409.      valid  dObject  expression,  and  setting a filter in this way affects
  3410.      every future operation done on the database,  including  repositioning
  3411.      with  the  Dbffile::top,  Dbffile::bot, Dbffile::skip, and Dbffile::go
  3412.      methods, as well as editing within the interactive DBASE editor.
  3413.  
  3414.  
  3415.      When  created,   Dbffile   objects   have   an   implied   filter   of
  3416.      logical(true), which  succeeds  for  any  record.  To clear the filter
  3417.      for a Dbffile object, use the Dbffile::clearFilter() method:
  3418.  
  3419.              dObject> clearFilter(db);
  3420.  
  3421.  
  3422.  
  3423.                                      - 57 -
  3424.  
  3425.  
  3426. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3427.  
  3428.  
  3429.      Collections can be created from DBASE fields using the  "asCollection"
  3430.      method.   The argument to this method is an expression to evaluate for
  3431.      each record in the DBASE file.  The Collection returned  contains  one
  3432.      entry for  the value of the expression for each record.  The filtering
  3433.      process descibed above applies to filter  out  unwanted  records.  The
  3434.      following  is  an  example  of  how to create a menu using information
  3435.      from a DBF file using a Collection as the list of  items  to  show  in
  3436.  
  3437.      the menu:
  3438.  
  3439.      /*
  3440.              create a menu of all the last names within a range
  3441.              of records in the dbf file
  3442.      */
  3443.      d = new(Dbffile,"patient");
  3444.      top(d);
  3445.      d = setFilter(d,#(recno(d) >= 8L) & (recno(d) <= 15L));
  3446.      a = sort(asCollection(d,#trim(lname)));
  3447.      m = new(Menu,3,3,5,31,3,a," Last Name ");
  3448.      c = choice(m,1);
  3449.      remove(m);
  3450.      ? "your menu choice was ",c;
  3451.  
  3452.  
  3453.      12.5 Using DBASE Index Files
  3454.  
  3455.      Records  containing field values of interest can be accessed much more
  3456.      quickly using DBASE index files than can be using the "locate"  method
  3457.      described above.    dObject  provides  the  built-in  Ndxfile class to
  3458.      represent DBASE index files.  To  open  an  existing  index  file  and
  3459.      associate  it  with  a  Dbffile variable, use the "useIndex" method of
  3460.      the Dbffile class.  This method returns a new Ndxfile variable:
  3461.  
  3462.              dObject> db = new(Dbffile,"patient");
  3463.              dObject> ndx = useIndex(db,"patient");
  3464.  
  3465.  
  3466.  
  3467.      This method opens the named  index  (with  the  default  extension  of
  3468.      .NDX) and   associates   it  with  the  Dbffile.    This  permits  the
  3469.      Ndxfile::seek method to be used to position the current record in  the
  3470.      Dbffile:
  3471.  
  3472.              dObject> seek(db,"1");
  3473.  
  3474.  
  3475.      To  create  a  new  index  file,  use  the "createIndex" method of the
  3476.      String class.  The "self" argument in this case is  the  name  of  the
  3477.      index  file  to create, followed by a String containing the expression
  3478.      to evaluate for the index, and finally an Int indicator specifying  if
  3479.      the index  is  to be unique (0=not unique, 1=unique).  It also returns
  3480.      a new Ndxfile variable:
  3481.  
  3482.              dObject> ndx = createIndex("test","test",1);
  3483.  
  3484.  
  3485.                                      - 58 -
  3486.  
  3487.  
  3488.                                             Chapter 12: DBASE File Programming
  3489.  
  3490.  
  3491.      The following program demonstrates how to create  an  index  file  and
  3492.      use it to access fields within a Dbffile:
  3493.  
  3494.      /*
  3495.              create an index file for a database
  3496.      */
  3497.      db = new(Dbffile,"patient");
  3498.      index = createIndex(db,"patient","LNAME",0,0);
  3499.      ? "type of index is ",type(index);
  3500.      close(db);
  3501.  
  3502.      /*
  3503.              open the index and print out records in index order
  3504.      */
  3505.      db = new(Dbffile,"patient");
  3506.      useIndex(db,"patient");
  3507.      top(db);
  3508.      while(!eof(db)) {
  3509.              ? recno(db)," ",lname;
  3510.              skip(db,1L);
  3511.      }
  3512.      close(db);
  3513.  
  3514.  
  3515.      12.6 Using Relations
  3516.  
  3517.      dObject  provides  a facility to relate two DBF files throught the use
  3518.      of the Dbffile::setRelation() method.  Calling this method  creates  a
  3519.      relation  between  a  controlling  database (the self parameter) and a
  3520.      related database.      Each   time   the   controlling   database   is
  3521.      re-positioned     (using     the    Dbffile::go(),    Dbffile::seek(),
  3522.      Dbffile::top(), or Dbffile::bot() methods), the  related  database  is
  3523.      re-positioned by  looking  up  an  expression in an index file.  If no
  3524.      index file is specified when the relationship  is  created,  then  the
  3525.      expression  is  evaluated  and interpreted as a record number to go to
  3526.      in the related database.
  3527.  
  3528.  
  3529.      The following example illustrates the use of relations in dObject:
  3530.  
  3531.      /*
  3532.              demonstrate the dObject relation facility between two related
  3533.              DBF files,  first, create a customer file with customer names
  3534.      */
  3535.      custDb = createDbf("customer",[
  3536.              ["cId",'N',8,0],
  3537.              ["cName",'C',32,0],
  3538.              ["cAddress",'C',48,0],
  3539.              ["cCity",'C',16,0],
  3540.              ["cState",'C',2,0],
  3541.              ["cZip",'C',5,0]]);
  3542.  
  3543.  
  3544.  
  3545.                                      - 59 -
  3546.  
  3547.  
  3548. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3549.  
  3550.  
  3551.      /*
  3552.              fill in some test customer names
  3553.      */
  3554.      #define MAXCUST 5
  3555.      for(i=0;i<MAXCUST;i=i+1) {
  3556.              cId = i;
  3557.              cName = "name"+asString(i);
  3558.              cAddress = "";
  3559.              cCity = "Chicago";
  3560.              cState = "IL";
  3561.              cZip = "60640";
  3562.              ? "writing record ",i;
  3563.              write(custDb,0L);
  3564.      }
  3565.      close(custDb);
  3566.  
  3567.      /*
  3568.              create a database of customer purchases
  3569.      */
  3570.      purchaseDb = createDbf("purchase",[
  3571.              ["cId",'N',8,0],
  3572.              ["pItem",'C',32,0],
  3573.              ["pDate",'D',0,0],
  3574.              ["pAmount",'N',8,2]]);
  3575.  
  3576.      /*
  3577.              create some test data
  3578.      */
  3579.      for(i=0;i<MAXCUST;i=i+1)
  3580.              for(j=0;j<2;j=j+1) {
  3581.                      cId = i;
  3582.                      pItem = "item"+asString(i);
  3583.                      pDate = date();
  3584.                      pAmount = 5.25;
  3585.                      write(purchaseDb,0L);
  3586.              }
  3587.      close(purchaseDb);
  3588.  
  3589.      /*
  3590.              find the purchases for customer #3
  3591.      */
  3592.      custDb = new(Dbffile,"customer");
  3593.      purchaseDb = new(Dbffile,"purchase");
  3594.      ndx = createIndex(purchaseDb,"CID","cId",0,0);
  3595.      setRelation(custDb,"cId",select(purchaseDb),select(ndx),0);
  3596.      top(custDb);
  3597.      locate(custDb,"cId",3);
  3598.      ? "record number for customer 3 is ",recno(custDb);
  3599.      ? "customer id field in purchase database is ",recno(purchaseDb);
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.                                      - 60 -
  3606.  
  3607.  
  3608.                                             Chapter 12: DBASE File Programming
  3609.  
  3610.  
  3611.      12.7 Editing DBASE Files
  3612.  
  3613.      Using the built-in Window::say() and read() methods  and  the  "Field"
  3614.      class,  the  file DBFLIB.DO provides an example of a DBASE full-screen
  3615.      editor that is invoked by sending the  "edit"  message  to  a  Dbffile
  3616.      object.   You  can  include this editor in your own programs as is, or
  3617.      customize it to fit your own application.  When  invoked,  the  editor
  3618.      will  display  the  field  name  and  value  for each field within the
  3619.      database in the current window, at the current record position.
  3620.  
  3621.  
  3622.      The "edit" method is implemented in the following library  of  Dbffile
  3623.      methods:
  3624.  
  3625.  
  3626.      /*
  3627.              DBFLIB.DO
  3628.              This is a collection of methods for handling DBASE files
  3629.              Includes:
  3630.                      Dbffile::displayStructure(self)
  3631.                      Dbffile::copyStructure(self)
  3632.                      Dbffile::list(self)
  3633.                      Dbffile::edit(self)
  3634.      */
  3635.      #include "keydef.do"
  3636.      #include "colors.do"
  3637.  
  3638.      /*
  3639.              Dbffile::displayStructure(self)
  3640.              this methods prints a description of the structure of a DBASE
  3641.              file similar to that in the DBASE DISPLAY STRUCTURE command
  3642.      */
  3643.      method Dbffile::displayStructure(self)
  3644.      {
  3645.              ? "Structure for\t\t",name(self);
  3646.              ? "Last udpate:\t\t",date(self);
  3647.              ? "Number of records:\t",numRecords(self);
  3648.              fields = structure(self);
  3649.              ? "FIELD\t\t\tTYPE\tLEN\tDEC";
  3650.              for(i=1;i<numFields(self);i=i+1) {
  3651.                      f = at(fields,i);
  3652.                      ? format(at(f,1),"%-24s"),at(f,2),"\t",
  3653.                              at(f,3),"\t",at(f,4);
  3654.              }
  3655.      }
  3656.  
  3657.      /*
  3658.              Dbffile::copyStructure(self,newname)
  3659.              this method copys the structure of self to a new database
  3660.              with name of "newname"
  3661.              only the structure of self is copied; no records are copied
  3662.      */
  3663.  
  3664.  
  3665.                                      - 61 -
  3666.  
  3667.  
  3668. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3669.  
  3670.  
  3671.      method Dbffile::copyStructure(self,newname)
  3672.      {
  3673.              l = structure(self);
  3674.              create(newname,l);
  3675.      }
  3676.  
  3677.      /*
  3678.              Dbffile::list(self)
  3679.              this method lists the records in a Dbffile to the screen
  3680.      */
  3681.      method Dbffile::list(self)
  3682.      {
  3683.              top(self);
  3684.              fields = structure(self);
  3685.              newline = set("newline");
  3686.              set("newline","");
  3687.              while(!eof(self)) {
  3688.                      for(i=1;i<numFields(self);i=i+1) {
  3689.                              f = at(fields,i);
  3690.                              name = at(f,1);
  3691.                              ? eval(asId(name))," ";
  3692.                      }
  3693.                      ? "\n";
  3694.                      skip(self,1L);
  3695.              }
  3696.              set("newline",newline);
  3697.      }
  3698.  
  3699.      /*
  3700.              The following methods implement a DBASE field editor using the
  3701.              dObject Window SAY and READ methods and the FIELD class.
  3702.              first, define a new class called MYFIELD that inherits the behavior of
  3703.              Field, but adds a prompt that is displayed at the bottom of the form
  3704.      */
  3705.      inherit(Field,Myfield,["prompt"]);
  3706.  
  3707.      /*
  3708.              define a method to get the prompt field from a Myfield variable
  3709.      */
  3710.      method Myfield::prompt(self)
  3711.      {
  3712.              return(slot(self,"prompt"));
  3713.      }
  3714.  
  3715.      /*
  3716.              this method will execute whenever the DOWN key is pressed
  3717.              from within a form
  3718.      */
  3719.      method Window::myNextField(self)
  3720.      {
  3721.              n = num(currentField(self));
  3722.              if(n < len(fields)) {
  3723.  
  3724.  
  3725.                                      - 62 -
  3726.  
  3727.  
  3728.                                             Chapter 12: DBASE File Programming
  3729.  
  3730.  
  3731.                      f = at(fields,n+1);
  3732.                      say(promptWindow,0,0,prompt(f),80,112);
  3733.                      gotoField(self,nextField(self));
  3734.              }
  3735.  
  3736.      }
  3737.  
  3738.      /*
  3739.              this method will execute whenever the UP key is pressed
  3740.              from within a form
  3741.      */
  3742.      method Window::myPrevField(self)
  3743.      {
  3744.              n = num(currentField(self));
  3745.              if(n > 1) {
  3746.                      f = at(fields,n-1);
  3747.                      say(promptWindow,0,0,prompt(f),80,112);
  3748.                      gotoField(self,prevField(self));
  3749.              }
  3750.      }
  3751.  
  3752.      /*
  3753.              this method implements a callable text editor for the contents of
  3754.              a field
  3755.      */
  3756.      method Window::myEdit(self)
  3757.      {
  3758.              f = currentField(self);
  3759.              s = eval(asId(name(f)));
  3760.              if(class(s) == "String") {
  3761.                      w = new(Window,1,31,3,name(f),5,5,10,40);
  3762.                      display(s);
  3763.                      remove(w);
  3764.                      gotoField(self,f);
  3765.              }
  3766.      }
  3767.  
  3768.      /*
  3769.              edit a Dbffile using a full screen editor
  3770.      */
  3771.      method Dbffile::edit(self)
  3772.      {
  3773.      /*
  3774.              make a window to run the editor in
  3775.      */
  3776.              w = new(Window,1,FWHITE+LIGHTBLUE,FWHITE+LIGHTBLUE,
  3777.                      name(self),0,0,24,80);
  3778.  
  3779.      /*
  3780.              create the DBASE form based on field definitions within self
  3781.      */
  3782.              clearGets(w);
  3783.  
  3784.  
  3785.                                      - 63 -
  3786.  
  3787.  
  3788. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3789.  
  3790.  
  3791.              sayExp(w,0,1,#name(self),len(name(self)),FWHITE+LIGHTBLUE);
  3792.              sayExp(w,0,20,#"Record=",7,FWHITE+LIGHTBLUE);
  3793.              sayExp(w,0,30,#recno(self),7,FWHITE+LIGHTBLUE);
  3794.  
  3795.              l = structure(self);
  3796.              fields = [];
  3797.  
  3798.      /*
  3799.              for each field in the DBF file, create:
  3800.                      a SAY field with the name of the DBF field
  3801.                      a GET field right next to it to read its value
  3802.      */
  3803.              for(i=1;i<=numFields(self);i=i+1) {
  3804.                      field_def = at(l,i);
  3805.                      fname = at(field_def,1); % name is first element in field def
  3806.                      len = at(field_def,3);
  3807.                      if(len > 40) len = 40;
  3808.                      say(w,i,1,fname,10,31);
  3809.                      fields = append(fields,new(Myfield,w,i,15,fname,len,112,
  3810.                              "Enter the "+asUpper(trim(fname))+ " field"));
  3811.  
  3812.              }
  3813.  
  3814.      /*
  3815.              execute the form
  3816.      */
  3817.              top(self);
  3818.              promptWindow = new(Window,80,112,0,"",24,0,1,80);
  3819.  
  3820.              onKey(w,DOWN,#myNextField(w));
  3821.              onKey(w,UP,#myPrevField(w));
  3822.              onKey(w,F8,#myEdit(w));
  3823.  
  3824.              say(promptWindow,0,0,prompt(at(fields,1)),80,112);
  3825.  
  3826.              read(w);
  3827.              remove(w);
  3828.              remove(promptWindow);
  3829.      }
  3830.  
  3831.  
  3832.  
  3833.      As  another example, the following program displays a directory of DBF
  3834.      files in the current directory and edits the  one  selected  from  the
  3835.      menu:
  3836.  
  3837.  
  3838.      /*
  3839.              this program creates a window, and displays a menu of DBF files
  3840.              available in the current directory.  When the user selects one,
  3841.              the DBF file editor is called to edit the fields and records
  3842.      */
  3843.  
  3844.  
  3845.                                      - 64 -
  3846.  
  3847.  
  3848.                                             Chapter 12: DBASE File Programming
  3849.  
  3850.  
  3851.      w = new(Window,1,7,7," select DBF ",1,1,10,40);
  3852.      s = dir("","*.dbf");
  3853.      while(s != "") {
  3854.              d = new(Dbffile,s);
  3855.              height = numFields(d)+2;
  3856.              edit(d);
  3857.              s = dir("","*.dbf");
  3858.      }
  3859.      remove(w);
  3860.  
  3861.  
  3862.      12.8 Closing DBASE Files
  3863.  
  3864.      To close a Dbffile, use the "close" method:
  3865.  
  3866.  
  3867.              dObject> close(db);
  3868.  
  3869.  
  3870.      To  close  all  the  open  Dbffiles at once, use the Nil::closeAllDbfs
  3871.      method (this will close all open .NDX files also):
  3872.  
  3873.              dObject> closeAllDbfs();
  3874.  
  3875.  
  3876.  
  3877.                           13.0 Graphics Programming
  3878.  
  3879.      13.1 BGI Graphics
  3880.  
  3881.      dObject comes complete with a built-in graphics system  based  on  the
  3882.      Borland Graphics  Interface  (BGI).   The BGI provides over 70 methods
  3883.      for  handling  graphics,  including  methods  to  draw  lines,   arcs,
  3884.      circles, polygons,  and other shapes;  methods for filling shapes in a
  3885.      variety of styles;  and methods for  setting  text  in  a  variety  of
  3886.      fonts.
  3887.  
  3888.  
  3889.      13.2 Graphics Drivers
  3890.  
  3891.      To   begin   with,  you  must  call  the  Int::initGraph()  method  to
  3892.      initialize the graphics  system.    This  will  put  the  screen  into
  3893.      graphics mode  and  allow  further  calls  to the BGI system.  dObject
  3894.      comes with graphics drivers for the following graphics adapters:
  3895.  
  3896.           * CGA
  3897.  
  3898.           * MCGA
  3899.  
  3900.           * EGA
  3901.  
  3902.           * VGA
  3903.  
  3904.  
  3905.                                      - 65 -
  3906.  
  3907.  
  3908. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3909.  
  3910.  
  3911.           * Hercules
  3912.  
  3913.           * AT&T 400-line
  3914.  
  3915.           * 3270 Graphics Adapter
  3916.  
  3917.           * IBM-8514 Graphics Adapter
  3918.  
  3919.      The self argument to Int::initGraph() is an  integer  flag  specifying
  3920.      the  device  driver  to use ( a value of 0 will detect the best driver
  3921.      to use):
  3922.  
  3923.  
  3924.           * 0 - autodetect
  3925.  
  3926.           * 1 - CGA
  3927.  
  3928.           * 2 - MCGA
  3929.  
  3930.           * 3 - EGA
  3931.  
  3932.           * 4 - EGA64
  3933.  
  3934.           * 5 - EGAMONO
  3935.  
  3936.           * 6 - IBM8514
  3937.  
  3938.           * 7 - Hercules
  3939.  
  3940.           * 8 - AT&T 400
  3941.  
  3942.           * 9 - VGA
  3943.  
  3944.           * 10 - PC 3270
  3945.  
  3946.      You can obtain the name of the current graphics driver through a  call
  3947.      to the Nil::getDriverName() method.
  3948.  
  3949.  
  3950.      dObject  provides  the following methods for initializing and shutting
  3951.      down the BGI graphics system:
  3952.  
  3953.  
  3954.      NAME                 ARGUMENTS            DESCRIPTION
  3955.  
  3956.      Int::initGraph       self, Int, String    initializes the BGI system;
  3957.                                                must be called before any
  3958.                                                other BGI method.  Sets the
  3959.                                                graphics driver to self, the
  3960.                                                graphics mode to the Int
  3961.                                                arg, and the driver path to
  3962.                                                the String arg.
  3963.  
  3964.  
  3965.                                      - 66 -
  3966.  
  3967.  
  3968.                                               Chapter 13: Graphics Programming
  3969.  
  3970.  
  3971.      Nil::detectGraph                          returns a Collection of 2
  3972.                                                Int values specifying the
  3973.                                                current graphics driver and
  3974.                                                mode.
  3975.      Nil::getDriverName                        returns a String containing
  3976.                                                the name of the current
  3977.                                                graphics driver.
  3978.      Int::getModeName     self                 returns a String containing
  3979.                                                the graphics mode name for
  3980.                                                the mode with Int code of
  3981.                                                self.
  3982.      Int::getModeRange    self                 returns a Collection of 2
  3983.                                                Int values specifying the
  3984.                                                min and max mode values for
  3985.                                                the graphics driver with Int
  3986.                                                code of self.
  3987.      Int::setGraphMode    self                 changes the graphics mode to
  3988.                                                self.
  3989.      Nil::getGraphMode                         returns an Int containing
  3990.                                                the current graphics mode.
  3991.      Nil::getMaxMode                           returns an Int containing
  3992.                                                the maximum mode number for
  3993.                                                the currently loaded driver.
  3994.      Nil::graphDefaults                        sets the graphics system to
  3995.                                                default values (see next
  3996.                                                section).
  3997.      Nil::closeGraph                           closes the graphics system,
  3998.                                                unloads the driver from
  3999.                                                memory, and restores the CRT
  4000.                                                to its original state before
  4001.                                                initGraph() was called.
  4002.      Nil::restoreCrtMode                       restores the CRT to its
  4003.                                                original state.
  4004.  
  4005.      13.3 Default Graphics Settings
  4006.  
  4007.      You can set the graphics system to  its  default  settings  through  a
  4008.      call to  the Nil::graphDefaults() method.  These defaults settings are
  4009.      as follows:
  4010.  
  4011.  
  4012.           * Viewport:  mamimum device resolution
  4013.  
  4014.           * Clipping:  on
  4015.  
  4016.           * Palette:  default for drive
  4017.  
  4018.           * Background color:  0
  4019.  
  4020.           * Drawing color:  max color
  4021.  
  4022.           * Fill style:  solid fill
  4023.  
  4024.  
  4025.                                      - 67 -
  4026.  
  4027.  
  4028. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4029.  
  4030.  
  4031.           * Fill color:  max color
  4032.  
  4033.           * Line style:  solid line
  4034.  
  4035.           * Hardware font direction:  horizontal
  4036.  
  4037.           * Font size:  1
  4038.  
  4039.           * Font justification:  left top
  4040.  
  4041.           * Current position:  home (0,0)
  4042.  
  4043.      13.4 Current Graphics Position
  4044.  
  4045.      The BGI system maintains the current X,Y graphics co-ordinate that  is
  4046.      referred to  as  the  current position (CP).  The current position can
  4047.      be obtained through calls to the Nil::getx() and Nil::gety()  methods,
  4048.      each of  which  return  an  Int  value.    The CP can be set using the
  4049.      Int::moveto() and Int::moveRel() methods, with the self arg  equal  to
  4050.      the  X  value  to  move  to,  and  the  first  argument being an Int Y
  4051.      co-ordinate.  Int::moveTo() uses  and  absolute  co-ordinate,  whereas
  4052.      Int::moveRel() moves relative to the current position:
  4053.  
  4054.  
  4055.  
  4056.              /*
  4057.                      move the graphics CP
  4058.              */
  4059.              moveto(100,100); % now at 100,100
  4060.              moveRel(100,100); % now at 200,200
  4061.  
  4062.  
  4063.  
  4064.      dObject  provides  the  following methods for maintinaing the graphics
  4065.      CP:
  4066.  
  4067.  
  4068.      NAME                 ARGUMENTS            DESCRIPTION
  4069.  
  4070.      Nil::getX                                 returns the x co-ordinate of
  4071.                                                the CP
  4072.      Nil::getY                                 returns the y co-ordinate of
  4073.                                                the CP
  4074.      Int::moveTo          self, Int            moves the CP to X,Y of self,
  4075.                                                Int arg
  4076.      Int::moveRel         self, Int            moves the CP the X,Y
  4077.                                                relative distance  of self,
  4078.                                                Int arg
  4079.      Nil::getMaxX                              returns the max X value for
  4080.                                                the current graphics driver
  4081.                                                and mode
  4082.      Nil::getMaxY                              returns the max Y value for
  4083.  
  4084.  
  4085.                                      - 68 -
  4086.  
  4087.  
  4088.                                               Chapter 13: Graphics Programming
  4089.  
  4090.  
  4091.                                                the current graphics driver
  4092.                                                and mode
  4093.  
  4094.      13.5 Drawing Lines
  4095.  
  4096.      Lines are drawn using the  Int::line()  method,  passing  it  the  X,Y
  4097.      positions of  the  beginning  and  end  points.  The following example
  4098.      draws a line from the point 5,5 to the point 100,100:
  4099.  
  4100.              dObject> line(5,5,100,100);
  4101.  
  4102.  
  4103.      The following methods are provided for drawing lines:
  4104.  
  4105.  
  4106.      NAME                 ARGUMENTS            DESCRIPTION
  4107.  
  4108.      Int::setLineStyle    self, Int, Int       sets the current line style
  4109.                                                to the code in self; sets
  4110.                                                the current pattern to the
  4111.                                                first Int arg code, and the
  4112.                                                current thickness to the
  4113.                                                second Int arg.  Line style
  4114.                                                codes are 0=solid, 1=dotted,
  4115.                                                2=center, 3=dashes,
  4116.                                                4=user-defined.  You can
  4117.                                                define a line style by using
  4118.                                                a 16-bit pattern in the
  4119.                                                first Int arg, where whenver
  4120.                                                a bit in the pattern is set
  4121.                                                to one, the corresponding
  4122.                                                pixel in the line is drawn
  4123.                                                in the current drawing
  4124.                                                color.  For example, a solid
  4125.                                                line is  represented by the
  4126.                                                value $FFFF (all one's), and
  4127.                                                a dashed line is $3333 or
  4128.                                                $0F0F.  Thickness codes in
  4129.                                                the second Int arg are 0=1
  4130.                                                pixel wide, 3=3 pixels wide.
  4131.      Nil::getLineSettings                      returns collection of 3 Int
  4132.                                                args representing current
  4133.                                                line style, user-defined
  4134.                                                pattern, and thickness code
  4135.                                                as described above.
  4136.      Int::line            self, Int, Int, Int  draws a line in the current
  4137.                                                drawing color. Arguments are
  4138.                                                X,Y of start point and X,Y
  4139.                                                of end point.
  4140.      Int::linerel         self, Int            draws a line in the current
  4141.                                                drawing color from current
  4142.                                                position to relative offset
  4143.  
  4144.  
  4145.                                      - 69 -
  4146.  
  4147.  
  4148. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4149.  
  4150.  
  4151.                                                of self, Int arg.
  4152.      Int::lineto          self, Int            draws a line in the current
  4153.                                                drawing color from current
  4154.                                                position to X,Y position of
  4155.                                                self, Int arg.
  4156.      Int::setWriteMode    self                 sets the writing mode for
  4157.                                                line drawing to self; if
  4158.                                                self = 0 the line will
  4159.                                                overwrite what is on the
  4160.                                                screen; if self=1 the line
  4161.                                                pixels will be XOR'd with
  4162.                                                the pixels on the screen.
  4163.  
  4164.      13.6 Drawing Circles
  4165.  
  4166.      The following methods are provided for drawing circles and arcs:
  4167.  
  4168.  
  4169.      NAME                 ARGUMENTS            DESCRIPTION
  4170.  
  4171.      Int::arc             self, Int, Int, Int, draws a circular arc in the
  4172.                           Int                  current  drawing color.
  4173.                                                Arguments are X,Y center,
  4174.                                                start angle, end angle, and
  4175.                                                radius.
  4176.      Int::circle          self, Int, Int       draws a circle in the
  4177.                                                current drawing color.
  4178.                                                Arguments are X,Y of center,
  4179.                                                and radius.
  4180.      Nil::getArcCoords                         returns a Collection of 6
  4181.                                                Int values containing the
  4182.                                                x,y center point, x,y start
  4183.                                                pos, and x,y end pos of the
  4184.                                                arc.  This is useful if you
  4185.                                                need to make a line meet at
  4186.                                                the end of an arc.
  4187.  
  4188.      13.7 Drawing Ellipses and Pie Charts
  4189.  
  4190.      The following methods  are  provided  for  drawing  ellipses  and  pie
  4191.      charts:
  4192.  
  4193.  
  4194.      NAME                 ARGUMENTS            DESCRIPTION
  4195.  
  4196.      Int::ellipse         self, Int, Int, Int, draws an ellipse in the
  4197.                           Int, Int             current drawing color.  Args
  4198.                                                are center point X,Y, start
  4199.                                                angle, end angle, and X and
  4200.                                                Y radius.
  4201.      Int::fillEllipse     self, Int, Int, Int  draws an ellipse and fills
  4202.                                                it with the current fill
  4203.  
  4204.  
  4205.                                      - 70 -
  4206.  
  4207.  
  4208.                                               Chapter 13: Graphics Programming
  4209.  
  4210.  
  4211.                                                pattern in the current fill
  4212.                                                color.  Args are X, Y, X
  4213.                                                radius, and Y radius.
  4214.      Int::pieSlice        self, Int, Int, Int, draws and fills a pie slice
  4215.                           Int                  using current fill pattern
  4216.                                                and drawing color.
  4217.                                                Arguments are X,Y center,
  4218.                                                start angle, end angle, and
  4219.                                                radius.
  4220.      Int::pieSliceXY      self, Int, Int, Int, draws and fills an
  4221.                           Int, Int             elliptical pie slice using
  4222.                                                current fill pattern and
  4223.                                                drawing color.   Arguments
  4224.                                                are X,Y center, start angle,
  4225.                                                end angle, X radius, and Y
  4226.                                                radius.
  4227.      Nil::getAspectRatio                       returns Collection of 2 Int
  4228.                                                value representing the x and
  4229.                                                y aspect ratio correction
  4230.                                                values of the current
  4231.                                                graphics mode.
  4232.      setAspectRatio       self, Int            sets the x and y
  4233.                                                aspect-ratio correction
  4234.                                                factors  to self and Int arg
  4235.                                                respectively.
  4236.  
  4237.      13.8 Drawing Rectangles and Bars
  4238.  
  4239.      dObject  provides  the  following  methods for drawing rectangles, bar
  4240.      graphs, and polygons:
  4241.  
  4242.  
  4243.      NAME                 ARGUMENTS            DESCRIPTION
  4244.  
  4245.      Int::rectangle       self, Int, Int, Int  draws a rectangle in the
  4246.                                                current line style,
  4247.                                                thickness, and drawing
  4248.                                                color.  Arguments are left,
  4249.                                                top, right, and bottom
  4250.                                                co-ordinates of the
  4251.                                                rectangle to draw  (from
  4252.                                                (left,top) to
  4253.                                                (right,bottom)).
  4254.      Int::bar             self, Int, Int, Int  draws a rectangular bar in
  4255.                                                the current line style,
  4256.                                                thickness, and drawing
  4257.                                                color, and fills it using
  4258.                                                the current fill pattern and
  4259.                                                fill color.  Arguments are
  4260.                                                left, top, right, and bottom
  4261.                                                co-ordinates of the
  4262.                                                rectangle to draw (from
  4263.  
  4264.  
  4265.                                      - 71 -
  4266.  
  4267.  
  4268. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4269.  
  4270.  
  4271.                                                (left,top) to
  4272.                                                (right,bottom)).
  4273.      Int::bar3d           self, Int, Int, Int, draws a rectangular 3-D bar
  4274.                           Int, Int             in  the current line style,
  4275.                                                thickness, and drawing
  4276.                                                color, and fills it using
  4277.                                                the current fill pattern and
  4278.                                                fill color.  Arguments are
  4279.                                                left, top, right, and bottom
  4280.                                                co-ordinates of the
  4281.                                                rectangle to draw (from
  4282.                                                (left,top)  to
  4283.                                                (right,bottom)), the depth
  4284.                                                of the bar, and a flag
  4285.                                                indicating if a top to the
  4286.                                                bar should be drawn (0=no,
  4287.                                                1=yes).
  4288.  
  4289.      13.9 Drawing Polygons
  4290.  
  4291.      dObject provides the following methods for drawing polygons:
  4292.  
  4293.  
  4294.      NAME                 ARGUMENTS            DESCRIPTION
  4295.  
  4296.      Collection::drawPoly self                 draws a polygon with as many
  4297.                                                points as Int value pairs in
  4298.                                                the collection; each Int
  4299.                                                pair is an x,y co-ordinate
  4300.                                                of a vertex on the polygon.
  4301.      Collection::fillPoly self                 draws a polygon with as many
  4302.                                                points as Int value pairs in
  4303.                                                the collection and fills it
  4304.                                                using the current fill style
  4305.                                                and fill color; each Int
  4306.                                                pair is an x,y co-ordinate
  4307.                                                of a vertex on the polygon.
  4308.  
  4309.      13.10 Palettes
  4310.  
  4311.      The BGI graphics screen consists of an array of pixels  controlled  by
  4312.      a color   table  called  a  palette.    The  background  color  always
  4313.      corresponds to pixel value 0.  The  drawing  color  is  the  value  to
  4314.      which pixels  are  set  when lines or shapes are being drawn.  You can
  4315.      select a drawing color with the Int::setColor() method.
  4316.  
  4317.  
  4318.      NAME                 ARGUMENTS            DESCRIPTION
  4319.  
  4320.      Int::setBkColor      self                 sets the current background
  4321.                                                color to self
  4322.      Nil::getBkcolor      self                 returns the current
  4323.  
  4324.  
  4325.                                      - 72 -
  4326.  
  4327.  
  4328.                                               Chapter 13: Graphics Programming
  4329.  
  4330.  
  4331.                                                background color
  4332.      Int::setColor        self                 sets the current drawing
  4333.                                                color to self
  4334.      Nil::getColor                             returns the current drawing
  4335.                                                color
  4336.      Nil::getMaxColor                          returns the maximum color
  4337.                                                value available in the
  4338.                                                current graphics mode
  4339.      Int::setPalette      self, Int            changes the color value
  4340.                                                stored under self to the
  4341.                                                color in the Int arg
  4342.      Collection::setAllPaletteself                 sets list of new palette
  4343.                                                colors. self  must be a
  4344.                                                Collection of 8 Int values
  4345.                                                specifying the colors.
  4346.  
  4347.      13.11 Filling Shapes
  4348.  
  4349.      You can fill the shapes drawn  with  the  circle,  ellipse,  bar,  and
  4350.      polygon  shape  drawing  methods  with the Int::floodFill() method, or
  4351.      combine drawing and filling into one  step  with  the  fillPoly()  and
  4352.      pieSlice() methods.    You  can  select a predefined fill pattern with
  4353.      setFillStyle,   and   define    your    own    fill    pattern    with
  4354.      setFillPattern().
  4355.  
  4356.  
  4357.      The  predefined  fill  pattern codes recognized by Int::setFillStyle()
  4358.      are as follows (as defined in the included file BGIDEF.DO):
  4359.  
  4360.           * 0 (EMPTY_FILL) - fill with background color
  4361.  
  4362.           * 1 (SOLID_FILL) - solid fill
  4363.  
  4364.           * 2 (LINE_FILL) - fill with ----
  4365.  
  4366.           * 3 (LTSLASH_FILL) - fill with ///
  4367.  
  4368.           * 4 (SLASH_FILL) - fill with ///, thick lines
  4369.  
  4370.           * 5 (BKSLASH_FILL) - fill with backslash, thick lines
  4371.  
  4372.           * 6 (LTBACKSLASH_FILL) - fill with backslash
  4373.  
  4374.           * 7 (HATCH_FILL) - light hatch fill
  4375.  
  4376.           * 8 (XHATCH_FILL) - heavy cross hatch fill
  4377.  
  4378.           * 9 (INTERLEAVE_FILL) - interleaving line fill
  4379.  
  4380.           * 10 (WIDE_DOT_FILL) - widely spaced dot fill
  4381.  
  4382.           * 11 (CLOSE_DOT_FILL) - closely spaced dot fill
  4383.  
  4384.  
  4385.                                      - 73 -
  4386.  
  4387.  
  4388. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4389.  
  4390.  
  4391.           *  12  (USER_FILL)  -   user-defined   fill   pattern   (see
  4392.           Collection::setFillPattern())
  4393.  
  4394.      The following methods are provided for filling shapes:
  4395.  
  4396.  
  4397.      NAME                 ARGUMENTS            DESCRIPTION
  4398.  
  4399.      Nil::getFillSettings                      returns a Collection of 2
  4400.                                                Int values; the first is the
  4401.                                                current fill pattern; the
  4402.                                                second is the current fill
  4403.                                                color
  4404.      Int::setFillStyle    self, Int            sets the current fill
  4405.                                                pattern to the predefined
  4406.                                                pattern with a code of self
  4407.                                                and the current fill color
  4408.                                                to the Int arg
  4409.      Collection::setFillPatternself, Int            sets the current fill
  4410.                                                pattern to a user-defined
  4411.                                                Collection of 8 Int color
  4412.                                                values. Each Int value
  4413.                                                represents a byte of 8
  4414.                                                pixels; whenever a bit in
  4415.                                                the pixel pattern is set to
  4416.                                                1, the corresponding pixel
  4417.                                                will be plotted.  The Int
  4418.                                                arg is the fill color to
  4419.                                                use.
  4420.      Nil::getFillPattern                       returns the current
  4421.                                                user-defined fill pattern as
  4422.                                                a Collection of 8 Int
  4423.                                                values.
  4424.      Int::floodFill       self, Int, Int       fills an enclosed area on
  4425.                                                the graphics screen.  Self
  4426.                                                and the first Int arg form a
  4427.                                                "seek point": within the
  4428.                                                enclosed area to be filled.
  4429.                                                The are bounded by the color
  4430.                                                indicated in the second Int
  4431.                                                arg is flooded with the
  4432.                                                current fill pattern and
  4433.                                                fill color.  If the seed
  4434.                                                point is within an enclosed
  4435.                                                area, the the inside will be
  4436.                                                filled.  If the seed is
  4437.                                                outside the enclosed the
  4438.                                                area, then the exterior will
  4439.                                                be filled.
  4440.  
  4441.  
  4442.  
  4443.  
  4444.  
  4445.                                      - 74 -
  4446.  
  4447.  
  4448.                                               Chapter 13: Graphics Programming
  4449.  
  4450.  
  4451.      13.12 Fonts and Text in Graphics Mode
  4452.  
  4453.      You  can  also  output  text  in a variety of fonts, sizes, and styles
  4454.      from within dObject's BGI graphics mode.  Text output is  accomplished
  4455.      by  calling  the  String::outText()  or  Int:outTextXY() methods after
  4456.      defining a current character font.
  4457.  
  4458.  
  4459.      Text justification constants in horizontal mode:
  4460.  
  4461.           * 0 - left horizontal
  4462.  
  4463.           * 1 - center horizontal
  4464.  
  4465.           * 2 - right horizontal
  4466.  
  4467.      Text justification constants in vertical mode:
  4468.  
  4469.           * 0 - bottom vertical
  4470.  
  4471.           * 2 - top vertical
  4472.  
  4473.      dObject provides  the  following  methods  for  manipulating  text  in
  4474.      graphics mode:
  4475.  
  4476.  
  4477.      NAME                 ARGUMENTS            DESCRIPTION
  4478.  
  4479.      String::outText      self                 outputs a string to the
  4480.                                                current graphics position
  4481.                                                (CP).
  4482.      Int::outTextXY       self, Int, String    outputs String arg to x,y
  4483.                                                location of self, Int arg
  4484.      String::textHeight   self                 returns height of self in
  4485.                                                pixels as Int
  4486.      String::textWidth    self                 returns width of self in
  4487.                                                pixels as Int
  4488.      Nil::getTextSettings                      returns Collection of 4 Int
  4489.                                                values indicating current
  4490.                                                text font, direction, size,
  4491.                                                and justification
  4492.      Int::setTextJustify  self, Int            sets justification to
  4493.                                                horizontal code of self and
  4494.                                                vertical code of Int arg.
  4495.                                                 Horizontal values:
  4496.                                                0=left,1=center,2=right
  4497.                                                Vertical values:
  4498.                                                0=bottom,1=top
  4499.      Int::setTextStyle    self, Int, Int       sets current text font to
  4500.                                                self; sets current direction
  4501.                                                to first Int arg, and
  4502.                                                current char size to second
  4503.  
  4504.  
  4505.                                      - 75 -
  4506.  
  4507.  
  4508. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4509.  
  4510.  
  4511.                                                Int arg.  Text direction
  4512.                                                codes are 0=horizontal (left
  4513.                                                to right), 1=vertical
  4514.                                                (bottom to top).
  4515.      Int::setUserCharSize self, Int, Int, Int  sets width and height ratio
  4516.                                                for stroked fonts.  Sets
  4517.                                                scale factors for x width, x
  4518.                                                height, y width, and y
  4519.                                                height to self and the 3 Int
  4520.                                                args respectively.
  4521.  
  4522.      13.13 Viewports
  4523.  
  4524.      Your  system  contains  between one and four screen-page buffers where
  4525.      screen  images  are  stored  dot-by-dot,  depending  on  the  graphics
  4526.      hardware installed.    You  can  specify  which  screen page is active
  4527.      (where graphics methods place their output) and which page is  visible
  4528.      using  the  Int::setActivePage() and Int::setVisualPage() methods. You
  4529.      can specify a region of the display screen where  clipping  is  active
  4530.      through a call to the setViewPort() method.
  4531.  
  4532.  
  4533.      dObject provides the following viewport-related methods:
  4534.  
  4535.  
  4536.      NAME                 ARGUMENTS            DESCRIPTION
  4537.  
  4538.      Int::setViewPort     self, Int, Int, Int, sets the current viewport to
  4539.                           Int                  the absolute screen
  4540.                                                co-ordinates left, top,
  4541.                                                right, bottom corresponding
  4542.                                                to the self argument and the
  4543.                                                first three Int arguments
  4544.                                                respectively. The final Int
  4545.                                                arg is a flag indicating if
  4546.                                                clipping is on or off (0 =
  4547.                                                off, 1 = on).
  4548.      Nil::getViewSettings                      returns a Collection of 5
  4549.                                                Int value specifying the
  4550.                                                left, top right, and bottom
  4551.                                                screen co-ordinates of the
  4552.                                                current viewport, and an Int
  4553.                                                flag indicating if clipping
  4554.                                                is on or off.
  4555.      Int::setActivePage   self                 sets the active graphics
  4556.                                                page to page  number of
  4557.                                                self.
  4558.      Int::setVisualPage   self                 sets the visible graphics
  4559.                                                page to page number of self.
  4560.      Nil::clearViewPort   self                 clears the current viewport
  4561.                                                and moves the CP to (0,0).
  4562.      Nil::clearDevice     self                 clears the entire screen and
  4563.  
  4564.  
  4565.                                      - 76 -
  4566.  
  4567.  
  4568.                                               Chapter 13: Graphics Programming
  4569.  
  4570.  
  4571.                                                moves the CP to (0,0).
  4572.  
  4573.      13.14 Pixels and Images
  4574.  
  4575.      The  BGI  system also provides several methods for manipulating images
  4576.      and pixels on the graphics screen:
  4577.  
  4578.  
  4579.      NAME                 ARGUMENTS            DESCRIPTION
  4580.  
  4581.      Int::getPixel        self, Int            returns the pixel color at
  4582.                                                location x,y specified by
  4583.                                                self and Int arg
  4584.      Int::putPixel        self, Int, Int       sets the pixel at location
  4585.                                                x,y (self, Int arg) to color
  4586.                                                specified by second Int arg
  4587.      Int::getImage        self, Int            returns image stored at x,y
  4588.                                                of self, Int arg
  4589.      Int::imageSize       self, Int, Int, Int  returns an Int number of
  4590.                                                bytes necessary to store a
  4591.                                                rectangular area of the
  4592.                                                screen.  Args are left, top,
  4593.                                                right, and bottom
  4594.                                                co-ordinates of the region.
  4595.      Int::putImage        self, Int, Image, Intwrites an image to the
  4596.                                                screen at x,y of self, first
  4597.                                                Int arg.  Second Int arg
  4598.                                                specifies how bits of the
  4599.                                                image will be combined with
  4600.                                                bits already on the screen:
  4601.                                                copy = 0, xor = 1, or = 2,
  4602.                                                and = 3, not = 4.
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.  
  4610.  
  4611.  
  4612.  
  4613.  
  4614.  
  4615.  
  4616.  
  4617.  
  4618.  
  4619.  
  4620.  
  4621.  
  4622.  
  4623.  
  4624.  
  4625.                                      - 77 -
  4626.  
  4627.