home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-23 | 160.7 KB | 4,621 lines |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- dObject Version 1.0 User Guide
- Object-Oriented Programming Language for DBASE(tm)
- Copyright (c) 1991 Intelligent Systems Research
- All Rights Reserved
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- 1.0 Introduction
-
- 1.1 Introduction
-
- Welcome to Object-Oriented programming for DBASE(tm) ! dObject is an
- object-oriented programming language with built-in base classes for
- handling DBASE data, memo, and index files. Using dObject, you can
- build complex applications that use your existing DBASE files and a
- class library of over 15 classes and 300 methods. You can define
- your own classes and methods that inherit the features of the base
- classes. You can create new DBASE data, memo, and index files, and
- you can write graphics and full-color windowed hypertext applications
- that display your DBASE data.
-
-
- dObject includes the following features:
-
- * a fast, efficient interpreted language for writing
- object-oriented DBASE applications
-
- * a built-in full screen text editor callable from your
- applications with hypertext on-line help
-
- * over 300 built-in methods for integer and real
- arithmetic, characters, strings, and dates
-
- * a text-mode windowing system
-
- * a graphics system based on the Borland BGI
-
- * a pop-up menu facility
-
- * DBASE-like SAY and GET output to windows, and code for a
- full screen DBASE field editor
-
- * output logging to printers and DOS text files
-
- * LAN-compatible row and file locking of DBASE files
-
- * a powerful GREP-like pattern matching function for
- strings and DBASE character fields
-
- * a hypertext facility linked to DBASE
-
- * multi-dimensional arrays
-
- * an advanced Collection class for managing complex data
- structures
-
- * a C-style preprocesssor for constant definitions and
- program text inclusions
-
-
-
- - 2 -
-
-
- Chapter 1: Introduction
-
-
- dObject provides the following advantages over the DBASE programming
- language:
-
- * facilities for defining classes and methods that are far
- superior to the UDF facility in DBASE, including support
- for inheritance and polymorphism
-
- * advanced date handling including international formats,
- julian dates, and date arithmetic
-
- * facilities for providing sophisticated user interfaces
- for DBASE(tm) applications, including use of multiple,
- overlapping full-color windows and pop-up menus
-
- * facilities for building hypertext applications that use
- DBASE data and index files
-
- * graphics
-
- 1.2 Manual Overview
-
- This manual is both a user guide and a reference guide to dObject.
- The chapters include:
-
-
- * Chapter 1 - Introduction
-
- * Chapter 2 - Getting Started
-
- * Chapter 3 - dObject Statements
-
- * Chapter 4 - dObject Classes
-
- * Chapter 5 - Numeric Classes
-
- * Chapter 6 - Logical Operations
-
- * Chapter 7 - Characters and Strings
-
- * Chapter 8 - Dates
-
- * Chapter 9 - Windows and Menus
-
- * Chapter 10 - Arrays and Collections
-
- * Chapter 11 - Files and Devices
-
- * Chapter 12 - DBASE File Programming
-
- * Chapter 13 - BGI Graphics
-
-
-
-
- - 3 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- 1.3 How to Contact ISR
-
- If you need technical support or would like to contact Intelligent
- Systems Research with comments, suggestions, or questions about
- dObject, please write to us at:
-
-
- Intelligent Systems Research
- P.O. Box 3690
- Chicago IL 60654 USA
- (312)-878-6054
-
- CompuServ: Send E-mail to userid 70304,2520
-
-
- Please include your dObject version number, your computer make and
- model number, and your operating system make and model number if you
- have technical questions or need detailed technical support.
-
-
-
- 2.0 Getting Started
-
- 2.1 Hardware Requirements
-
- dObject requires the following minimal hardware configuration:
-
-
- * an 80286, 80386 or 80406 CPU
-
- * 640KB main memory
-
- * a hard disk drive
-
- * MS-DOS 3.0 or above
-
- 2.2 Installing dObject
-
- The shareware version of dObject does not need to be installed beyond
- the "unzip" of the distribution .ZIP file. The files DO.EXE,
- HELP.DBF, HELP.DBT, HELP.NDX, ERROR.DBF, ERROR.NDX, and DO.CFG should
- reside in the hard disk directory "DOBJECT".
-
- The registered version of dObject comes with an INSTALL program on
- the distribution diskette. The INSTALL program will prompt you for
- the name of a directory to create on your hard disk, and then copy
- the dObject distribution files to that directory. If you wish, you
- can duplicate this yourself by issuing the DOS commands below:
-
-
-
- C:\>md dobject
-
-
- - 4 -
-
-
- Chapter 2: Getting Started
-
-
- C:\>cd dobject
- C:\DOBJECT>copy a:do.exe
- C:\DOBJECT>copy a:do.cfg
- C:\DOBJECT>copy a:*.dbf
- C:\DOBJECT>copy a:*.dbt
- C:\DOBJECT>copy a:*.ndx
- C:\DOBJECT>copy a:*.do
- C:\DOBJECT>copy a:*.bgi
- C:\DOBJECT>copy a:*.chr
-
-
- You should also specify the DOBJECT directory as one of the PATH
- options in your DOS AUTOEXEC.BAT file. dObject will always look in
- the directory that the DO.EXE file is in for the HELP and ERROR
- databases (including memo and index files). Make sure that when you
- install dObject, all these files are in the same directory as the
- executable file DO.EXE, otherwise the on-line help and error
- reporting systems will not work properly.
-
-
- Because dObject provides direct access to existing DBASE III format
- files, and becuase dObject uses several DBASE III files in its
- runtime environment, you should set the DOS FILES and BUFFERS option
- in your config.sys file to at least the following values:
-
-
- FILES=20
- BUFFERS=20
-
-
- To run the BGI demonstration program (BGIDEMO.DO) you must also first
- define a DOS environment variable named BGIPATH. This variable must
- contain the name of the directory where the supplied BGI drivers and
- font files are stored. If you install dObject in the directory
- C:\DOBJECT, you should add this line to your autoexec.bat file:
-
- SET BGIPATH=C:\DOBJECT
-
-
- 2.3 Running dObject
-
- To run dObject, at the DOS prompt type "do":
-
-
- C:\>do
-
- dObject Version 1.0 (Shareware)
- Copyright (c) 1991 Intelligent Systems Research
- Please register this version for support and updates
- Press any key to continue...
-
-
-
-
- - 5 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Pressing any key at this point will cause dObject to issue the
- "dObject> " prompt and accept commands. (The registered version of
- dObject goes directly to the "dObject> " prompt without pausing;
- this is a small reminder to register the shareware version !). To
- run a dObject source program directly from the DOS prompt, type "do"
- followed by the name of the file to run, with a default extension of
- "DO". For example, to run the dObject program in the file "demo.do"
- in the current DOS directory, issue the command:
-
- C:\> do demo
-
-
-
- 3.0 dObject Statements
-
- 3.1 Statements
-
- dObject accepts statements at the "dObject>" prompt using free-form
- input. Statements can be entered in any number of lines but must be
- terminated with a semicolon. dObject will prompt for statement
- continuation with the "more>" prompt until a semicolon is entered.
- dObject accepts the following legal statements:
-
- STATEMENT DESCRIPTION
-
- help; enter online hypertext help system and
- display table of contents
- cls; clear screen (current window)
- exit; exit dObject and return to DOS (also
- recognizes "quit;")
- edit <filename>; edit file (default extension .DO) ESC
- - exit without saving changes; F10 -
- exit and save changes
- for(statement;exp;statement) execute statements for range of values
- <statements>
- while <exp> <statements> while expression is true execute
- statements
- if <exp> <statements> else conditional execution of statements
- <statements> with else clause
- if <exp> <statements> conditional execution of statements
- do <filename>; execute statements in file (default
- extension .DO)
- dos; suspend dObject and shell to DOS
- return(<exp>); return expression as method result
- show <item>; shows internal information about
- dObject. "show classes" shows defined
- classes, "show methods" shows defined
- methods, "show set" shows SET
- variables, "show variables" shows all
- defined user variables
- switch (exp) {<cases>} conditional execution of cases
- ? <exp>[,<exp>...]; print expression values in current
-
-
- - 6 -
-
-
- Chapter 3: dObject Statements
-
-
- window
- <exp>; evaluate the expression
-
- dObject accepts comments within source programs using the conventions
- of the "C" programming language. Comments must begin with the
- characters "/*" and end with the characters "*/". All characters in
- between, including spaces, tabs, and newlines, are treated as comment
- characters and are ignored by the interpreter. The following example
- demonstrates legal dObject comments:
-
-
- /*
- this is a comment
- */
- method Int::zero(self) /* comments are allowed anywhere */
- {
- return(0); % this is an end-of-line comment
- }
-
-
- To exit from dObject and return to the DOS prompt, issue the "exit"
- command:
-
-
- dObject> exit;
-
-
- To review the on-line hypertext help, issue the "help" command:
-
-
- dObject> help;
-
-
-
- dObject provides a way to execute other dObject program source files
- through the use of the "do" command with a filename to execute.
- dObject will supply a default extension of ".do" if you do not supply
- one. For example, to execute the statements in the file "test.do",
- issue the statement:
-
- dObject> do test;
-
-
- 3.2 Errors
-
- If you make an error in a dObject statement, dObject will attempt to
- locate the error and print out the offending statement with a
- relevant error message. The error display will be shown in an Error
- window displayed in the lower left corner of the screen. The
- complete list of error codes generated by dObject is contained in the
- supplied file ERROR.DBF.
-
-
-
- - 7 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- To produce the error displauy, dObject calls the built-in
- Int::onError() method and passes it the Int error code of the error.
- You can re-define this method in your applications to change the way
- that error messages are displayed:
-
-
- /*
- demonstration of the Int::onError() method
- this method is called whenever dObject detects a parse or runtime
- error in a program; normally dObject creates a 1-line window
- at the bottom of the display screen and prints out the error
- number, an error message, and the statement where the error
- was detected. you can re-define this method to handle errors
- for your own applications
- */
- method Int::onError(self)
- {
- w = new(Window,1,112,112," Error ",10,10,5,50);
- db = new(Dbffile,"error");
- ndx = new(Ndxfile,db,"error");
- seek(db,self);
- ? "ERROR ",self,": ",msg;
- readchar();
- remove(w);
- }
-
- /*
- cause an error
- */
- exit(10002);
-
-
- 3.3 Breaks
-
- To interrupt a dObject program during execution, press the Control
- key and the Break key at the same time (Ctrl-Break). This will cause
- dObject to issue an error message for the break, and then return to
- the dObject> prompt.
-
-
-
- 3.4 Preprocessor
-
- dObject includes a built-in preprocessor for defining compile-time
- constants and file includes. dObject accepts constant definitions of
- the form:
-
- #define NAME VALUE
-
-
-
-
-
-
- - 8 -
-
-
- Chapter 3: dObject Statements
-
-
- where NAME is the name of the constant to define, and VALUE is the
- value to assign to it. Values can be any single token of text, or
- any string of text delimited with double quotes. For example, the
- following are all legal dObject constant definitions:
-
-
- /*
- define some commonly used integer codes for characters
- */
- #define ESC 27
- #define CR 13
- #define TRUE "T"
- /*
- define an alias name for a dObject function
- */
- #define CURRENT_DATE "date()"
-
-
- Whenever dObject encounters a defined constant anywhere in the text
- of a program, it will substitute the defined text before parsing and
- executing the statement. Use of this technique makes your programs
- more readable and understandable. For example, the following code
- uses the constants defined above:
-
- /*
- read a character from the keyboard
- */
- c = inkey();
- if(c == ESC) ? "the escape key was pressed";
- if(c == CR) ? "the return key was pressed";
-
-
- A file can be included in the source text before it is parsed by
- using the "include" directive:
-
- #include "keydef.do"
-
-
- 3.5 Variables
-
- In dObject, variables are used to store any kind of value in memory
- for use by your program. The names of these variables must begin
- with a lower case alphabetic character (since upper case names are
- reserved for class names); and can then contain any number of
- alphabetic or numeric characters, as well as the underscore. The
- variable name must not be one of the following dObject reserved
- keywords: while, for, if, then, else, do, return or method.
-
- For example, the following are legal dObject variable names:
-
- * a
-
-
-
- - 9 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- * a1
-
- * my_variable
-
- The following are NOT legal variable names:
-
- * 1a (begins with a numeric character)
-
- * My_variable (begins with an uppercase character)
-
- * my-variable (uses the '-' character)
-
- * while (uses the reserved dObject keyword while)
-
- Variables use memory space within dObject that can be re-used later
- if your program no longer needs the variable. To reclaim the storage
- space for a variable, send the "release" message to an Exp object
- containing the name of the variable:
-
- dObject> a = 32;
- dObject> release(#a);
-
-
- 3.6 Literals
-
- Literal values are sequences of numbers, letters, and special
- characters that are interpreted as actual values by dObject, not
- variable names. dObject accepts literal values in the following
- formats (note that hex integer constants are defined using a leading
- dollar sign):
-
-
- CLASS FORMAT EXAMPLE
-
- Nil: nil nil
- Date: mm/dd/yyyy 5/10/1990
- Char: 'c' 'a'
- String: "ccc" "this is a string"
- Int (decimal): n 123
- Int (hex): $n $1ff
- Long: nL 123L
- Real: n.d 12.34
- Logical: T or F T
- Collection: [v1,v2,v3...] [1,2,$1ff,T,3.3,"four",'5',(1,"one"),5/10/90]
- Exp: #exp #date()
-
- 3.7 Expressions
-
- Expressions in dObject are combinations of literal values, variable
- names, and "messages". Messages are sent to objects in dObject either
- as operators or as named messages. Operators are special characters
- (usually one or two characters) that have a special meaning when
-
-
- - 10 -
-
-
- Chapter 3: dObject Statements
-
-
- applied to values, and are generally used in messages of the form
- "object operator object". For example, in dObject the expression 1 +
- 2 means send the "plus" message to Int 1 with an argument of Int 2.
-
-
- Named messages are always of the form name(object,args), where "name"
- is the name of the message to send, "object" is the object to send
- the message to, and "args" is zero or more values to use as arguments
- to the message. For example, the expression "clear(w)" in dObject
- means send the "clear" message to the object stored in the variable
- "w" (presumably a Window object) with no argument. The only exception
- to this convention are messages sent to the Nil object, which
- effectively have no object or arguments in the calling sequence. The
- expression "memory()" means send the "memory" message to the Nil
- object.
-
-
- dObject allows the assignment of values and expressions to variables
- through the use of the assignment operator, denoted by the equals (=)
- sign:
-
- dObject> v = 1+2*3;
-
-
- dObject recognizes literal expressions beginning with the '#'
- character and defers evaluation of the expression until runtime.
- Such expressions are useful when you are actually passing an
- expression to a method to evaluate later, such as using the built-in
- "avg" method on a DBASE(tm) file. The argument to the "avg" method
- is an expression to evaluate for each record in the file. For
- example, the following statements print the average length of the
- "lname" field within a DBASE(tm) file:
-
- dObject> db = new(Dbffile,"patient");
- dObject> ? avg(db,#len(trim(lname)));
-
-
- Passing the literal expression #len(trim(lname))) instructs dObject
- to defer evaluating the expression until the "avg" method runs; if
- you forget the '#' sign before the expression, dObject will evaluate
- the expression and pass the resulting Int value to the "avg" method
- as an argument, which will result in an error !
-
-
- 3.8 Program Control Statements
-
- dObject provides the "for", "while" and "switch" statements to
- control the flow of program execution, all of which are similar to
- their counterparts in the C programming language. The "for"
- statement executes a block of statements while an iteration
- expression is true:
-
-
-
- - 11 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- /*
- demonstrate the for statement
- */
- for(i=0;i<10;i=i+1) ? i;
-
-
- In this case, dObject will execute the first statement in the for
- expression, i=0, and then execute the statements in the block after
- the for expression. After each pass through the block, the statement
- i=i+1 will be executed, and the expression i<10 evaluated. If the
- expression is true dObject will continue to execute the statement
- block. Execution stops whenever the expression is found to be
- false. After the for statement is completed any variables used in
- the statements will still exist; in the above example i will have
- the value of 11 after the for statement executes.
-
-
- The "while" statement executes a block of statements while an
- expression evaluates to logical "true":
-
- /*
- demonstrate the while statement
- */
- i = 1;
- while(i < 10) {
- ? " i = ",i;
- i = i+1;
- }
-
-
- The "switch" statement is similar to the one found in the C
- programming language. An expression is evaluated and then matched
- against the values found in a series of "case" statements. The first
- case matching the expression value is executed:
-
-
- /*
- demonstrate the switch statement
- */
- i = 3;
- switch(i) {
- case 1: ? "i is one ";
- case 2: ? "i is two ";
- case 3: ? "i is three ";
- case 4: ? "i is four ";
- }
-
-
- In the above example only the statement ? "i is three " would
- execute within the switch.
-
-
-
-
- - 12 -
-
-
- Chapter 3: dObject Statements
-
-
- 3.9 Editing Text Files
-
- dObject provides a built-in full screen text editor for creating and
- modifying text files, including dObject source files. To invoke the
- editor, issue the "edit" command followed by the name of the file in
- the current directory to edit. dObject will supply a default
- extension of ".DO" for the file to make it easy to edit dObject
- source files. For example, to edit the file "test.do", issue the
- command:
-
- dObject> edit test;
-
-
- dObject will invoke the text editor in the current window, which by
- default is the full screen. Editing can occur in other windows by
- first creating the window and the issuing the "edit" command. The
- built-in editor is similar to the WordStar(tm) text editor and
- responds to the following keystroke commands:
-
-
- FUNCTION KEY
-
- View dObject help for word at cursor Ctrl-F1
- Move cursor right one character right arrow
- Move cursor left one character left arrow
- Move cursor up one line up arrow
- Move cursor down one line down arrow
- Scroll up one line Ctrl-W
- Scroll down one line Ctrl-Z
- Move cursor right one word Ctrl-Right arrow
- Move cursor left one word Ctrl-A
- Move cursor to right end of line End
- Move cursor to left end of line Home
- Move cursor to top of window Ctrl-Home
- Move cursor to bottom of window Ctrl-End
- Move cursor up one screen PgUp
- Move cursor down one screen PgDn
- Move cursor to top of file Ctrl-PgUp
- Move cursor to bottom of file Ctrl-PgDn
- Delete character at cursor Del, Ctrl-G
- Delete character left of cursor Backspace
- Delete word at cursor Ctrl-T
- Delete line at cursor Ctrl-Y
- Delete left from cursor to start of line Ctrl-Q T
- Delete right from cursor to start of line Ctrl-Q Y
- Mark beginning of block Ctrl-K B
- Mark end of block Ctrl-K K
- Copy (insert) marked block at cursor Ctrl-K C
- Move (insert) marked block at cursor Ctrl-K V
- Delete marked block Ctrl-K Y
- Write marked block to diskfile Ctrl-K W
- Write marked block to printer Ctrl-K P
-
-
- - 13 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Block select on/off Ctrl-K M
- Copy block to pastebuffer Ctrl-K I
- Move block to pastebuffer Ctrl-K Y
- Paste Ctrl-U
- Search Ctrl-F3 or Ctrl-Q F
- Search again Shift-F3 or Ctrl-O
- Replace F4
- Replace again Shift-F4 or Ctrl-L
-
- The key assignments for the editor are contained in the file "do.cfg"
- that is loaded at runtime by dObject. You can change these default
- combinations by calling the Nil::setupKeyboard() method from the
- dObject prompt, changing the key assignments using the menu choices
- provided, and then saving the current key configuration using the
- String::saveConfig method. The following example illustrates this
- procedure:
-
- dObject> setupKeyboard();
- dObject> saveConfig("new.cfg");
- dObject> exit;
- C:\DOBJECT:> rename do.cfg old.cfg
- C:\DOBJECT:> rename new.cfg do.cfg
-
-
- From within the Nil::setupKeyboard() method, a series of menu choices
- will be presented that allow you to choose the particular functions
- within the editor to be re-assigned to a key or keystroke
- combination. To redefine a command's keystroke(s), highlight the
- menu item for the command using the arrow keys and press Enter. In
- the input box that appears, you can define one or two sets of
- keystrokes for the command. Press Enter to skip over the first set
- of keystrokes, or press the new key combination for the first setup
- and then press Enter. When the cursor is in the second column, press
- Enter to skip the second setup, or press a new key combination
- followed by Enter. To abort this process at any time press the Esc
- key.
-
-
- Your application can load a special .CFG file at runtime using the
- String::loadConfig method and passing it the name of the file to
- load. The file should be one of the supplied .CFG files that comes
- with dObject, or a .CFG file you have created using the procedure
- described above.
-
-
- Comprehensive on-line help for editor commands is available from
- within the editor by pressing the F1 key. Help for dObject
- statements and built-in classes and methods is available from within
- the editor by placing the cursor on a dObject keyword, class name, or
- method name and pressing the Ctrl-F1 key.
-
-
-
-
- - 14 -
-
-
- Chapter 3: dObject Statements
-
-
- 3.10 Input and Output Statements
-
- The "?" statement prints the value of an expression onto the current
- window, followed by a carriage return and line feed:
-
- dObject> ? 1+1;
- 2
- dObject>
-
-
- The String::accept() method provides a simple way to write a prompt
- and read Strings from the keyboard:
-
- dObject> line = accept("enter value> ");
-
-
- For a detailed description of the input, output, and file handling
- capabilities of dObject, refer to the chapters titled "Files and
- Devices" and "Windows and Menus" later in this manual.
-
-
- 3.11 Output Logs
-
- dObject will also log the output from the "?" command to a file
- and/or an attached printer using the built-in log feature. Pressing
- the ALT-P key combination will display a popup menu showing the
- current on/off status of the logs to the printer and to the file
- PROLOG.LOG. To toggle the status from off to on and vice versa, use
- the arrow keys to position the menu bar, and press the RETURN key to
- toggle the value. Press the ESC key to exit the menu and return to
- the dObject prompt.
-
-
- 3.12 Environment Variables
-
- dObject maintains a small set of environment variables that can be
- set using the String::set() method and interrogated by the "show"
- command. These environment variables are:
-
-
- VARIABLE DEFAULT DESCRIPTION
-
- echo F when true, causes dObject to echo the
- statement just about to be executed to the
- current window
- hyperhelp T when true, allows use of Ctrl-F1 key from
- within editor to access dObject help stored
- in HELP.DBF file; when false, disables
- Ctrl-F1
- newline nl dObject will print this value at the end of
- each "?" statement
- prompt "dObject>" the String to be used as the command prompt
-
-
- - 15 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- softseek F when true, all String comparisons return true
- (T) if a "partial match" occurs; that is if
- the first string being compared is a
- substring of second string. when off,
- dObject returns true only if the strings
- being compared are identical, including
- trailing blanks
- space "" dObject will print this value between
- expressions in the "?" statement; normally
- set to a null String
- status T when true, status lines appear for text
- editor, window resize, etc. when false,
- turns off display of all status lines
- step F when true, causes dObject to pause between
- executing statements and print the message:
- Press SPACE to continue, ESC to abort...
- pressing the space key executes the next
- statement pressing the ESC key returns to the
- dObject> prompt
-
- To set an enviroment variable to a value, use the String::set method,
- with the "self" argument set to the name of the SET variable:
-
- dObject> set("echo",T);
-
-
- For example, to change the dObject prompt, set the prompt variable:
-
- dObject> set("prompt","--> ");
- -->
-
-
- To show the value of all the environment variables, use the "show
- set" command:
-
- dObject> show set;
- echo=logical(false)
- step=logical(false)
- softseek=logical(false)
- status=logical(true)
- hyperhelp=logical(true)
- prompt=string("dObject> ")
- space=char(' ')
-
-
- The value of a particular set variable is available by calling the
- String::set() method with self set to the name of the set variable to
- retrieve and with no other arguments:
-
- dObject> ? set("echo");
- F
-
-
-
- - 16 -
-
-
- Chapter 3: dObject Statements
-
-
- To show all the currently defined dObject variables, use the "show
- variables" command:
-
- dObject> a = 1;
- dObject> b = 2;
- dObject> show variables;
- a=1
- b=2
-
-
- To show all the classes you have defined in a dObject session beyond
- the built-in classes, use the "show classes" command (refer to the
- next chapter for a description of how to create these classes):
-
- dObject> show classes;
-
-
- To show all the methods currently defined, use the "show methods"
- command.
-
-
- 3.13 The RETURN Statement
-
- The return statement is used to return a value from a dObject method
- back to a calling program. The format of this statement is
- return(exp), where exp is any dObject expression as described above.
- The use of this statement is appropriate only when defining you own
- dObject classes and methods, a topic that is described in detail in
- the next chapter.
-
-
-
-
- 4.0 dObject Classes
-
- 4.1 Objects
-
- dObject provides a powerful facility for you to write complex
- applications using the "Object" paradigm. With this way of thinking,
- you define an object as something within the problem you are trying
- to solve that you want the computer to represent and store
- information about. For example, in a small business accouting
- system, the objects might include Companies, Departments, Employees,
- Products, and Accounts, to name but a few. Each of these objects has
- a certain correct behavior in the computer, such as a behavior to add
- a new Employee to a Company, or a behavior for calculating the profit
- from the sale of a Product to a Customer.
-
-
- In dObject, the object types within the application are called
- "Classes", and the rules that tell the computer how a class is to
- behave are called "Methods". Each class has a set of methods that it
-
-
- - 17 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- knows about that allow it to perform calculations on the class.
- dObject provides a large library of built in classes, each with its
- own set of methods, that allow you to create complex applications
- right away. However, to fully exploit the power of object-oriented
- programming, you will eventually want to create your own classes and
- methods that apply directly to the problems you want to solve. You
- create these new classes and methods by building them on top of the
- existing classes and methods.
-
-
- 4.2 Class Definitions
-
- To create a new object class, use the "inherit" message on an already
- existing dObject class:
-
- inherit(Parentclass,Newclass,variables);
-
-
- where "Newclass" is the name of the new class to define,
- "Parentclass" is the class to inherit from, and "variables" is an
- array of strings that name instance variables within the class. In
- dObject, the names of classes must always begin with an uppercase
- letter, followed by upper or lower-case characters or numerals. For
- example, the statement:
-
- inherit(Date,Mydate,["julian"]);
-
-
- You should use the "Nil" class as a parent class that does not
- inherit data or methods from any parent.
-
-
- To create a variable of a given class type, use the "new" message:
-
- v = new(Class,arguments)
-
-
- where "v" is the name of the variable to create, and "Class" is the
- object class of the variable. For example, to create a new instance
- of the "Mydate" class and store it into a variable named "d", use the
- statement:
-
- d = new(Mydate);
-
-
- dObject provides a number of base classes as building blocks,
- including:
-
- * Nil - an empty class
-
- * Int - 2-byte signed integers
-
-
-
- - 18 -
-
-
- Chapter 4: dObject Classes
-
-
- * Long - 4 byte signed integers
-
- * Real - floating point numbers
-
- * Char - single characters
-
- * String - strings of characters (up to 64K in length)
-
- * Logical - true (T) or false (F)
-
- * Date - dates
-
- * Array - an array of object at locations indicated by an
- index
-
- * Collection - an ordered collection of objects
-
- * File - DOS ASCII text files and devices (such as the
- printer)
-
- * Exp - literal dObject expressions that can be passed as
- arguments
-
- * Dbffile - DBASE files
-
- * Ndxfile - DBASE index files
-
- * Address - addresses of other objects
-
- The class of any dObject variable can always be found by sending the
- object the built-in "class" message:
-
- dObject> ? class(5/10/91);
- Date
- dObject> ? class("this is a test");
- String
- dObject> ? class(T);
- Logical
-
-
- 4.3 Method Definitions
-
- To create a named method for a class, use the format:
-
- method Class::name(self,arguments)
- {
- statements...
- }
-
-
-
-
-
-
- - 19 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Values are returned to the calling program through the use of the
- "return" statement. This should be the last statement executed from
- within a method. Methods that do not use a "return" statement have a
- return value of Nil.
-
-
- The special variable "self" always refers to the specific instance of
- the object that the method is being performed on. You can treat
- "self" as any other argument in the calling sequence. For example:
-
- method Mydate::asString(self)
- {
- return(asString(slot(self,"julian"));
- }
-
-
- defines a method for the "Mydate" class to convert itself to a
- String.
-
-
- To define an operator for a class, use the character representing the
- operator as the method name. For example, to define the '+' operator
- for the Mydate class:
-
- method Mydate::+(self,d)
- {
- return(asDate(julian(self) + julian(d)));
- }
-
-
- Variables within a class can be set by using the "replace" method,
- and referenced by the "slot" method. However, these two methods are
- only available from within methods defined for the class! This
- implements an important feature of object-oriented programming: data
- hiding. Using data hiding, it is good programming form to provide a
- method that returns the value of a variable within a class, instead
- of allowing a calling program to access that variable directly. That
- way, if the implementation of the object changes at some later date,
- and the variables within the class change, only the methods for the
- class need to understand the change ! The "outside world" still
- accesses information about the class through the methods.
-
-
- 4.4 Private Methods
-
- By default, methods defined using the syntax described above are
- "public" in scope - they are available to any other method or main
- program that wants to use them. In some cases, however, you may wish
- to define methods that are hidden from other methods in the same way
- that variables are hidden. dObject lets you do this by substituting
- the keyword "private" for "method" in the method definition. The
- following example shows how to define a private method for a class:
-
-
- - 20 -
-
-
- Chapter 4: dObject Classes
-
-
- private Mydate::yearPlusOne(self)
- {
- return(year(self)+1);
- }
-
-
-
- In the example above, the "yearPlusOne" method is only available to
- other methods of the Mydate class. Attempts to call it from a method
- of another class or from a main program will generate an error
- message.
-
-
- The following example illustrates the use of a private method:
-
-
- /*
- demo of a private method for a class
- private methods are only callable from within a method for a class
- */
- inherit(Nil,Temp,[]);
-
- private Temp::testPrivate(self)
- {
- ? "within testPrivate";
- }
-
- method Temp::test(self)
- {
- ? "enter Temp::test";
- testPrivate(self);
- ? "exit Temp::test";
- }
-
- v = new(Temp);
- test(v); % this will work, Temp::testPrivate will be called by Temp::test
- ? "the next statement will cause an error !...";
- testPrivate(v); % this will cause an error !
-
-
- 4.5 Friend Classes
-
- In some cases, you may wish to share the variables and/or the private
- methods defined for a class with another class. In this case,
- dObject provides the Exp::friend() method to allow such access. The
- following example shows how to define one class as a friend of
- another:
-
- /*
- demo of a private method for a class
- private methods are only callable from within a method for a class
- */
-
-
- - 21 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- inherit(Nil,Temp,[]);
- inherit(Nil,Temp2,[]);
-
- /*
- defining class Temp2 as a friend of class Temp
- means that methods of Temp2 can access variable and private
- methods of Temp
- */
- friend(Temp,Temp2);
-
- /*
- define a private method for Temp
- */
- private Temp::testPrivate(self)
- {
- ? "within Temp::testPrivate()";
- }
-
- /*
- define a public method for Temp2 that creates a variable of
- type Temp and calls a private method for it
- */
- method Temp2::test(self)
- {
- ? "enter Temp2::test";
- v = new(Temp);
- testPrivate(v); % this won't work unless Temp2 is a friend of Temp !
- ? "exit Temp2::test";
- }
-
- v = new(Temp2);
- test(v);
-
-
- 4.6 Inheritance
-
- dObject stores variables for classes you define by allocating storage
- for a variable of its parent class type, and storage for all the
- variables defined in the "inherit" statement for its class. For
- example, consider a class called "Time" that inherits its behavior
- from the Date class. The "Time" class also contains internal
- variables for hours, minutes, and seconds, as defined in the
- following statement:
-
-
- dObject> inherit(Date,Time,["hours","minutes","seconds"]);
-
-
- A new variable of type "Time" can be constructed as follows:
-
-
- dObject> t = new(Time,7/20/1990,1,2,3);
-
-
- - 22 -
-
-
- Chapter 4: dObject Classes
-
-
- Internally, the variable "t" would be stored as an object of class
- "Time", with 4 internal variables. The first variable is of type
- Date (the parent class), with the value of 7/20/1990. The remaining
- variables are the values for "hours", "minutes", and "seconds" as
- defined in the inherit statement above, with values of 1, 2, and 3
- respectively.
-
-
- dObject classes "inherit" all the variables and methods from their
- parent class. If you send a message to a variable of a class you
- create and a method for the message has not been defined, dObject
- will begin searching backwards through the parent class(es) to try to
- find a method definition it can use. If a method is found, the
- variable storing the parent class value is passed to the method,
- without any of the variables for the original class. This process
- continues until no more parent classes are found.
-
-
- For example, if you send the "asString" message to a Time variable as
- defined below, and you have not defined a version of "asString" for
- the Time class, then dObject will take the parent Date value and send
- it the "asString" message:
-
-
- dObject> inherit(Date,Time,["hours","minutes","seconds"]);
- dObject> t = new(Time,7/20/1991,1,2,3);
- dObject> ? asString(t);
- 7/20/1991
-
-
- 4.7 Parameter Passing
-
- dObject normally passes arguments to methods by creating an internal
- stack and pushing the value for all the arguments to the method onto
- it. This is exactly the way the C language calls functions.
- However, in dObject, this implies that you cannot internally change
- the value of a variable within a class, but must instead return a
- copy of the variable containing the change. This leads to an easy
- error to make:
-
- /*
- define a class for Money
- */
- inherit(Int,Money,["cents"]);
-
- method Money::setCents(self,c)
- {
- return(replace(slot(self,"cents"),i));
- }
-
-
- /*
-
-
- - 23 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- create a variable of type Money
- */
- m = new(Money);
- setCents(m,100); % this is wrong !
-
-
- While it may appear simple to set a Money variable to a value from a
- calling program, be careful ! You must remember to store the
- returned copy of the variable back into itself:
-
- /*
- assign "m" a value the wrong way
- */
- setCents(m,100); % this returns a copy of m with "cents"=100 that is lost
-
- /*
- assign "m" a value the right way
- */
- m = setCents(m,100); % this stores the copy back in m !
-
-
- dObject allows a program to circumvent the need to always pass copies
- of variables around through the use of the Address class. Using the
- "address-of" operator (the "&" symbol, as in C), you can instead pass
- the address of a variable to a method:
-
- setCents(&m,100);
-
-
- However, to do this correctly, the method must be expecting an
- address of a variable and not a copy of the variable itself. This is
- done by using an asterik before the argument in the method definition
- wherever an address is to be used. The following example shows how
- to define and use a method that replaces the value of an internal
- class variable directly in memory:
-
-
- /*
- define a new version of the setCents method that
- replaces a memory location and does not return a copy
- */
- method Money::setCents(*self,c)
- {
- replace(slot(*self,"cents"),c);
- }
-
- /*
- now this is OK !
- */
- m = new(Money);
- setCents(&m,100); % m will be updated in-place
-
-
-
- - 24 -
-
-
- Chapter 4: dObject Classes
-
-
- To access the contents of an address, use the "contents" operator
- (the asterik character), again just like in the C language:
-
- dObject> ?class(&1);
- Address
- dObject> ? *&1;
- 1
-
-
- 4.8 Space Management
-
- To reclaim the space used by a variable, send an expression
- containing the name of the variable the "release" message:
-
- dObject> a = 1;
- dObject> release(#a);
-
-
- To reclaim the space used by a method definition once it is no longer
- needed by your program, use the "release" method of the Exp class.
- Send the message to the Class name for the method you wish to delete,
- and pass the message a String argument containing the method name:
-
- dObject> release(Myint,"value");
-
-
- To reclaim all the space used by a class, including its definition,
- its methods, and any variables, use the releaseClass method:
-
- dObject> releaseClass(Mydate);
-
-
- 4.9 Input and Output
-
- To print the value of an object (while executing the "?" command, for
- example), dObject first sends the object the "asString" method to try
- to convert it to a String. If this succeeds, the resulting String is
- printed and the next object to print is processed. Each of the
- built-in classes provided in dObject has an asString method defined
- for it. If there is no such method for the class, dObject attempts
- to print a representation of the internal form of the object. For
- user defined classes, this printout will be of the form:
-
- object(Class,[slot(Name,Value)...])
-
-
- 4.10 Sample Application
-
- As a final example of how to create classes and methods, the
- following program completes the implementation of the abstract class
- "Money" used in the examples above:
-
-
-
- - 25 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- /*
- this is an example of a class to handle money as an abstract type
- first, define a Money class with a variable to hold an
- integer number of cents; this will be converted into
- dollars and cents whenever the Money variable is converted to a String
- */
- inherit(Int,Money,[]);
-
- /*
- set the number of cents in self
- NOTE: self must be passed by address for this to work !
- */
- method Money::setCents(*self,c)
- {
- replace(parent(*self),c);
- }
-
- /*
- return the number of dollars in self
- */
- method Money::dollars(self)
- {
- return(self/100);
- }
-
- /*
- return the number of cents in self
- */
- method Money::cents(self)
- {
- return(self - (dollars(self)*100));
- }
-
- /*
- the "asString" method allows a Money variable to be converted
- to a String and/or printed
- */
- method Money::asString(self)
- {
- return("$ "+asString(dollars(self))+"."+format(cents(self),"%02d"));
- }
-
- method Int::asMoney(self)
- {
- return(new(Money,self));
- }
-
- /*
- test case
- */
- m = new(Money,100);
- setCents(&m,104);
-
-
- - 26 -
-
-
- Chapter 4: dObject Classes
-
-
- ? m;
- ? asMoney(m+1);
- ? asMoney(m*10);
-
-
-
-
- 5.0 Numeric Classes
-
- 5.1 Numeric Classes
-
- dObject supports three types of numeric classes: Int, Long, and
- Real. Class Int supports signed 2-byte integer values between
- -32,768 to 32,767. Long values are signed 4-byte integer numbers in
- the range -2147483648 to 2147483647. Real numbers are 8 bytes long
- and in the range -1e+307 to 1e+308. dObject provides operators for
- performing arithmetic on Int, Long and Real classes. For example, to
- add two integers together to get a third, send the "plus" message to
- the first integer, using the second integer as an argument. This is
- accomplished in the statement:
-
- dObject> n = 1+2;
- dObject> ? n;
- 3
-
-
- where the variable "n" will be assigned the value Int 3. dObject
- responds to the '+' (plus), '-' (minus), '*' (multiply), and '/'
- (divide) operators on both Int and Real variables. Mixed mode
- arithmetic is also supported for calculations involving Ints and
- Reals, in which case the result is always Real. Mixed mode
- arithmetic involving Long values is not supported.
-
-
- A wide variety of named messages are supplied for numeric classes,
- including:
-
-
- * max(self,Int), max(self,Real), max(self,Long) - returns
- max value of self and arg
-
- * min(self,Int), min(self,Real), min(self,Long) - returns
- min value of self and arg
-
- * abs(self) - returns absolute value of self (Int or Real)
-
- * log(self) - returns log base e of self (Real)
-
- * log10(self) - returns log base 10 of self (Real)
-
- * sqrt(self) - returns square root of self(Real)
-
-
-
- - 27 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- * sin(self) - returns sine of self (Real, self in radians)
-
- * cos(self) - returns cosine of self(Real, self in radians)
-
- * tan(self) - returns tangent of self (Real, self in
- radians)
-
- Refer to the accompanying file "CLASSLIB.DOC" for a complete
- description of the built-in numeric methods and operators.
-
-
- Of course, you can define new methods for the numeric classes if you
- so choose. This example show defining a new method "factorial" for
- the Long class, which calls itself recursively:
-
- /*
- define a recursive factorial method for the "Long" class
- */
- method Long::factorial(self)
- {
- if(self <= 1L) return(self);
- else return(self*factorial(self-1L));
- }
-
- /*
- calculate some factorials
- */
- i = 0;
- while(i < 10) {
- ? i," ",factorial(asLong(i));
- i = i+1;
- }
-
-
-
- 6.0 Logical Operations
-
- 6.1 Logical Operations
-
- dObject provides the built-in class "Logical" for representing the
- boolean values of "true" and "false". dObject also provides built-in
- operators for a variety of comparison operations between classes that
- result in a Logical value:
-
-
- OPERATOR NAME CLASS(ES) DESCRIPTION
-
- [eq][eq] equal all returns true if self
- and arg are equal
- != not equal all returns true if self
- and arg are not
- equal
-
-
- - 28 -
-
-
- Chapter 6: Logical Operations
-
-
- > greater than Int,Real,Char,String returns true if self
- greater than arg
- >= greater than/eqInt,Real,Char,String returns true if self
- greater than or
- equal to arg
- < less than Int,Real,Char,String returns true if self
- less than arg
- <= less than/eq Int,Real,Char,String returns true if self
- less than or equal
- to arg
-
- To create a logical value, use the "new" method, a literal Logical
- value, or make an assignment using one of the comparison operators
- above:
-
- dObject> l = new(Logical);
- dObject> l = T;
- dObject> l = 1 < 2;
-
-
-
- 7.0 Characters and Strings
-
- 7.1 Characters and Strings
-
- dObject provides the built-in classes "Char" and "String" for
- handling character calculations. A Char literal should be a single
- character surrounded by single quotes, while a String literal can be
- any number of characters delimited by the double quote character.
-
-
- To create a string, use the "new" method or make an assignment using
- a literal:
-
- dObject> s = new(String);
- dObject> s2 = "this is a string";
-
-
- To find the length of a String, use the "len" method:
-
- dObject> ? len(String);
- 16
-
-
- Strings respond to the normal set of comparison operators (==,!=, <,
- <=,>, >=). Trailing blanks can be removed from a String by the
- "trim" method:
-
- dObject> ? len(trim("aaa "));
- 3
-
-
-
-
- - 29 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Strings can be concatenated together using the "+" operator:
-
- dObject> a = "string1";
- dObject> b = "string2";
- dObject> ? a + " and " + b;
- "string1 and string2"
-
-
- To access a particular character in a String, use the "at" method:
-
- dObject> c = at("test",2);
- dObject> ? c;
- e
-
-
- The same built-in text editor that is used by the "edit" command to
- edit text files is callable as a method of the String class. This
- causes the contents of the string to be edited in the current window,
- and returns the value of the edited string. For a read-only display
- of the string contents in the current window with no editing allowed,
- use the "display" method:
-
- dObject> s = "this is a string";
- dObject> edited_string = edit(s);
- dObject> display(edited_string);
-
-
- dObject also provides String methods to interface directly with DOS.
- A DOS command within a String can be executed using the "system"
- method, passing it the command string in the "self" argument and an
- Int indicator for resetting the screen to the state it was in prior
- to executing the command string (0=do not reset, 1=reset):
-
- dObject> cmd = "dir *.do";
- dObject> system(cmd,0);
-
-
- The value of a DOS environment variable can be accessed through the
- "envSymbol" method:
-
- dObject> s = envSymbol("path");
-
-
- A named file can be edited using the "editFile" method:
-
- dObject> editFile("test.txt");
-
-
- The contents of an existing DOS file can be placed in a String very
- quickly by the "fileString" method, where "self" is the name of the
- file:
-
-
-
- - 30 -
-
-
- Chapter 7: Characters and Strings
-
-
- dObject> text = fileString("test.do");
- dObject> edit(text);
-
-
- String values can be converted to Int, Real, Date, and Logical values
- using the "asInt", "asReal", "asDate", and "asLogical" methods
- respectively:
-
- dObject> s = "123";
- dObject> ? class(asInt(s))," ",asInt(s);
- Int 123
-
-
- String values can be forced to upper or lower case using the
- "asUpper" and "asLower" methods:
-
- dObject> s = "This is a Test";
- dObject> ? asUpper(s);
- THIS IS A TEST
- dObject> ? asLower(s)
- this is a test
-
-
- dObject provides a pattern match function in the String::match()
- method. This method matches a pattern against the string and returns
- a Int index specifying the portion of the string that matched the
- pattern:
-
- dObject> s = "This is a test";
- dObject> ? match(s,"is a test");
- 6
-
-
- The special codes recogized by the String::match() method are those
- recognized by the UNIX GREP utility and include:
-
-
- * ' start-of-line anchor
-
- * '$' end-of-line anchor
-
- * '.' matches any character
-
- * '[' start a character class
-
- * ']' end a character class
-
- * ' negates character class if 1st char
-
- * '*' Keene closure (matches 0 or more)
-
- * '+' positive closure (1 or more)
-
-
- - 31 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- * '?' optional closure (0 or more)
-
- There are other String methods provided by dObject that are described
- in CLASSLIB.DOC.
-
-
-
- 8.0 Dates
-
- 8.1 Dates
-
- dObject provides a rich set of methods for handling dates using the
- built-in "Date" class. To create a new date variable, use the "new"
- method, or a date literal:
-
- dObject> d = new(Date);
- dObject> d = 5/1/91;
-
-
- The built in Nil::date() method returns the current system date as a
- Date variable.
-
-
- You can access the month, day, and year parts of a date using the
- "month", "day", "year", and "century" methods. For example, the
- expression below will return just the year of the current date as an
- Int:
-
- dObject> ? year(date());
-
-
- You can also set the values of these parts of the date using the
- "setMonth", "setDay", "setYear", and "setCentury" methods:
-
- dObject> d = date();
- dObject> d = setMonth(d,1);
-
-
- dObject supports the addition and subtraction of an integer number of
- days to and from a Date variable, and also supports conversion of
- Dates to a julian value. For example, to find the date that is 30
- days from the current date:
-
- dObject> future_date = date()+30;
-
-
- The "asJulian" method returns a Real value that is the julian date
- for a Date value. The Real::asDate method performs the inverse
- operation, returning a Date for a given julian number:
-
- dObject> j = asJulian(date());
- dObject> d = asDate(j);
-
-
- - 32 -
-
-
- Chapter 8: Dates
-
-
- Dates can be formatted into and from String variables in a variety of
- formats, including international formats. dObject provides the
- "asString" method for the Date class and the "asDate" method for the
- String class to accomplish these format conversions. In both cases a
- format String is passed to the method indicating how the date is to
- be formatted or scanned:
-
- /*
- test the dObject date conversion functions
- */
- ? date();
- s = asString(date(),"MMM DD/YY");
- ? s;
- d = asDate(s,"MMM DD/YY");
- ? d;
-
-
- The valid date format codes recognized by dObject are:
-
- * CC 2-digit century
-
- * YY 2-digit year
-
- * MM 2-digit month
-
- * MMM 3-char month (JAN, FEB, etc.)
-
- * DD 2-digit day
-
- These codes can be used in format strings to indicate how the date
- should be formatted or scanned. For example, the following are
- typical date formats:
-
- * YY.MM.DD
-
- * CCYY.MM.DD
-
- * MM/DD/YY
-
- * DD-MM/YY
-
- * DD-MM/CCYY
-
- * MMM DD/YY
-
- As a final example, the following code implements the "cday" method,
- which returns a String that contains the name of the day for the
- date:
-
- /*
- this is an example of how to define methods for the built-in
- Date class
-
-
- - 33 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- "cday" returns a character string naming the day
- */
- method Date::cday(self)
- {
- if(dow(self) == 1) return("Sunday");
- if(dow(self) == 2) return("Monday");
- if(dow(self) == 3) return("Tuesday");
- if(dow(self) == 4) return("Wednesday");
- if(dow(self) == 4) return("Thursday");
- if(dow(self) == 5) return("Friday");
- if(dow(self) == 6) return("Saturday");
- }
-
-
- /*
- define the same function, using the "switch" statement
- */
- method Date::cday2(self)
- {
- switch(dow(self)) {
- case 1: return("Sunday");
- case 2: return("Monday");
- case 3: return("Tuesday");
- case 4: return("Wednesday");
- case 5: return("Thursday");
- case 6: return("Friday");
- case 7: return("Saturday");
- }
- }
-
- /*
- call the methods defined above
- */
- ? cday(date());
- ? cday2(date());
-
-
-
- 9.0 Windows and Menus
-
- dObject provides classes that allow you to write professional-looking
- applications that use character-cell windows and pop-up menus. The
- "?" command, the "say" method of the Window class, and the built-in
- "Field" base class all send their output to a specified window.
-
-
- 9.1 Windows
-
- Windows are created using the "new" method, and passing it the window
- number, window attribute, frame attribute, title, left corner y,x
- position, and the y and x lengths for the window as parameters. The
- x,y co-ordinates of a window or other object within a window are
-
-
- - 34 -
-
-
- Chapter 9: Windows and Menus
-
-
- always counted down and right from the (0,0) origin in the upper left
- corner. For example, to create a new window that is the size of the
- entire screen, contains the title "test window", and has a white on
- blue display color and a lite blue border:
-
- dObject> w = new(Window,1,31,3,"test window",0,0,24,80);
-
-
- Color attributes can be calculated from the following formula:
-
- * Choose one foreground color and one background color
-
- * Add the corresponding integer values below.
-
- * Add 128 if you want whatever is displayed with that
- attribute to blink
-
- BACKGROUND FOREGROUND
-
- Black 0 Black 0
- Blue 16 Blue 1
- Green 32 Green 2
- Cyan 48 Cyan 3
- Red 64 Red 4
- Magenta 80 Magenta 5
- Brown 96 Brown 6
- White 112 White 7
- Grey 8
- Light Blue 24
- Light Green 40
- Light Red 72
- Light Magenta 88
- Yellow 104
- White (High 120
- Intensity)
-
- You can also include the supplied file "COLORS.DO" that defines
- symbolic names for the colors.
-
-
- When the "new" method creates the window it also displays it
- immediately and makes the new window the current window. To write
- output to a window, you must first make the window current. You can
- do this explicitly by sending the window the "shiftwindow" message:
-
- dObject> shiftwindow(w);
-
-
- You can always obtain the current window as a Window object through a
- call to the Nil::currentWindow() method:
-
- dObject> shiftwindow(currentWindow());
-
-
- - 35 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- You can clear the contents of a window with the "clear" message. To
- remove a window from the screen, send it the "remove" message:
-
- dObject> remove(w);
-
-
- To interactively resize or setup the color for a window, use the
- "resize" and "setupColor" methods. These methods allow for
- interactive resizing and color setup using the cursor keys and a
- color display that shows the foreground and background colors
- available as well as the color attribute number. When interactively
- resizing a window, use the following keys to change the window's
- size:
-
-
- * Width - Press the left arrow key to make the window
- narrower or the right arrow key to make it wider. To make
- changes in larger increments, hold down the Ctrl key at the
- same time. Use the end key to expand the window at the
- start of the screen.
-
- * Length - Press the up arrow key to decrease or the down
- arrow key to increase the length of the window. Use the
- page down key to extend the window to the bottom of the
- screen and the page up key to extend the window to the top
- of the screen.
-
- To change the position of the window on the screen, use the following
- keys:
-
- * Shift-Up Up one row
-
- * Shift-Down Down one row
-
- * Shift-Right Right one column
-
- * Shift-left Left one column
-
- * Shift-Home To left screen edge
-
- * Shift-End To right screen edge
-
- * Shift-PgUp To top of screen
-
- * Shift-PgDn To bottom of screen
-
- * Ctrl-Home To top left screen corner
-
- * Ctrl-End To bottom left screen corner
-
- * Ctrl-PgUp To top right screen corner
-
-
-
- - 36 -
-
-
- Chapter 9: Windows and Menus
-
-
- * Ctrl-PgDn To bottom right screen corner
-
- To setup the color for the window text, pass the setupColor method an
- Int argument of 0; to setup the color of the frame, pass it an Int
- argument of 1. For example, the following statement invokes the
- setup display for the color of the current window:
-
- dObject> setupColor(currentWindow(),0);
-
-
- dObject creates windows with a default frame consisting of a
- single-width line border, and with the window title centered above
- the window in the border. to change this, you can use the "setFrame"
- message. The first argument to setFrame is the color attribute of
- the frame, followed by the title of the frame, the integer position
- to place the title counting from the left-hand side (a value of 0
- instructs dObject to center the title), and finally a String
- containing 6 characters to build frame with using the following
- convention:
-
- * 1st char: Upper left corner
-
- * 2nd char: Upper right corner
-
- * 3rd char: Lower left corner
-
- * 4th char: Lower right corner
-
- * 5th char: Horizontal line
-
- * 6th char: Vertical line
-
- For example, to frame a window with the title "My Window" starting at
- position 3, with a white frame and a the '#' character for a border,
- use the message:
-
- dObject> setFrame(w,7,"My Window",3,"######");
-
-
- 9.2 Output using SAY and GET
-
- dObject provides methods to build full-screen data entry and review
- forms through the Int::say() and Window::say() methods, and through
- the built-in Field base class. The SAY/GET facility in dObject is
- similar in function to the @ say and @ get commands provided by the
- DBASE language. In dObject these methods work within a window,
- providing a way to create very sophisticated data handling forms.
-
-
- To produce output from an expression at a y,x point within a window,
- send the window the Int y coordinate, the Int x coordinate, the
- expression to output, an Int length of the field to display, and an
-
-
- - 37 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Int color attribute to display the expression in:
-
- dObject> say(currentWindow(),5,5,"this is a test",14,7);
-
-
- To set up a get field for input, call the Exp::new method for the
- class "Field", and send it the Window to place the field in, the Int
- y coordinate, the Int x coordinate, a String name of the variable to
- place the result into, an Int length of the field to display, and Int
- color attribute. Make sure that the variable you will store the
- value into is already defined:
-
- dObject> a = "this is a test";
- dObject> new(Field,currentWindow(),6,6,"a",14,112);
-
-
- Alternatively, the field name can be the name of a DBASE field in the
- currently active DBF file:
-
- dObject> db = new(Dbffile,"patient");
- dObject> new(Field,currentWindow(),6,6,"lname",14,112);
-
-
- The Exp::new(Field,...) method returns a variable of type Field that
- represents the field within the window. Once defined, a list of get
- variables can be read in a full-screen input mode using the
- Window::read() method:
-
- dObject> read(currentWindow());
-
-
- Entering this mode causes dObject to position the cursor at the
- beginning of the first get field defined, and to wait for the user to
- enter new values for data fields and scroll through records in the
- current Dbffile. The specific keys recognized are:
-
-
- KEY ACTION DESCRIPTION
-
- Esc Escape exits the form and returns to dObject>
- prompt
- Home Goto top Positions the current DBF file at the
- first record and displays it
- End Goto bottom Positions the current DBF file at the
- last record and displays it
- PgUp Prev Record Positions the current DBF file at the
- previous record and displays it
- PgDn Next Record Positions the current DBF file at the
- next record and displays it
- Tab Next Field Positions the cursor at the beginning of
- the next display field
- Up Up cursor Positions the cursor up one line
-
-
- - 38 -
-
-
- Chapter 9: Windows and Menus
-
-
- Down Down cursor Positions the cursor down one line
- Right Right cursor Positions the cursor right one space
- within current display field
- Left Left cursor Positions the cursor left one space
- within the current display field
- F10 Quit exits the form and returns to dObject>
- prompt
-
- You can modify the actions associated with these or any other key
- while in read mode by calling the Int::onKey() method and passing it
- an expression to evaluate. For example, the following example shows
- how to call the built-in text editor to edit the contents of a GET
- field by pressing the F8 key while in read mode:
-
-
- /*
- this method implements a callable text editor for the contents of
- a field
- */
- method Window::myEdit(self)
- {
- f = currentField(self);
- s = eval(asId(name(f)));
- if(class(s) == "String") {
- w = new(Window,1,31,3,name(f),5,5,10,40);
- display(s);
- remove(w);
- gotoField(self,f);
- }
- }
-
- db = new(Dbffile,"patient");
- new(Field,currentWindow(),6,6,"lname",14,112);
- onKey(w,F8,#myEdit(w));
- read(currentWindow());
-
-
- To clear the existing list of get variables from future reads, use
- the Window::clearGets() method:
-
- dObject> clearGets(currentWindow());
-
-
- The following example program shows setting up two get fields with
- prompts:
-
- /*
- sample full screen field output
- */
- w = new(Window,1,31,3,"",0,0,24,80);
- clearGets(2);
- a = "test";
-
-
- - 39 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- b = "test2";
- say(w,5,5,"field a",7,7);
- say(w,6,5,"field b",7,7);
- new(Field,w,5,20,"a",10,112);
- new(Field,w,6,20,"b",10,112);
- read(w);
- remove(w);
-
-
- 9.3 Pictures
-
- You can assign a picture template to a GET field that will cause
- dObject to format the value being displayed in the field, and
- validate keystrokes upon entry to the field. Do this by calling the
- Field::setPicture() method, and passing it a String containing the
- picture:
-
-
- dObject> a = "test";
- dObject> f = new(Field,w,5,20,"a",10,112);
- dObject> setPicture(f,"!!!!!!!!!!");
-
-
- dObject recognizes the following picture code characters:
-
- * ! - Converts letters to uppercase; accepts all
- characters
-
- * A - Allows letters only
-
- * L - Translates characters to logical values (T, t, F, f,
- Y, y, N, n)
-
- * N - Allows letters and numbers
-
- * 9 - Allows digits only
-
- * X - Allows numbers, spaces, signs, and decimal points
- only
-
- * Other characters are copied literally into the displayed
- value
-
- The following example demonstrates the use of picture clauses:
-
-
- /*
- demonstrate the use of a picture within a GET field
- */
- w = currentWindow();
- clearGets(w);
- cls;
-
-
- - 40 -
-
-
- Chapter 9: Windows and Menus
-
-
- a = "test";
- prompt = "Enter a value: ";
- say(w,5,5,prompt,len(prompt),7);
- f = new(Field,w,5,len(prompt)+5,"a",10,112);
- setPicture(f,"!!!!!!!!!!");
- read(w);
- ? "the value you entered was ",a;
-
-
- 9.4 Key Codes
-
- The special key codes recognized by the Window::read() and
- Nil::inkey() methods are defined in the supplied file KEYDEF.DO (you
- can include this file in programs by using the #include preprocessor
- statement):
-
- #define BACK_SPACE "$08"
- #define TAB "$09"
- #define ESC "$1B"
- #define CTRL_A "$01"
- #define CTRL_B "$02"
- #define CTRL_C "$03"
- #define CTRL_D "$04"
- #define CTRL_E "$05"
- #define CTRL_F "$06"
- #define CTRL_G "$07"
- #define CTRL_H "$08"
- #define CTRL_I "$09"
- #define CTRL_J "$0A"
- #define CTRL_K "$0B"
- #define CTRL_L "$0C"
- #define CTRL_M "$0D"
- #define CTRL_N "$0E"
- #define CTRL_O "$0F"
- #define CTRL_P "$10"
- #define CTRL_Q "$11"
- #define CTRL_R "$12"
- #define CTRL_S "$13"
- #define CTRL_T "$14"
- #define CTRL_U "$15"
- #define CTRL_V "$16"
- #define CTRL_W "$17"
- #define CTRL_X "$18"
- #define CTRL_Y "$19"
- #define CTRL_Z "$1A"
- #define RETURN "$D"
- #define HOME "$4700"
- #define END "$4F00"
- #define PGUP "$4900"
- #define PGDN "$5100"
- #define UP "$4800"
- #define DOWN "$5000"
-
-
- - 41 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- #define RIGHT "$4D00"
- #define LEFT "$4B00"
- #define SHIFT_TAB "$0F00"
- #define INS "$5200"
- #define DEL "$5300"
-
- #define CTRL_HOME "$7700"
- #define CTRL_END "$7500"
- #define CTRL_PGUP "$8400"
- #define CTRL_PGDN "$7600"
- #define CTRL_RIGHT "$7400"
- #define CTRL_LEFT "$7300"
-
- #define ALT_1 "$7800"
- #define ALT_2 "$7900"
- #define ALT_3 "$7A00"
- #define ALT_4 "$7B00"
- #define ALT_5 "$7C00"
- #define ALT_6 "$7D00"
- #define ALT_7 "$7E00"
- #define ALT_8 "$7F00"
- #define ALT_9 "$8000"
- #define ALT_0 "$8100"
- #define ALT_MINUS "$8200"
- #define ALT_EQUAL "$8300"
-
- #define ALT_Q "$1000"
- #define ALT_W "$1100"
- #define ALT_E "$1200"
- #define ALT_R "$1300"
- #define ALT_T "$1400"
- #define ALT_Y "$1500"
- #define ALT_U "$1600"
- #define ALT_I "$1700"
- #define ALT_O "$1800"
- #define ALT_P "$1900"
-
- #define ALT_A "$1E00"
- #define ALT_S "$1F00"
- #define ALT_D "$2000"
- #define ALT_F "$2100"
- #define ALT_G "$2200"
- #define ALT_H "$2300"
- #define ALT_J "$2400"
- #define ALT_K "$2500"
- #define ALT_L "$2600"
-
- #define ALT_Z "$2C00"
- #define ALT_X "$2D00"
- #define ALT_C "$2E00"
- #define ALT_V "$2F00"
- #define ALT_B "$3000"
-
-
- - 42 -
-
-
- Chapter 9: Windows and Menus
-
-
- #define ALT_N "$3100"
- #define ALT_M "$3200"
-
- #define F1 "$3B00"
- #define F2 "$3C00"
- #define F3 "$3D00"
- #define F4 "$3E00"
- #define F5 "$3F00"
- #define F6 "$4000"
- #define F7 "$4100"
- #define F8 "$4200"
- #define F9 "$4300"
- #define F10 "$4400"
-
- #define CTRL_F1 "$5E00"
- #define CTRL_F2 "$5F00"
- #define CTRL_F3 "$6000"
- #define CTRL_F4 "$6100"
- #define CTRL_F5 "$6200"
- #define CTRL_F6 "$6300"
- #define CTRL_F7 "$6400"
- #define CTRL_F8 "$6500"
- #define CTRL_F9 "$6600"
- #define CTRL_F10 "$6700"
-
- #define SHIFT_F1 "$5400"
- #define SHIFT_F2 "$5500"
- #define SHIFT_F3 "$5600"
- #define SHIFT_F4 "$5700"
- #define SHIFT_F5 "$5800"
- #define SHIFT_F6 "$5900"
- #define SHIFT_F7 "$5A00"
- #define SHIFT_F8 "$5B00"
- #define SHIFT_F9 "$5C00"
- #define SHIFT_F10 "$5D00"
-
- #define ALT_F1 "$6800"
- #define ALT_F2 "$6900"
- #define ALT_F3 "$6A00"
- #define ALT_F4 "$6B00"
- #define ALT_F5 "$6C00"
- #define ALT_F6 "$6D00"
- #define ALT_F7 "$6E00"
- #define ALT_F8 "$6F00"
- #define ALT_F9 "$7000"
- #define ALT_F10 "$7100"
-
-
- 9.5 Menus
-
-
-
-
-
- - 43 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- dObject provides a pop-up menu facility in the built-in Menu and
- Linemenu classes. Menus are created by passing the "new" method the
- Int y,x location of the upper left corner of the menu, the Int length
- of the menu (number of lines to show), the Int text and frame color
- attributes, a Collection of menu choices, and a String title. Menus
- are executed using the "choice" method containing an Int argument
- that specifies what choice to highlight upon entry to the menu. The
- "choice" method returns the index of the menu item chosen within the
- Collection; the calling program can retrieve the actual value chosen
- by indexing the Collection with the "at" method.
-
- Menus remain displayed in the current Window until the "remove"
- message is sent to them. The following example shows putting up a
- menu of numeric values and asking the user to choose:
-
- /*
- create a menu using a Collection of choices
- */
- myCollection = [1.0,2.0,3,4,5,6,7,8,9];
- a= new(Menu,3,3,5,31,3,myCollection," test ");
- b = choice(a,1);
- remove(a);
- ? "result of menu is ",b;
-
- /*
- the actual value chosen is found by getting the value
- in the collection at index "b"
- */
- value = at(myCollection,b);
-
-
- To exit the menu without making a choice, press the ESC key while the
- menu is active. This causes the Menu::choice() method to return 0 as
- the chosen value.
-
-
- The number of values in the Collection in a Menu can be much larger
- than the display size of the Menu. When this occurs, the user can
- press the up and down arrow keys to scroll through the menu before
- making a choice with the "Enter" key.
-
-
-
- 9.6 Line Menus
-
- dObject also provides a "Linemenu" class that implements lotus-style
- line menus with optional help lines. You can create a line menu
- using the "new" method, and passing it the Int window number of the
- window to create for the menu, an Int row and column for the upper
- left corner of the menu, an Int width of the menu, a Collection of
- values to put in the menu, and a corresponding Collection of status
- lines to show for each menu choice. When the menu is created and
-
-
- - 44 -
-
-
- Chapter 9: Windows and Menus
-
-
- shown using the Linemenu::choice() method, the choices will be evenly
- spaced across the width of the menu in the first line of the menu,
- and the status line text for a given choice will be displayed on the
- second line, much like the style of a Lotus 1-2-3 menu. The
- following example illustrates the use of the Linemenu class:
-
-
- /*
- demo of the Linemenu class
- */
- color = 54;
- width = 40;
- m = new(Linemenu,1,5,width,color,color,[1,2,3,4,5,6],
- ["first","second","third","fourth","fifth","sixth"]);
- c = choice(m);
- remove(m);
- ? "your choice was ",c;
-
-
- You can create a Linemenu that does not display status lines
- underneath the choices by passing an empty Collection to "new" for
- the status line text. In this case a one-line menu will be created:
-
-
- m = new(Linemenu,1,5,5,54,54,[1,2,3,4,5,6],[]);
-
-
- 9.7 Hypertext
-
- dObject provides the capability to use the Window class described
- above to display hypertext built from DBASE data and index files. To
- build a hypertext string that can be displayed or edited using the
- built-in text editor, use the Dbffile::htExpand() method. The "self"
- argument to this method is a Dbffile object that contains at least
- two text fields: one field containing a one-word topic string, and
- one field containing the text to show whenever that topic is selected
- from within a display. For example, the supplied dObject files
- HELP.DBF, HELP.DBT, and HELP.NDX are DBASE files that are used as the
- dictionary for the on-line help within the text editor and are an
- example of suitable hypertext files:
-
- dObject> db = new(Dbffile,"help");
- dObject> displayStructure(db);
- Structure for: HELP.DBF
- Number of records: 8
- Last update: 6/2/91
- Version: 3
- Number of fields: 2
- Field Field Name Type Width Dec
- 0 TOPIC C 8 0
- 1 TEXT M 10 0
-
-
-
- - 45 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- You must also pass an Ndxfile object that is a DBASE index on the
- topic field, a String name of the text field to use in the Dbffile
- for the text to show for a topic, an Int color to highlight the words
- in the string being converted that have topic entries in the Dbffile,
- and a String containing the text to convert. The method returns a
- String containing embedded control codes telling the built-in editor
- to highlight the topic words in the color you have chosen. The
- following example illustrates the proper calling sequence:
-
- dObject> db = new(Dbffile,"help");
- dObject> ndx = useIndex(db,"help");
- dObject> keylen = 32; % length of the topic field
- dObject> htext = htExpand(db,ndx,"text",31,keylen,
- "this is some text");
-
-
- To display the hypertext within the current window, use the
- String::display() method:
-
- dObject> display(htext);
-
-
- Calling this method will display the text within the current window
- with words that have matching entries in the topic field of the
- Dbffile highlighted with the color attribute chosen above. You can
- position the cursor using the normal editor keys, and you can
- "follow" the hypertext link for a highlighed word by positioning the
- cursor on that word and pressing the CTRL-F1 key. Pressing this key
- causes dObject to execute the String::onHyperKey() method with the
- contents of the "text" field for the topic that was found in the
- Dbffile. You should always supply a version of String::onHyperKey as
- part of your hypertext application; If you do not, pressing the
- CTRL-F1 key will have no effect will look for the word at the cursor
- in the HELP.DBF file.
-
-
- The following example shows how to define the String::onHyperKey()
- method and build a small hypertext application using the supplied
- dObject HELP.DBF, HELP.NDX, and HELP.DBT files:
-
- /*
- this is a demo of dObject's hypertext display feature
- first, define a method to handle the "follow hyper link"
- key when it is pressed from a window
- */
- method String::onHyperKey(self)
- {
- /*
- create a window for the text
- */
- w = new(Window,1,31,31,"",8,8,10,40);
- /*
-
-
- - 46 -
-
-
- Chapter 9: Windows and Menus
-
-
- the color attribute is the first character token in the string
- */
- color = asInt(token(self,#s));
- /*
- turn off the dObject hypertext help key (CTRL-F1) from within
- the display
- */
- set("hyperhelp",F);
- /*
- display the text
- to follow the link for a highlighted field, hit the SHIFT-F8 key
- */
- display(htExpand(db,index,"text",32,color,s));
- remove(w);
- }
-
- /*
- demo hypertext
- */
- #define COLOR 79
- db = new(Dbffile,"help");
- index = useIndex(db,"help");
- w = new(Window,1,31,31," Hypertext ",5,5,10,50);
- display(htExpand(db,index,"text",COLOR,32,":while for if then else dos"));
- remove(w);
- close(db);
-
-
-
- 10.0 Arrays and Collections
-
- 10.1 Arrays
-
- dObject provides classes for handling Arrays and Collections of
- objects. The primary difference between an Array and a Collection is
- that a Collection can be considered an ordered list of values that
- can easily be inserted into, appended to , and deleted from, while an
- Array is similar to a DBASE array that can be easily indexed by a set
- of integer indexes, but not easily ordered, inserted into, or deleted
- from. Both Collections and Arrays can contain any kind of dObject
- class, including other Collections and Arrays. There is no
- pre-defined limit on the size of an Array or Collection, but attempts
- to use more memory than is available will cause an error message.
-
-
- Arrays are similar to those provided in the DBASE programming
- language. An array element can be stored or retrieved from a
- specific location within an array through the use of the "replace"
- and "at" messages, passing a Collection of integer indexes as an
- argument.
-
-
-
-
- - 47 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- For example, to create an array of 10 elements and store a String
- value in the first location:
-
- dObject> a = new(Array,[10]);
- dObject> replace(a,[1],"this is the first element");
- dObject> ? at(a,[1]);
- t
-
-
- To create multi-dimensional arrays, create the array with more than
- one dimension in the dimension Collection, and address it with more
- than one element in the index Collection:
-
- dObject> a = new(Array,[3,3,3]);
- dObject> replace(a,[1,1,1],"this is the first element");
-
-
- /*
- this is a test of dObject's Array class
- */
- method Array::print(self)
- {
- i = 0;
- while(i < len(self)) {
- print(at(self,i));
- print(' ');
- i = i+1;
- }
- }
-
- /*
- create a single-dimension array of 4096 locations
- */
- a = new(Array,[4096]);
- i = 0;
- while(i < 4096) {
- replace(a,[i],i);
- i = i+1;
- }
- ? a;
-
-
- 10.2 Collections
-
- dObject's Collection class provides an advanced way to store ordered
- collections of objects. The Collection class comes with a
- comprehensive set of built-in methods for adding, deleting, finding,
- and replacing members within the collection. Collections are most
- easily created using the literal convention of surrounding a
- comma-separated list of literal values with brackets:
-
- dObject> myCollection = [1,2,3,4,5];
-
-
- - 48 -
-
-
- Chapter 10: Arrays and Collections
-
-
- Empty Collections can also be created using the Exp::new() method:
-
-
- dObject> myCollection = new(Collection);
- dObject> ? myCollection;
- []
-
-
- As with Arrays, members of a Collection can be any valid dObject
- class, including other Collections:
-
- dObject> myCollection = [[1,2,3],[4,5,6],[7,8,9]];
-
-
- To add a value to the end of a Collection, use the "append" method:
-
- dObject> myCollection = [1,2,3];
- dObject> myCollection = append(myCollection,4);
- dObject> ? myCollection;
- [1,2,3,4]
-
-
- To replace an existing value within a Collection, use the "replace"
- method, passing it a value to replace and the new value to replace it
- with:
-
- dObject> myCollection = [1,2,3];
- dObject> myCollection = replace(myCollection,1,32);
- dObject> ? myCollection;
- [32,2,3]
-
-
- The number of values within a Collection can be found by the "len"
- method:
-
- dObject> ? len([1,2,3,4,5]);
- 5
-
-
- The first value in a Collection is called the "head" of the
- Collection, and the remaining Collection without the head is called
- the "tail":
-
- dObject> ? myCollection = [1,2,3];
- dObject> ? head(myCollection);
- 1
- dObject> ? tail(myCollection);
- [2,3]
-
-
-
-
-
-
- - 49 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Individual values within a Collection can be retrieved using an Int
- index, but this is not nearly as efficient as using an Array for this
- purpose:
-
- dObject> ? at(["one","two","three"],2);
- two
-
-
- The last element in a collection is available using the "last"
- method:
-
- dObject> ? last([1,2,3,4]);
- 4
-
-
- The maximum and minimum values from within a Collection can be found
- with the "max" and "min" methods respectively:
-
- dObject> ? max([1,2,3]);
- 3
-
-
- A Collection can be filtered into another Collection by the "sort"
- and "unique" methods. The "sort" method returns a Collection that is
- the sorted version of the variable it is called on. The sort is
- accomplished using the ">" operator on whatever class is in the
- Collection, and is done in ascending order:
-
- dObject> ? sort([3,1,4,6,5,2]);
- [1,2,3,4,5,6]
-
-
- The "unique" method returns a Collection consisting of the unique
- elements in the Collection it is called on:
-
- dObject> ? unique([1,1,2,2,3,3,4,4,5,5,6,6]);
- [1,2,3,4,5,6]
-
-
- The following example demonstrates many of the methods available for
- handling Collections:
-
- /*
- this is a demonstration of dObject's Collection class
- */
- a = [5,3,9,5,100,44,5];
- ? "Collection is ",a;
- ? "length is ",len(a);
- ? "reversed is ",reverse(a);
- ? "third element is ",at(a,3);
- ? "last element is ",last(a);
- ? "with 100 removed is ",remove(a,100);
-
-
- - 50 -
-
-
- Chapter 10: Arrays and Collections
-
-
- ? "substitute 1005 for 5 is ",replace(a,5,1005);
- ? "is 44 in collection ?: ",44 $ a;
- ? "sorted array is ",sort(a);
- ? "unique array is ",unique(a);
- ? "unique sorted Collection is ",sort(unique(a));
- ? "sum of elements is ",sum(a);
- ? "minimum value is ",min(a);
- ? "maximum value is ",max(a);
- ? "average value is ",avg(a);
-
- /*
- fill a collection
- */
- a = [];
- i = 0;
- while(i < 10) {
- a = append(a,i);
- i = i+1;
- }
- ? a;
-
-
-
- 11.0 Files and Devices
-
- 11.1 Files and Devices
-
- dObject allows output to DOS text files and to devices such as the
- printer through the built-in "File" class. Files are created by
- passing the "new" method the name of the file to create, an Int
- switch indicating if the file is to be opened in read, write, or
- append mode (1,2, or 3 respectively), an Int containing the DOS
- attributes of the file, and an Int specifying what to do if the file
- already exists:
-
- dObject> f = new(File,"new.out",1,0,0);
-
-
- Constant definitions for the open mode, the DOS file attributes, and
- the creation option flag are provided in the file IODEF.DO:
-
- /*
- some constant definitions for new(File,...)
- */
- /* File Attributes */
- #define FA_RDONLY "$01" /* Read only file */
- #define FA_HIDDEN "$02" /* Hidden file */
- #define FA_SYSTEM "$04" /* System file */
- #define FA_SUBDIR "$10" /* Subdirectory */
- #define FA_ARCH "$20" /* Archive file */
- #define FA_NORMAL "$40" /* Normal file - No read/write restrictions */
-
-
-
- - 51 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- /* File usage Modes */
- #define FM_ACCESS_WO "$0001" /* write only */
- #define FM_ACCESS_RW "$0002" /* read/write */
- #define FM_ACCESS_RO "$0004" /* read only */
- #define FM_SH_DENYRW "$0010" /* deny read/write mode */
- #define FM_SH_DENYWR "$0020" /* deny write mode */
- #define FM_SH_DENYRD "$0030" /* deny read mode */
- #define FM_SH_DENYNO "$0040" /* deny none mode */
-
- /* Exclusively for OS2 and DOS >4.0 */
- #define FM_RETURNERR "$2000" /* return error rather than call crit hand. */
- #define FM_WRITETHRU "$4000" /* write through */
-
- /* Creation Flags */
- /* Actions if file exists (low nibble) : */
- #define CR_EX_FAIL "$00"
- #define CR_EX_OPEN "$01"
- #define CR_EX_REPLACE "$02"
-
- /* Actions if file doesn't exist (high nibble): */
- #define CR_NOEX_FAIL "$00"
- #define CR_NOEX_CREATE "$10"
-
-
- dObject maintains "current" input and output devices which are
- normally the keyboard and the screen respectively. These devices can
- be redirected to files through the "readDevice" and "writeDevice"
- methods:
-
- dObject> writeDevice(f);
-
-
- Files can be flushed and closed through the "flush" and "close"
- methods. For example, to open a file and write a line of output to
- it:
-
-
- You can read a character from the current input device using the
- Nil::readchar() method, which returns the next character as a Char
- variable. To read a complete keycode from the keyboard as an Int,
- use the Nil::inkey() method. The key definitions returned by
- Nil::inkey() are defined in the include file "keydef.do".
-
- If you use Nil::readchar() to read characters, you can "push back"
- characters into the input buffer using the Char::unread() method.
- This method pushes its Char argument back into the input buffer where
- it can be read later using Nil::readchar().
-
-
- The following example describes how to create a file and write output
- to it:
-
-
-
- - 52 -
-
-
- Chapter 11: Files and Devices
-
-
- /*
- this is a demonstration of dObject's file handling capabilities
- */
- f = new(File,"new.out",1,0,0);
- writeDevice(f);
- ? "this is a test";
- close(f);
-
-
- When opening a file in the "new" command, the filename can also be a
- device name, such as "prn:". The printer can be accessed as shown in
- the following example:
-
-
- /*
- this is a demonstration of dObject's printer handling features
- open the printer and print 10 lines to it without echoing the
- lines to the screen
- */
- p = new(File,"prn:",1,0,0);
- writeDevice(p);
- i = 1;
- while(i < 10) {
- ? "printing line ",i;
- i = i+1;
- }
-
- /*
- note: on some printers (HP II, Epson EPL-6000) it is necessary
- to send an ESC E to flush the printer... consult your printer
- manual to see if the next line is necessary, otherwise the
- "flush" method should work OK by itself
- */
- ? chr(27),'E';
- flush(p);
- close(p);
- ? "printout is done";
-
-
-
- 12.0 DBASE File Programming
-
- 12.1 DBASE File Programming
-
- dObject provides an extensive set of built-in methods for handling
- DBASE data, memo, and index files. You can create your own new
- DBASE-format files for storing data, or use existing files already in
- the DBASE format. You can also use and create DBASE index (.NDX)
- files.
-
-
-
-
-
- - 53 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- 12.2 Creating DBASE Files
-
- The following example demonstrates how to create a .DBF file using
- the String::createDbf() method. The argument to "createDbf" is an
- Collection of Collections of field defintions. Each field definition
- Collection should contain a string that is the DBASE field name, a
- character field type ('C' = char, 'N' = numeric, 'D' = date, 'M' =
- memo), an Int length, and an Int number of decimals for numerics:
-
- /*
- create a new Dbffile
- */
- db = createDbf("test",[
- ["cfield",'C',32,0],
- ["nfield",'N',5,0],
- ["dfield",'D',0,0],
- ["mfield",'M',512,0]);
- displayStructure(db);
-
-
- dObject will create a .DBT file for each MEMO field specified in the
- Collection of field definitions.
-
-
- To set the value of a field within the current DBASE file, set a
- variable with the same name as the field to a value, just like in
- DBASE. Once set, the field value can be updated in the current
- record by the "write" method, or a new record can be appended to the
- file using the "write" method:
-
-
- /*
- store some test data to the database
- */
- select(db); % make sure the Dbffile to process is the "current" file
- i = 1;
- while(i < 10) {
- cfield = "test"+asString(i);
- nfield = i;
- dfield = date();
- mfield = "memo" + asString(i);
- write(db,0L);
- i = i+1;
- }
-
-
- The structure (field definitions) from a DBF file can be obtained by
- using the Dbffile::structure() method. This returns a Collection of
- field definitions like the one described above. The following is an
- example of how to use the structure method to simulate some common
- DBASE commands:
-
-
-
- - 54 -
-
-
- Chapter 12: DBASE File Programming
-
-
- /*
- Dbffile::copyStructure(self,newname)
- this method copys the structure of self to a new database
- with name of "newname"
- only the structure of self is copied; no records are copied
- */
- method Dbffile::copyStructure(self,newname)
- {
- l = structure(self);
- createDbf(newname,l);
- }
-
- /*
- Dbffile::list(self)
- this method lists the records in a Dbffile to the screen
- */
- method Dbffile::list(self)
- {
- top(self);
- fields = structure(self);
- newline = set("newline");
- set("newline","");
- while(!eof(self)) {
- for(i=1;i<numFields(self);i=i+1) {
- f = at(fields,i);
- name = at(f,1);
- ? eval(asId(name))," ";
- }
- ? "\n";
- skip(self,1L);
- }
- set("newline",newline);
- }
-
-
- dObject> db2 = copyStructure(db,"test2");
-
-
- 12.3 Reading DBASE Files
-
- DBF files can be opened through the use of the "new" message with the
- name of the DBF file passed as an argument. Once opened, the records
- and fields within a DBF file are available for reading and for update
- by your dObject program. For example, to open the "patient.dbf"
- file, use the statement:
-
- dObject> db = new(Dbffile,"patient");
-
-
- The number of records and fields defined within a DBF file are
- available through calls to the "numRecords" and "numFields" methods:
-
-
-
- - 55 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- dObject> ? numFields(db);
- 6
- dObject> ? numRecords(db);
- 20
-
-
- The current record number is available as a Long using the "recno"
- method:
-
- dObject> top(db);
- dObject> ? recno(db),class(recno(db));
- 1 Long
-
-
- Dbffiles can be positioned by sending them the "top", "bot",
- "locate", and "seek" messages. The "eof" method returns logical T
- when a Dbffile is positioned beyond the last record in the file (and
- otherwise returns logical F). The following example demonstrates a
- program that loops over all the records in a DBF file:
-
-
- db = new(Dbffile,"patient");
- top(db);
- while(!eof(dbf)) {
- ? "at record ",recno(db);
- skip(db,1L);
- }
-
-
- The "locate" method can be used to locate specific field values of
- type Int, Real, Char, String, Date, or Logical. The first argument
- to the method should be the name of the field to perform the
- comparison on, and the second the value to find. The search will
- always start at the current record, so to always search from the top
- of the database, the "top" method can be used to position the Dbffile
- first:
-
- dObject> db = new(Dbffile,"patient");
- dObject> locate(top(db),"lname","lname6");
-
-
- Fields within DBF files are accessed by using a variable name with
- the same name as a field in the currently selected database, as in
- DBASE:
-
- dObject> db = new(Dbffile,"patient");
- dObject> top(db);
- dObject> ? lname;
- lname0
-
-
- dObject> select(db);
-
-
- - 56 -
-
-
- Chapter 12: DBASE File Programming
-
-
- The currently selected Dbffile is available through a call to the
- Nil::currentDbffile() method:
-
- dObject> top(currentDbffile());
-
-
- You can also perform sophisticated calculations over all the records
- in a DBASE file using the built-in "sum", "max", "min", and "avg"
- methods. These methods accept a literal dObject expression as an
- argument, and evaluate the sum, max, min, or average of the
- expression over all the records in the file. For example, to
- calculate the minimum and maximum length of a DBASE char field named
- "lname", your need to evaluate the length of the trimmed field value
- across all the records in the file. The following commands perform
- this task:
-
- dObject> ? db = new(Dbffile,"patient");
- dObject> ? min(db,#len(trim(lname)));
- dObject> ? max(db,#len(trim(lname)));
-
-
- These methods always start from the top of the file.
-
-
- 12.4 Using Filters
-
- dObject allows you to specify an expression as a "filter" for a .DBF
- file to make it appear to your application that certain records do
- not exist. The expression is evaluated for each record within a .DBF
- file, and unless the expression evaluates to logical true for a given
- record, the record appears as if it does not exist. To create an
- expression filter for a database, call the Dbffile::setFilter
- method:
-
- dObject> setFilter(db,#(recno(db) > 5L) & (recno(db) < 15L));
-
-
- The above example creates a filter for a Dbffile making it appear
- that only the records having record numbers between 6 and 14
- inclusive actually exist in the file. The expression can be any
- valid dObject expression, and setting a filter in this way affects
- every future operation done on the database, including repositioning
- with the Dbffile::top, Dbffile::bot, Dbffile::skip, and Dbffile::go
- methods, as well as editing within the interactive DBASE editor.
-
-
- When created, Dbffile objects have an implied filter of
- logical(true), which succeeds for any record. To clear the filter
- for a Dbffile object, use the Dbffile::clearFilter() method:
-
- dObject> clearFilter(db);
-
-
-
- - 57 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Collections can be created from DBASE fields using the "asCollection"
- method. The argument to this method is an expression to evaluate for
- each record in the DBASE file. The Collection returned contains one
- entry for the value of the expression for each record. The filtering
- process descibed above applies to filter out unwanted records. The
- following is an example of how to create a menu using information
- from a DBF file using a Collection as the list of items to show in
- the menu:
-
- /*
- create a menu of all the last names within a range
- of records in the dbf file
- */
- d = new(Dbffile,"patient");
- top(d);
- d = setFilter(d,#(recno(d) >= 8L) & (recno(d) <= 15L));
- a = sort(asCollection(d,#trim(lname)));
- m = new(Menu,3,3,5,31,3,a," Last Name ");
- c = choice(m,1);
- remove(m);
- ? "your menu choice was ",c;
-
-
- 12.5 Using DBASE Index Files
-
- Records containing field values of interest can be accessed much more
- quickly using DBASE index files than can be using the "locate" method
- described above. dObject provides the built-in Ndxfile class to
- represent DBASE index files. To open an existing index file and
- associate it with a Dbffile variable, use the "useIndex" method of
- the Dbffile class. This method returns a new Ndxfile variable:
-
- dObject> db = new(Dbffile,"patient");
- dObject> ndx = useIndex(db,"patient");
-
-
- This method opens the named index (with the default extension of
- .NDX) and associates it with the Dbffile. This permits the
- Ndxfile::seek method to be used to position the current record in the
- Dbffile:
-
- dObject> seek(db,"1");
-
-
- To create a new index file, use the "createIndex" method of the
- String class. The "self" argument in this case is the name of the
- index file to create, followed by a String containing the expression
- to evaluate for the index, and finally an Int indicator specifying if
- the index is to be unique (0=not unique, 1=unique). It also returns
- a new Ndxfile variable:
-
- dObject> ndx = createIndex("test","test",1);
-
-
- - 58 -
-
-
- Chapter 12: DBASE File Programming
-
-
- The following program demonstrates how to create an index file and
- use it to access fields within a Dbffile:
-
- /*
- create an index file for a database
- */
- db = new(Dbffile,"patient");
- index = createIndex(db,"patient","LNAME",0,0);
- ? "type of index is ",type(index);
- close(db);
-
- /*
- open the index and print out records in index order
- */
- db = new(Dbffile,"patient");
- useIndex(db,"patient");
- top(db);
- while(!eof(db)) {
- ? recno(db)," ",lname;
- skip(db,1L);
- }
- close(db);
-
-
- 12.6 Using Relations
-
- dObject provides a facility to relate two DBF files throught the use
- of the Dbffile::setRelation() method. Calling this method creates a
- relation between a controlling database (the self parameter) and a
- related database. Each time the controlling database is
- re-positioned (using the Dbffile::go(), Dbffile::seek(),
- Dbffile::top(), or Dbffile::bot() methods), the related database is
- re-positioned by looking up an expression in an index file. If no
- index file is specified when the relationship is created, then the
- expression is evaluated and interpreted as a record number to go to
- in the related database.
-
-
- The following example illustrates the use of relations in dObject:
-
- /*
- demonstrate the dObject relation facility between two related
- DBF files, first, create a customer file with customer names
- */
- custDb = createDbf("customer",[
- ["cId",'N',8,0],
- ["cName",'C',32,0],
- ["cAddress",'C',48,0],
- ["cCity",'C',16,0],
- ["cState",'C',2,0],
- ["cZip",'C',5,0]]);
-
-
-
- - 59 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- /*
- fill in some test customer names
- */
- #define MAXCUST 5
- for(i=0;i<MAXCUST;i=i+1) {
- cId = i;
- cName = "name"+asString(i);
- cAddress = "";
- cCity = "Chicago";
- cState = "IL";
- cZip = "60640";
- ? "writing record ",i;
- write(custDb,0L);
- }
- close(custDb);
-
- /*
- create a database of customer purchases
- */
- purchaseDb = createDbf("purchase",[
- ["cId",'N',8,0],
- ["pItem",'C',32,0],
- ["pDate",'D',0,0],
- ["pAmount",'N',8,2]]);
-
- /*
- create some test data
- */
- for(i=0;i<MAXCUST;i=i+1)
- for(j=0;j<2;j=j+1) {
- cId = i;
- pItem = "item"+asString(i);
- pDate = date();
- pAmount = 5.25;
- write(purchaseDb,0L);
- }
- close(purchaseDb);
-
- /*
- find the purchases for customer #3
- */
- custDb = new(Dbffile,"customer");
- purchaseDb = new(Dbffile,"purchase");
- ndx = createIndex(purchaseDb,"CID","cId",0,0);
- setRelation(custDb,"cId",select(purchaseDb),select(ndx),0);
- top(custDb);
- locate(custDb,"cId",3);
- ? "record number for customer 3 is ",recno(custDb);
- ? "customer id field in purchase database is ",recno(purchaseDb);
-
-
-
-
-
- - 60 -
-
-
- Chapter 12: DBASE File Programming
-
-
- 12.7 Editing DBASE Files
-
- Using the built-in Window::say() and read() methods and the "Field"
- class, the file DBFLIB.DO provides an example of a DBASE full-screen
- editor that is invoked by sending the "edit" message to a Dbffile
- object. You can include this editor in your own programs as is, or
- customize it to fit your own application. When invoked, the editor
- will display the field name and value for each field within the
- database in the current window, at the current record position.
-
-
- The "edit" method is implemented in the following library of Dbffile
- methods:
-
-
- /*
- DBFLIB.DO
- This is a collection of methods for handling DBASE files
- Includes:
- Dbffile::displayStructure(self)
- Dbffile::copyStructure(self)
- Dbffile::list(self)
- Dbffile::edit(self)
- */
- #include "keydef.do"
- #include "colors.do"
-
- /*
- Dbffile::displayStructure(self)
- this methods prints a description of the structure of a DBASE
- file similar to that in the DBASE DISPLAY STRUCTURE command
- */
- method Dbffile::displayStructure(self)
- {
- ? "Structure for\t\t",name(self);
- ? "Last udpate:\t\t",date(self);
- ? "Number of records:\t",numRecords(self);
- fields = structure(self);
- ? "FIELD\t\t\tTYPE\tLEN\tDEC";
- for(i=1;i<numFields(self);i=i+1) {
- f = at(fields,i);
- ? format(at(f,1),"%-24s"),at(f,2),"\t",
- at(f,3),"\t",at(f,4);
- }
- }
-
- /*
- Dbffile::copyStructure(self,newname)
- this method copys the structure of self to a new database
- with name of "newname"
- only the structure of self is copied; no records are copied
- */
-
-
- - 61 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- method Dbffile::copyStructure(self,newname)
- {
- l = structure(self);
- create(newname,l);
- }
-
- /*
- Dbffile::list(self)
- this method lists the records in a Dbffile to the screen
- */
- method Dbffile::list(self)
- {
- top(self);
- fields = structure(self);
- newline = set("newline");
- set("newline","");
- while(!eof(self)) {
- for(i=1;i<numFields(self);i=i+1) {
- f = at(fields,i);
- name = at(f,1);
- ? eval(asId(name))," ";
- }
- ? "\n";
- skip(self,1L);
- }
- set("newline",newline);
- }
-
- /*
- The following methods implement a DBASE field editor using the
- dObject Window SAY and READ methods and the FIELD class.
- first, define a new class called MYFIELD that inherits the behavior of
- Field, but adds a prompt that is displayed at the bottom of the form
- */
- inherit(Field,Myfield,["prompt"]);
-
- /*
- define a method to get the prompt field from a Myfield variable
- */
- method Myfield::prompt(self)
- {
- return(slot(self,"prompt"));
- }
-
- /*
- this method will execute whenever the DOWN key is pressed
- from within a form
- */
- method Window::myNextField(self)
- {
- n = num(currentField(self));
- if(n < len(fields)) {
-
-
- - 62 -
-
-
- Chapter 12: DBASE File Programming
-
-
- f = at(fields,n+1);
- say(promptWindow,0,0,prompt(f),80,112);
- gotoField(self,nextField(self));
- }
-
- }
-
- /*
- this method will execute whenever the UP key is pressed
- from within a form
- */
- method Window::myPrevField(self)
- {
- n = num(currentField(self));
- if(n > 1) {
- f = at(fields,n-1);
- say(promptWindow,0,0,prompt(f),80,112);
- gotoField(self,prevField(self));
- }
- }
-
- /*
- this method implements a callable text editor for the contents of
- a field
- */
- method Window::myEdit(self)
- {
- f = currentField(self);
- s = eval(asId(name(f)));
- if(class(s) == "String") {
- w = new(Window,1,31,3,name(f),5,5,10,40);
- display(s);
- remove(w);
- gotoField(self,f);
- }
- }
-
- /*
- edit a Dbffile using a full screen editor
- */
- method Dbffile::edit(self)
- {
- /*
- make a window to run the editor in
- */
- w = new(Window,1,FWHITE+LIGHTBLUE,FWHITE+LIGHTBLUE,
- name(self),0,0,24,80);
-
- /*
- create the DBASE form based on field definitions within self
- */
- clearGets(w);
-
-
- - 63 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- sayExp(w,0,1,#name(self),len(name(self)),FWHITE+LIGHTBLUE);
- sayExp(w,0,20,#"Record=",7,FWHITE+LIGHTBLUE);
- sayExp(w,0,30,#recno(self),7,FWHITE+LIGHTBLUE);
-
- l = structure(self);
- fields = [];
-
- /*
- for each field in the DBF file, create:
- a SAY field with the name of the DBF field
- a GET field right next to it to read its value
- */
- for(i=1;i<=numFields(self);i=i+1) {
- field_def = at(l,i);
- fname = at(field_def,1); % name is first element in field def
- len = at(field_def,3);
- if(len > 40) len = 40;
- say(w,i,1,fname,10,31);
- fields = append(fields,new(Myfield,w,i,15,fname,len,112,
- "Enter the "+asUpper(trim(fname))+ " field"));
-
- }
-
- /*
- execute the form
- */
- top(self);
- promptWindow = new(Window,80,112,0,"",24,0,1,80);
-
- onKey(w,DOWN,#myNextField(w));
- onKey(w,UP,#myPrevField(w));
- onKey(w,F8,#myEdit(w));
-
- say(promptWindow,0,0,prompt(at(fields,1)),80,112);
-
- read(w);
- remove(w);
- remove(promptWindow);
- }
-
-
-
- As another example, the following program displays a directory of DBF
- files in the current directory and edits the one selected from the
- menu:
-
-
- /*
- this program creates a window, and displays a menu of DBF files
- available in the current directory. When the user selects one,
- the DBF file editor is called to edit the fields and records
- */
-
-
- - 64 -
-
-
- Chapter 12: DBASE File Programming
-
-
- w = new(Window,1,7,7," select DBF ",1,1,10,40);
- s = dir("","*.dbf");
- while(s != "") {
- d = new(Dbffile,s);
- height = numFields(d)+2;
- edit(d);
- s = dir("","*.dbf");
- }
- remove(w);
-
-
- 12.8 Closing DBASE Files
-
- To close a Dbffile, use the "close" method:
-
-
- dObject> close(db);
-
-
- To close all the open Dbffiles at once, use the Nil::closeAllDbfs
- method (this will close all open .NDX files also):
-
- dObject> closeAllDbfs();
-
-
-
- 13.0 Graphics Programming
-
- 13.1 BGI Graphics
-
- dObject comes complete with a built-in graphics system based on the
- Borland Graphics Interface (BGI). The BGI provides over 70 methods
- for handling graphics, including methods to draw lines, arcs,
- circles, polygons, and other shapes; methods for filling shapes in a
- variety of styles; and methods for setting text in a variety of
- fonts.
-
-
- 13.2 Graphics Drivers
-
- To begin with, you must call the Int::initGraph() method to
- initialize the graphics system. This will put the screen into
- graphics mode and allow further calls to the BGI system. dObject
- comes with graphics drivers for the following graphics adapters:
-
- * CGA
-
- * MCGA
-
- * EGA
-
- * VGA
-
-
- - 65 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- * Hercules
-
- * AT&T 400-line
-
- * 3270 Graphics Adapter
-
- * IBM-8514 Graphics Adapter
-
- The self argument to Int::initGraph() is an integer flag specifying
- the device driver to use ( a value of 0 will detect the best driver
- to use):
-
-
- * 0 - autodetect
-
- * 1 - CGA
-
- * 2 - MCGA
-
- * 3 - EGA
-
- * 4 - EGA64
-
- * 5 - EGAMONO
-
- * 6 - IBM8514
-
- * 7 - Hercules
-
- * 8 - AT&T 400
-
- * 9 - VGA
-
- * 10 - PC 3270
-
- You can obtain the name of the current graphics driver through a call
- to the Nil::getDriverName() method.
-
-
- dObject provides the following methods for initializing and shutting
- down the BGI graphics system:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::initGraph self, Int, String initializes the BGI system;
- must be called before any
- other BGI method. Sets the
- graphics driver to self, the
- graphics mode to the Int
- arg, and the driver path to
- the String arg.
-
-
- - 66 -
-
-
- Chapter 13: Graphics Programming
-
-
- Nil::detectGraph returns a Collection of 2
- Int values specifying the
- current graphics driver and
- mode.
- Nil::getDriverName returns a String containing
- the name of the current
- graphics driver.
- Int::getModeName self returns a String containing
- the graphics mode name for
- the mode with Int code of
- self.
- Int::getModeRange self returns a Collection of 2
- Int values specifying the
- min and max mode values for
- the graphics driver with Int
- code of self.
- Int::setGraphMode self changes the graphics mode to
- self.
- Nil::getGraphMode returns an Int containing
- the current graphics mode.
- Nil::getMaxMode returns an Int containing
- the maximum mode number for
- the currently loaded driver.
- Nil::graphDefaults sets the graphics system to
- default values (see next
- section).
- Nil::closeGraph closes the graphics system,
- unloads the driver from
- memory, and restores the CRT
- to its original state before
- initGraph() was called.
- Nil::restoreCrtMode restores the CRT to its
- original state.
-
- 13.3 Default Graphics Settings
-
- You can set the graphics system to its default settings through a
- call to the Nil::graphDefaults() method. These defaults settings are
- as follows:
-
-
- * Viewport: mamimum device resolution
-
- * Clipping: on
-
- * Palette: default for drive
-
- * Background color: 0
-
- * Drawing color: max color
-
- * Fill style: solid fill
-
-
- - 67 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- * Fill color: max color
-
- * Line style: solid line
-
- * Hardware font direction: horizontal
-
- * Font size: 1
-
- * Font justification: left top
-
- * Current position: home (0,0)
-
- 13.4 Current Graphics Position
-
- The BGI system maintains the current X,Y graphics co-ordinate that is
- referred to as the current position (CP). The current position can
- be obtained through calls to the Nil::getx() and Nil::gety() methods,
- each of which return an Int value. The CP can be set using the
- Int::moveto() and Int::moveRel() methods, with the self arg equal to
- the X value to move to, and the first argument being an Int Y
- co-ordinate. Int::moveTo() uses and absolute co-ordinate, whereas
- Int::moveRel() moves relative to the current position:
-
-
-
- /*
- move the graphics CP
- */
- moveto(100,100); % now at 100,100
- moveRel(100,100); % now at 200,200
-
-
-
- dObject provides the following methods for maintinaing the graphics
- CP:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Nil::getX returns the x co-ordinate of
- the CP
- Nil::getY returns the y co-ordinate of
- the CP
- Int::moveTo self, Int moves the CP to X,Y of self,
- Int arg
- Int::moveRel self, Int moves the CP the X,Y
- relative distance of self,
- Int arg
- Nil::getMaxX returns the max X value for
- the current graphics driver
- and mode
- Nil::getMaxY returns the max Y value for
-
-
- - 68 -
-
-
- Chapter 13: Graphics Programming
-
-
- the current graphics driver
- and mode
-
- 13.5 Drawing Lines
-
- Lines are drawn using the Int::line() method, passing it the X,Y
- positions of the beginning and end points. The following example
- draws a line from the point 5,5 to the point 100,100:
-
- dObject> line(5,5,100,100);
-
-
- The following methods are provided for drawing lines:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::setLineStyle self, Int, Int sets the current line style
- to the code in self; sets
- the current pattern to the
- first Int arg code, and the
- current thickness to the
- second Int arg. Line style
- codes are 0=solid, 1=dotted,
- 2=center, 3=dashes,
- 4=user-defined. You can
- define a line style by using
- a 16-bit pattern in the
- first Int arg, where whenver
- a bit in the pattern is set
- to one, the corresponding
- pixel in the line is drawn
- in the current drawing
- color. For example, a solid
- line is represented by the
- value $FFFF (all one's), and
- a dashed line is $3333 or
- $0F0F. Thickness codes in
- the second Int arg are 0=1
- pixel wide, 3=3 pixels wide.
- Nil::getLineSettings returns collection of 3 Int
- args representing current
- line style, user-defined
- pattern, and thickness code
- as described above.
- Int::line self, Int, Int, Int draws a line in the current
- drawing color. Arguments are
- X,Y of start point and X,Y
- of end point.
- Int::linerel self, Int draws a line in the current
- drawing color from current
- position to relative offset
-
-
- - 69 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- of self, Int arg.
- Int::lineto self, Int draws a line in the current
- drawing color from current
- position to X,Y position of
- self, Int arg.
- Int::setWriteMode self sets the writing mode for
- line drawing to self; if
- self = 0 the line will
- overwrite what is on the
- screen; if self=1 the line
- pixels will be XOR'd with
- the pixels on the screen.
-
- 13.6 Drawing Circles
-
- The following methods are provided for drawing circles and arcs:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::arc self, Int, Int, Int, draws a circular arc in the
- Int current drawing color.
- Arguments are X,Y center,
- start angle, end angle, and
- radius.
- Int::circle self, Int, Int draws a circle in the
- current drawing color.
- Arguments are X,Y of center,
- and radius.
- Nil::getArcCoords returns a Collection of 6
- Int values containing the
- x,y center point, x,y start
- pos, and x,y end pos of the
- arc. This is useful if you
- need to make a line meet at
- the end of an arc.
-
- 13.7 Drawing Ellipses and Pie Charts
-
- The following methods are provided for drawing ellipses and pie
- charts:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::ellipse self, Int, Int, Int, draws an ellipse in the
- Int, Int current drawing color. Args
- are center point X,Y, start
- angle, end angle, and X and
- Y radius.
- Int::fillEllipse self, Int, Int, Int draws an ellipse and fills
- it with the current fill
-
-
- - 70 -
-
-
- Chapter 13: Graphics Programming
-
-
- pattern in the current fill
- color. Args are X, Y, X
- radius, and Y radius.
- Int::pieSlice self, Int, Int, Int, draws and fills a pie slice
- Int using current fill pattern
- and drawing color.
- Arguments are X,Y center,
- start angle, end angle, and
- radius.
- Int::pieSliceXY self, Int, Int, Int, draws and fills an
- Int, Int elliptical pie slice using
- current fill pattern and
- drawing color. Arguments
- are X,Y center, start angle,
- end angle, X radius, and Y
- radius.
- Nil::getAspectRatio returns Collection of 2 Int
- value representing the x and
- y aspect ratio correction
- values of the current
- graphics mode.
- setAspectRatio self, Int sets the x and y
- aspect-ratio correction
- factors to self and Int arg
- respectively.
-
- 13.8 Drawing Rectangles and Bars
-
- dObject provides the following methods for drawing rectangles, bar
- graphs, and polygons:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::rectangle self, Int, Int, Int draws a rectangle in the
- current line style,
- thickness, and drawing
- color. Arguments are left,
- top, right, and bottom
- co-ordinates of the
- rectangle to draw (from
- (left,top) to
- (right,bottom)).
- Int::bar self, Int, Int, Int draws a rectangular bar in
- the current line style,
- thickness, and drawing
- color, and fills it using
- the current fill pattern and
- fill color. Arguments are
- left, top, right, and bottom
- co-ordinates of the
- rectangle to draw (from
-
-
- - 71 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- (left,top) to
- (right,bottom)).
- Int::bar3d self, Int, Int, Int, draws a rectangular 3-D bar
- Int, Int in the current line style,
- thickness, and drawing
- color, and fills it using
- the current fill pattern and
- fill color. Arguments are
- left, top, right, and bottom
- co-ordinates of the
- rectangle to draw (from
- (left,top) to
- (right,bottom)), the depth
- of the bar, and a flag
- indicating if a top to the
- bar should be drawn (0=no,
- 1=yes).
-
- 13.9 Drawing Polygons
-
- dObject provides the following methods for drawing polygons:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Collection::drawPoly self draws a polygon with as many
- points as Int value pairs in
- the collection; each Int
- pair is an x,y co-ordinate
- of a vertex on the polygon.
- Collection::fillPoly self draws a polygon with as many
- points as Int value pairs in
- the collection and fills it
- using the current fill style
- and fill color; each Int
- pair is an x,y co-ordinate
- of a vertex on the polygon.
-
- 13.10 Palettes
-
- The BGI graphics screen consists of an array of pixels controlled by
- a color table called a palette. The background color always
- corresponds to pixel value 0. The drawing color is the value to
- which pixels are set when lines or shapes are being drawn. You can
- select a drawing color with the Int::setColor() method.
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::setBkColor self sets the current background
- color to self
- Nil::getBkcolor self returns the current
-
-
- - 72 -
-
-
- Chapter 13: Graphics Programming
-
-
- background color
- Int::setColor self sets the current drawing
- color to self
- Nil::getColor returns the current drawing
- color
- Nil::getMaxColor returns the maximum color
- value available in the
- current graphics mode
- Int::setPalette self, Int changes the color value
- stored under self to the
- color in the Int arg
- Collection::setAllPaletteself sets list of new palette
- colors. self must be a
- Collection of 8 Int values
- specifying the colors.
-
- 13.11 Filling Shapes
-
- You can fill the shapes drawn with the circle, ellipse, bar, and
- polygon shape drawing methods with the Int::floodFill() method, or
- combine drawing and filling into one step with the fillPoly() and
- pieSlice() methods. You can select a predefined fill pattern with
- setFillStyle, and define your own fill pattern with
- setFillPattern().
-
-
- The predefined fill pattern codes recognized by Int::setFillStyle()
- are as follows (as defined in the included file BGIDEF.DO):
-
- * 0 (EMPTY_FILL) - fill with background color
-
- * 1 (SOLID_FILL) - solid fill
-
- * 2 (LINE_FILL) - fill with ----
-
- * 3 (LTSLASH_FILL) - fill with ///
-
- * 4 (SLASH_FILL) - fill with ///, thick lines
-
- * 5 (BKSLASH_FILL) - fill with backslash, thick lines
-
- * 6 (LTBACKSLASH_FILL) - fill with backslash
-
- * 7 (HATCH_FILL) - light hatch fill
-
- * 8 (XHATCH_FILL) - heavy cross hatch fill
-
- * 9 (INTERLEAVE_FILL) - interleaving line fill
-
- * 10 (WIDE_DOT_FILL) - widely spaced dot fill
-
- * 11 (CLOSE_DOT_FILL) - closely spaced dot fill
-
-
- - 73 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- * 12 (USER_FILL) - user-defined fill pattern (see
- Collection::setFillPattern())
-
- The following methods are provided for filling shapes:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Nil::getFillSettings returns a Collection of 2
- Int values; the first is the
- current fill pattern; the
- second is the current fill
- color
- Int::setFillStyle self, Int sets the current fill
- pattern to the predefined
- pattern with a code of self
- and the current fill color
- to the Int arg
- Collection::setFillPatternself, Int sets the current fill
- pattern to a user-defined
- Collection of 8 Int color
- values. Each Int value
- represents a byte of 8
- pixels; whenever a bit in
- the pixel pattern is set to
- 1, the corresponding pixel
- will be plotted. The Int
- arg is the fill color to
- use.
- Nil::getFillPattern returns the current
- user-defined fill pattern as
- a Collection of 8 Int
- values.
- Int::floodFill self, Int, Int fills an enclosed area on
- the graphics screen. Self
- and the first Int arg form a
- "seek point": within the
- enclosed area to be filled.
- The are bounded by the color
- indicated in the second Int
- arg is flooded with the
- current fill pattern and
- fill color. If the seed
- point is within an enclosed
- area, the the inside will be
- filled. If the seed is
- outside the enclosed the
- area, then the exterior will
- be filled.
-
-
-
-
-
- - 74 -
-
-
- Chapter 13: Graphics Programming
-
-
- 13.12 Fonts and Text in Graphics Mode
-
- You can also output text in a variety of fonts, sizes, and styles
- from within dObject's BGI graphics mode. Text output is accomplished
- by calling the String::outText() or Int:outTextXY() methods after
- defining a current character font.
-
-
- Text justification constants in horizontal mode:
-
- * 0 - left horizontal
-
- * 1 - center horizontal
-
- * 2 - right horizontal
-
- Text justification constants in vertical mode:
-
- * 0 - bottom vertical
-
- * 2 - top vertical
-
- dObject provides the following methods for manipulating text in
- graphics mode:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- String::outText self outputs a string to the
- current graphics position
- (CP).
- Int::outTextXY self, Int, String outputs String arg to x,y
- location of self, Int arg
- String::textHeight self returns height of self in
- pixels as Int
- String::textWidth self returns width of self in
- pixels as Int
- Nil::getTextSettings returns Collection of 4 Int
- values indicating current
- text font, direction, size,
- and justification
- Int::setTextJustify self, Int sets justification to
- horizontal code of self and
- vertical code of Int arg.
- Horizontal values:
- 0=left,1=center,2=right
- Vertical values:
- 0=bottom,1=top
- Int::setTextStyle self, Int, Int sets current text font to
- self; sets current direction
- to first Int arg, and
- current char size to second
-
-
- - 75 -
-
-
- dObject Version 1.0 (c) 1991 Intelligent Systems Research
-
-
- Int arg. Text direction
- codes are 0=horizontal (left
- to right), 1=vertical
- (bottom to top).
- Int::setUserCharSize self, Int, Int, Int sets width and height ratio
- for stroked fonts. Sets
- scale factors for x width, x
- height, y width, and y
- height to self and the 3 Int
- args respectively.
-
- 13.13 Viewports
-
- Your system contains between one and four screen-page buffers where
- screen images are stored dot-by-dot, depending on the graphics
- hardware installed. You can specify which screen page is active
- (where graphics methods place their output) and which page is visible
- using the Int::setActivePage() and Int::setVisualPage() methods. You
- can specify a region of the display screen where clipping is active
- through a call to the setViewPort() method.
-
-
- dObject provides the following viewport-related methods:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::setViewPort self, Int, Int, Int, sets the current viewport to
- Int the absolute screen
- co-ordinates left, top,
- right, bottom corresponding
- to the self argument and the
- first three Int arguments
- respectively. The final Int
- arg is a flag indicating if
- clipping is on or off (0 =
- off, 1 = on).
- Nil::getViewSettings returns a Collection of 5
- Int value specifying the
- left, top right, and bottom
- screen co-ordinates of the
- current viewport, and an Int
- flag indicating if clipping
- is on or off.
- Int::setActivePage self sets the active graphics
- page to page number of
- self.
- Int::setVisualPage self sets the visible graphics
- page to page number of self.
- Nil::clearViewPort self clears the current viewport
- and moves the CP to (0,0).
- Nil::clearDevice self clears the entire screen and
-
-
- - 76 -
-
-
- Chapter 13: Graphics Programming
-
-
- moves the CP to (0,0).
-
- 13.14 Pixels and Images
-
- The BGI system also provides several methods for manipulating images
- and pixels on the graphics screen:
-
-
- NAME ARGUMENTS DESCRIPTION
-
- Int::getPixel self, Int returns the pixel color at
- location x,y specified by
- self and Int arg
- Int::putPixel self, Int, Int sets the pixel at location
- x,y (self, Int arg) to color
- specified by second Int arg
- Int::getImage self, Int returns image stored at x,y
- of self, Int arg
- Int::imageSize self, Int, Int, Int returns an Int number of
- bytes necessary to store a
- rectangular area of the
- screen. Args are left, top,
- right, and bottom
- co-ordinates of the region.
- Int::putImage self, Int, Image, Intwrites an image to the
- screen at x,y of self, first
- Int arg. Second Int arg
- specifies how bits of the
- image will be combined with
- bits already on the screen:
- copy = 0, xor = 1, or = 2,
- and = 3, not = 4.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 77 -
-