home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / turbo55 / install / oopdemos.arc / OOPDEMOS.DOC < prev    next >
Text File  |  1989-05-02  |  24KB  |  678 lines

  1.  
  2.                  Turbo Pascal 5.5 Documentation
  3.               Object-Oriented Programming Examples
  4.  
  5. This file documents the Turbo Pascal 5.5 Object-Oriented
  6. Programming (OOP) examples. There are over 12,000 lines of
  7. examples contained in the OOPDEMOS.ARC file on the disk labeled
  8. OOP/DEMOS/BGI/DOC. (If you have a hard disk and run the INSTALL
  9. program to install Turbo Pascal on your system, it will place the
  10. OOP examples in C:\TP by default.)
  11.  
  12.  
  13. TABLE OF CONTENTS
  14. -----------------
  15.  
  16.  1.  OBJECTS.PAS - Basic object types unit
  17.  
  18.  2.  ODEMO.PAS - An example that uses streams and lists
  19.  
  20.  3.  FORMS.PAS - Implements a form entry and edit object
  21.  
  22.  4.  SLIDERS.PAS - Implements a slider field
  23.  
  24.  5.  FDEMO.PAS - A simple forms editor example
  25.  
  26.  6.  CARDS.PAS - Implements a card file object
  27.  
  28.  7.  CARDFILE.PAS - A simple card filer applciation
  29.  
  30.  8.  CARDGEN.PAS - Card filer forms generator
  31.  
  32.  9.  TCALC.PAS - See TCALC.DOC
  33.  
  34. 10.  Examples from the Object-Oriented Programming Guide
  35.  
  36.      Four examples are included from the OOP Guide for your
  37.      convenience:
  38.  
  39.        POINTS   PAS  - From P-20 of the OOP Guide
  40.        FIGURES  PAS  - From P-42 of the OOP Guide
  41.        FIGDEMO  PAS  - From P-47 of the OOP Guide
  42.        LISTDEMO PAS  - From P-57 of the OOP Guide
  43.  
  44.     These examples are fully documented in Chapter 1 of the OOP
  45.     Guide.
  46.  
  47.  
  48. OBJECTS.PAS - BASIC OBJECT TYPES UNIT
  49. -------------------------------------
  50.  
  51. The Objects unit implements two basic object types: a Stream and
  52. a List. The Stream type is the object-oriented counterpart of a
  53. Pascal file. Turbo Pascal 5.5 does not allow "file of object"
  54. types, but streams may be used to implement the same
  55. functionality, and much more as the example programs show. The
  56. List type implements a singly-linked list of objects, each of
  57. which must be derived from the Node type.
  58.  
  59.  
  60. The Base type
  61. -------------
  62.  
  63. Base is an abstract object type, and serves only as an ultimate
  64. ancestor for other object types. Objects of type Base are never
  65. instantiated. Object types derived from Base are guaranteed to
  66. have a destructor called Done. In addition, the VMT field of
  67. descendants of Base will always be the first field in the
  68. descendant, which is a prerequisite of types registered with a
  69. stream.
  70.  
  71. Unless overridden, the Done destructor in Base does nothing
  72. except to dispose the instance when called via the extended
  73. syntax of the Dispose standard procedure.
  74.  
  75.  
  76. The Stream type
  77. ---------------
  78.  
  79. Much like an untyped file, a stream implements a number of basic
  80. I/O capabilities, such as opening, closing, reading, writing, and
  81. seeking. What sets a stream apart from an untyped file is its
  82. ability to polymorphically read and write objects. This is best
  83. demonstrated through an example.
  84.  
  85. Assume that you have three object types, Circle, Rectangle, and
  86. Triangle, each of which are derived from an ancestor type Shape.
  87. In order to read and write such objects to disk you would need a
  88. FILE OF Shape that allows reading and writing of objects of type
  89. Shape as well as descendants of Shape. For a number of reasons,
  90. ordinary Pascal FILE types cannot achieve this. First, objects of
  91. type Circle, Rectangle, and Triangle are most likely not of the
  92. same size, since each will add a varying number of fields to the
  93. basic Shape type. Thus, it would be impossible to determine the
  94. proper record size for a FILE OF Shape. Second, a FILE OF Shape
  95. would need to store additional type information for each object
  96. in the file so that when reading the file, the application can
  97. "know" the types of the objects it is reading.
  98.  
  99. The Stream type provides the solution to this problem: By
  100. defining a Store and Load method in an object type, and by
  101. registering that type with a stream, the stream can perform
  102. polymorphic I/O through its Put and Get methods. The FORMS.PAS
  103. unit and the CARDFILE.PAS program provide good examples on how to
  104. use streams.
  105.  
  106. The Stream type is the ancestor of all other streams. It defines
  107. the basic properties of a stream, but most of its methods are
  108. purely abstract and meant to be overridden in descendant types.
  109.  
  110.  
  111. FIELDS
  112.  
  113. TypeCount       Number of types registered with the stream.
  114.  
  115. TypeList        Pointer to array of VMT offsets of registered types.
  116.  
  117. ProcList        Pointer to array of Store and Load method pointers.
  118.  
  119. Status          Stream status. When Status is non-zero, an error
  120.                 has occurred on the stream, and all subsequent
  121.                 I/O is suspended. The Status field is the
  122.                 equivalent of the IOResult standard function,
  123.                 except that you have to manually clear Status to
  124.                 re-enable I/O operations.
  125.  
  126.  
  127. CONSTRUCTORS AND DESTRUCTORS
  128.  
  129. constructor Init;
  130.  
  131.   Initializes the stream by allocating TypeList and ProcList, and
  132.   calling RegisterTypes to register the types known by the
  133.   stream.
  134.  
  135. destructor Done; virtual;
  136.  
  137.   Disposes TypeList and ProcList.
  138.  
  139.  
  140. BASIC I/O METHODS
  141.  
  142. procedure Read(var Buf; Count: Word); virtual;
  143.  
  144.   Reads Count bytes from the stream into Buf. In case of error,
  145.   Buf is filled with zeros. This method must be overridden.
  146.  
  147. procedure Write(var Buf; Count: Word); virtual;
  148.  
  149.   Writes Count bytes from Buf onto the stream. This method must
  150.   be overridden.
  151.  
  152. procedure Flush; virtual;
  153.  
  154.   Flushes the stream's I/O buffer, if any. This method does
  155.   nothing unless overridden.
  156.  
  157. procedure Truncate; virtual;
  158.  
  159.   Truncates the stream at the current position, i.e. makes the
  160.   current position the end of the stream. This method must be
  161.   overridden.
  162.  
  163. function GetPos: Longint; virtual;
  164.  
  165.   Returns the current position of the stream, or -1 in case of
  166.   error.
  167.  
  168. procedure SetPos(Pos: Longint; Mode: Byte); virtual;
  169.  
  170.   Sets the current position of the stream to a new position that
  171.   is Pos bytes from the stream location given by Mode. Valid Mode
  172.   values are given by the constants PosAbs, PosCur, and PosEnd,
  173.   which represent the stream's beginning, current position, and
  174.   end. This method must be overridden.
  175.  
  176. function GetSize: Longint;
  177.  
  178.   Returns the current size of a stream. Calls SetPos and GetPos
  179.   to find the resulting value. This method should not be
  180.   overridden.
  181.  
  182. procedure Seek(Pos: Longint);
  183.  
  184.   Seeks to the specified position. Corresponds to a call to
  185.   SetPos with a Mode value of PosAbs. This method should not be
  186.   overridden.
  187.  
  188.  
  189. TYPE REGISTRATION METHODS
  190.  
  191. procedure RegisterTypes; virtual;
  192.  
  193.   Registers all types that should be known to the stream. To
  194.   register types with a stream you must override this method and
  195.   call the Register method for each type. Within an overridden
  196.   RegisterTypes, always first call the inherited RegisterTypes to
  197.   register any types required by the ancestor. A type need only
  198.   be registered if instances of the type are read and written
  199.   using the Get and Put methods. Unless overridden, this method
  200.   does nothing.
  201.  
  202. procedure Register(TypePtr, StorePtr, LoadPtr: Pointer);
  203.  
  204.   Registers a type with the stream. This method must only be used
  205.   within a RegisterTypes method. The format of a method call is:
  206.  
  207.     Register(TypeOf(AType), @AType.Store, @AType.Load);
  208.  
  209.   where AType is an object type derived from the Base object type
  210.   (i.e. an object type whose ultimate ancestor is Base). AType
  211.   must define Store and a methods with the following headers:
  212.  
  213.     procedure Store(var S: Stream);
  214.     constructor Load(var S: Stream);
  215.  
  216.   The Store method must write a binary representation of the
  217.   object onto the stream S (using S.Write), and the Load
  218.   constructor must read such a binary representation back from
  219.   the stream S (using S.Read).
  220.  
  221.  
  222. POLYMORPHIC I/O METHODS
  223.  
  224. procedure Put(P: BasePtr);
  225.  
  226.   Writes the specified object to the stream. The type of the
  227.   object must have been registered with the stream (using an
  228.   overridden RegisterTypes method). Put writes a 16-bit object
  229.   type identifier number onto the stream and then calls the
  230.   object's Store method, which writes a binary copy of the
  231.   object. The 16-bit object type identifier corresponds to the
  232.   index of the object type in the TypeList and ProcList arrays.
  233.  
  234.   If the specified object pointer is NIL, a 16-bit zero is
  235.   written to the stream. If the object type has not been
  236.   registered with the stream, the stream's Error method is called
  237.   with an error code of -1.
  238.  
  239. function Get: BasePtr;
  240.  
  241.   Reads an object from a stream and returns a pointer to it. Get
  242.   is the counterpart of Put, and can only read objects that were
  243.   written by Put. Get reads the 16-bit object type identifier
  244.   from the stream and then calls the object type's Load
  245.   constructor, which allocates an object on the heap and reads a
  246.   binary copy of it from the stream.
  247.  
  248.   If the 16-bit object type identifier is zero, Get returns a
  249.   NIL. If the object type identifier is out of range, the
  250.   stream's error method is called with an error code of -2, and
  251.   Get returns a NIL.
  252.  
  253.  
  254. ERROR HANDLING METHODS
  255.  
  256. procedure Error(Code: Integer); virtual;
  257.  
  258.   This method is called whenever an error occurs on the stream.
  259.   Code contains the 16-bit error code, which for DOS file streams
  260.   is a DOS error code (see the Run-time Errors in Appendix D in
  261.   the Reference Guide). Unless overridden, the Error method just
  262.   stores Code in the stream's Status field.
  263.  
  264.  
  265. The DosStream type
  266. ------------------
  267.  
  268. The DosStream type implements a DOS file stream. Data written to
  269. a DosStream is written to a DOS file, and data read from a
  270. DosStream is read from a DOS file.
  271.  
  272.  
  273. FIELDS
  274.  
  275. Handle          DOS file handle.
  276.  
  277.  
  278. CONSTRUCTORS AND DESTRUCTORS
  279.  
  280. constructor Init(FileName: FNameStr; Mode: Word);
  281.  
  282.   Calls Stream.Init and then opens the file given by FileName
  283.   using the access mode given by Mode. Valid Mode values are
  284.   defined by the constants SCreate, SOpenRead, SOpenWrite, and
  285.   SOpen. SCreate causes a new file to be created. SOpenRead,
  286.   SOpenWrite, and SOpen opens an existing file in read-only mode,
  287.   write-only mode, or read/write mode. The DOS file handle is
  288.   stored in the Handle field.
  289.  
  290. destructor Done; virtual;
  291.  
  292.   Closes the file and then calls Stream.Done.
  293.  
  294.  
  295. BASIC I/O METHODS
  296.  
  297. procedure Read(var Buf; Count: Word); virtual;
  298.  
  299.   Implements Read for a DOS file. Count bytes are read from the
  300.   file into Buf using DOS function 3FH. In case of error, Buf is
  301.   filled with zeros.
  302.  
  303. procedure Write(var Buf; Count: Word); virtual;
  304.  
  305.   Implements Write for a DOS file. Count bytes are written to the
  306.   file from Buf using DOS function 40H.
  307.  
  308. procedure Truncate; virtual;
  309.  
  310.   Implements Truncate for a DOS file using DOS function 40H with
  311.   a count of zero.
  312.  
  313. function GetPos: Longint; virtual;
  314.  
  315.   Implements GetPos for a DOS file using DOS function 42H.
  316.  
  317. procedure SetPos(Pos: Longint; Mode: Byte); virtual;
  318.  
  319.   Implements SetPos for a DOS file using DOS function 42H.
  320.  
  321. procedure Open(var Name; Mode: Word);
  322.  
  323.   Private method which creates or opens the file using DOS
  324.   function 3CH or 3DH. Called from DosStream.Init and should
  325.   never be called directly.
  326.  
  327. procedure Close;
  328.  
  329.   Private method which flushes the stream buffer (using the Flush
  330.   method) and closes the file. Called from DosStream.Done and
  331.   should never be called directly.
  332.  
  333.  
  334. The BufStream type
  335. ------------------
  336.  
  337. The BufStream type implements a buffered DOS stream. Input and
  338. output with a BufStream is buffered in blocks of a user specified
  339. size. When an application makes a large number of Read and Write
  340. method calls with a small transfer size, using a BufStream rather
  341. than a DosStream will substantially improve performance. For a
  342. typical stream, a buffer size of 1024 bytes is suggested.
  343.  
  344. FIELDS
  345.  
  346. Buffer          Pointer to an I/O buffer of BufSize bytes.
  347.  
  348. BufSize         Size of I/O buffer.
  349.  
  350. BufPtr          Index of current buffer position in the buffer.
  351.  
  352. BufEnd          Index of current buffer end in the buffer. BufPtr
  353.                 is equal to BufEnd, the buffer is empty. When
  354.                 BufPtr is less than BufEnd, the buffer is in read
  355.                 mode and the bytes between BufPtr and BufEnd have
  356.                 been read ahead from the file. When BufPtr is
  357.                 greater than BufEnd, the file is in write mode
  358.                 and the bytes between BufEnd and BufPtr have been
  359.                 written to the file but not yet flushed to disk.
  360.  
  361.  
  362. CONSTRUCTORS AND DESTRUCTORS
  363.  
  364. constructor Init(FileName: FNameStr; Mode, Size: Word);
  365.  
  366.   Allocates a buffer of Size bytes and then calls DosStream.Init.
  367.  
  368. destructor Done; virtual;
  369.  
  370.   Calls DosStream.Done and then disposes the stream buffer.
  371.  
  372.  
  373. BASIC I/O METHODS
  374.  
  375. procedure Read(var Buf; Count: Word); virtual;
  376.  
  377.   Implements Read for a buffered stream. The stream buffer is
  378.   used to buffer disk read operations in blocks of BufSize bytes.
  379.  
  380. procedure Write(var Buf; Count: Word); virtual;
  381.  
  382.   Implements Write for a buffered stream. The stream buffer is
  383.   used to buffer disk write operations in blocks of BufSize
  384.   bytes.
  385.  
  386. procedure Flush; virtual;
  387.  
  388.   Flushes the stream's buffer.
  389.  
  390. function GetPos: Longint; virtual;
  391.  
  392.  
  393. The Node type
  394. -------------
  395.  
  396. Node is an abstract type that serves as the ultimate ancestor of
  397. all objects that are kept on linked lists using the List type.
  398. The Next field points to the next node on the list. If the node
  399. is the last node on the list, the Next field points to the first
  400. node, thus making the list circular. The Prev method returns a
  401. pointer to the preceding node. If the node is the first node of
  402. the list, the Prev method returns a pointer to the last node.
  403.  
  404.  
  405. The List type
  406. -------------
  407.  
  408. The List type implements the basic algorithms of a circular
  409. linked list. The objects kept on a List must be derived from the
  410. abstract Node type. Other abstract types, such as stacks and
  411. queues, can be built from the List type, since they are simply
  412. restricted versions of the functionality provided by List.
  413.  
  414. The List type does not inherit and has no virtual methods. For
  415. that reason, no constructors or destructors are needed in the
  416. List object.
  417.  
  418.  
  419. FIELDS
  420.  
  421. Last            Pointer to the last node on the list, or NIL if
  422.                 the list is empty. The Next field of the last
  423.                 node on a list, i.e. Last^.Next, points to the
  424.                 first node on the list.
  425.  
  426.  
  427. LIST MANAGEMENT METHODS
  428.  
  429. procedure Clear;
  430.  
  431.   Clears the list by setting the Last field to NIL. Any nodes on
  432.   the list are not disposed.
  433.  
  434. procedure Delete;
  435.  
  436.   Disposes all nodes on the list using their Done destructor.
  437.  
  438. procedure Append(N: NodePtr);
  439.  
  440.   Appends a node. The new node becomes the first node on the
  441.   list.
  442.  
  443. procedure Insert(N: NodePtr);
  444.  
  445.   Inserts a node. The new node becomes the last node on the list.
  446.  
  447. procedure Remove(N: NodePtr);
  448.  
  449.   Removes a node. The node itself is not disposed.
  450.  
  451. function First: NodePtr;
  452.  
  453.   Returns a pointer to the first node on the list, or NIL if the
  454.   list is empty. The last node on the list can be directly
  455.   accessed through the Last field.
  456.  
  457. function Next(N: NodePtr): NodePtr;
  458.  
  459.   Returns a pointer to the node after N, or NIL if N is the last
  460.   node. This corresponds to N^.Next, except that the Next field
  461.   of the last node points to the first node in the list.
  462.  
  463. function Prev(N: NodePtr): NodePtr;
  464.  
  465.   Returns a pointer to the node before N, or NIL if N is the
  466.   first node. This corresponmds to N^.Prev, except that the Prev
  467.   method of the first node will return the last node in the list.
  468.  
  469. function Empty: Boolean;
  470.  
  471.   Returns True if the list is empty, else returns False.
  472.  
  473.  
  474. STREAM I/O ROUTINES
  475.  
  476. procedure Store(var S: Stream);
  477.  
  478.   Stores the list on a stream. The types of all nodes of the list
  479.   must have been registered with the stream. The list is stored
  480.   by applying S.Put to each node in the list, followed by an
  481.   S.Put(NIL).
  482.  
  483. procedure Load(var S: Stream);
  484.  
  485.   Loads the list from a stream. The types of all nodes of the
  486.   list to be loaded must have been registered with the stream.
  487.   The list is loaded by appending the result of S.Get until S.Get
  488.   returns NIL.
  489.  
  490.  
  491. ODEMO.PAS - AN EXAMPLE THAT USES STREAMS AND LISTS
  492. --------------------------------------------------
  493.  
  494. The ODemo program demonstrates input and output of polymorphic
  495. objects using a stream. A list of IntNode and StrNode objects is
  496. created, written to a file, deleted, and finally reloaded from
  497. the file. Notice how the list is built using the List type from
  498. the Objects unit.
  499.  
  500.  
  501. FORMS.PAS - IMPLEMENTS A FORM ENTRY AND EDIT OBJECT
  502. ---------------------------------------------------
  503.  
  504. The Forms unit implements two basic object types: Field and Form.
  505. A Field represents a data entry field, and a Form represents a
  506. collection of Fields which add up to a complete data entry form.
  507.  
  508. A number of field types are implemented by the Forms unit. Viewed
  509. as a whole, they form the following hierarchy:
  510.  
  511.   Field                                  (Abstract field type)
  512.   └───────FText                          (Abstract text field)
  513.           ├───────FStr                   (String field)
  514.           └───────FNum                   (Abstract numeric field)
  515.                   ├───────FInt           (Integer field)
  516.                   │       └───────FZip   (Zipcode field)
  517.                   └───────FReal          (Floating point field)
  518.  
  519. The basic Field type defines the common properties of all fields.
  520. It is an abstract type, which exists only so that other field
  521. types can inherit from it. Instances of type Field are never
  522. actually created. Field is derived from Node (defined in the
  523. Objects unit), so that fields can be put on a linked list that
  524. makes up a data entry form. The data fields of type Field are:
  525.  
  526. X           X coordinate in the form.
  527. Y           Y coordinate in the form.
  528. Size        Size of the data stored in the field.
  529. Title       Pointer to a title string.
  530. Value       Pointer to current value (Size bytes long).
  531. Extra       Marks location of fields defined in descendant types.
  532.  
  533. The methods of a Field are:
  534.  
  535. Init        Allocates and initializes a field.
  536. Load        Loads a field from a stream.
  537. Done        Cleans up and disposes a field.
  538. Clear       Sets a field to its default value.
  539. Edit        Edits a field and returns termination character.
  540. Show        Displays a field.
  541. Store       Stores a field on a stream.
  542.  
  543. The FText type is an abstract type which serves as the ancestor
  544. of all text field types. It defines two "helper" methods, GetStr
  545. and PutStr, and implements code for the Edit and Show methods.
  546. GetStr converts a field's value to a string. PutStr converts a
  547. string and stores it as the field's value. PutStr returns True if
  548. the string represents a valid value; else it returns false and
  549. leaves the field's value unchanged.
  550.  
  551. The FStr type implements a String field with a user defined
  552. maximum length.
  553.  
  554. The FNum type is the abstract ancestor type of all numeric
  555. fields. It changes the Show method to right justify the value
  556. when it is displayed.
  557.  
  558. The FInt type implements a Longint field with user defined upper
  559. and lower bounds.
  560.  
  561. The FZip type implements a zipcode field, which essentially is a
  562. 5-digit FInt field that gets left-padded with zeros when
  563. displayed.
  564.  
  565. The FReal type implements a floating point value field with a
  566. user defined total width and number of decimals.
  567.  
  568. The Form type defines a form, which primarily is a collection of
  569. fields kept on a list. The data fields of type Form are:
  570.  
  571. X1          Left coordinate of Form window.
  572. Y1          Top coordinate of Form window.
  573. X2          Right coordinate of Form window.
  574. Y2          Bottom coordinate of Form window.
  575. Size        Total size of data in the form. This is the sum of
  576.             the Size fields of each field on the Fields list.
  577. Fields      List of Field objects.
  578.  
  579. The methods of a Form are:
  580.  
  581. Init        Allocates and initializes a form.
  582. Load        Loads a form from a stream.
  583. Done        Cleans up and disposes a form.
  584. Edit        Edits a form and returns termination character.
  585. Show        Displays a form, optionally first erasing the window.
  586. Add         Adds a field to a form.
  587. Clear       Sets all fields to their default values.
  588. Get         Copies a form into a variable.
  589. Put         Copies a variable into a form.
  590. Store       Stores a form on a stream.
  591.  
  592. The fields in a form a kept on a linked list, which is managed by
  593. the List type in the Objects unit. Notice how the Edit, Show,
  594. Clear, Get, and Put methods use typecasts to promote the nodes of
  595. the list from type Node to type Field (a descendant of Node). The
  596. Form object "knows" that the entries on the field list are always
  597. of type Field, and can therefore safely promote them.
  598.  
  599. The Get and Put methods are used to copy data into and out of a
  600. form. A variable specified as a parameter to Get or Put must be
  601. record with fields that correspond in order, type, and size to
  602. the fields of the form.
  603.  
  604. The FStream type implements a buffered stream that knows the
  605. FStr, FInt, FZip, and FReal types. Notice how only the
  606. RegisterTypes method is overridden, and how it first calls the
  607. inherited RegisterTypes before registering any new types.
  608.  
  609.  
  610. SLIDERS.PAS - IMPLEMENTS A SLIDER FIELD
  611. ---------------------------------------
  612.  
  613. The Sliders unit implements a new Field type, called FSlider, for
  614. use with the Forms unit. Contrary to the text field types
  615. implemented by the Forms unit, a slider shows and edits itself as
  616. a scroll-bar like control with a knob that indicates the current
  617. value. The FSlider type is a direct descendant of the Field type.
  618. The current slider value, and the minimum, maximum, and delta
  619. values of the slider are stored as 16-bit integers.
  620.  
  621. In addition to the FSlider type, the Sliders unit defines a new
  622. FStream type. It is a direct descendant of the FStream type in
  623. Forms (notice how the same name can be used in two different
  624. units). Sliders.FStream differs from Forms.FStream only in the
  625. RegisterTypes method, which adds registration of the FSlider
  626. type; this is required so that sliders can be stored on and
  627. loaded from streams along with other field types.
  628.  
  629.  
  630. FDEMO.PAS - A SIMPLE FORMS EDITOR EXAMPLE
  631. -----------------------------------------
  632.  
  633. The FDemo program uses the Forms and Sliders unit to implement a
  634. simple forms editor program, which lets you edit a record using a
  635. form. Notice how the fields in a Person record correspond in
  636. order, type, and size to the fields in the form. The Form.Put and
  637. Form.Get methods require this one-to-one mapping in order to work
  638. correctly.
  639.  
  640.  
  641. CARDS.PAS - IMPLEMENTS A CARD FILE OBJECT
  642. -----------------------------------------
  643.  
  644. The Cards unit implements a Rolodex-like card file object. The
  645. cards are kept on a doubly-linked list which can be traversed
  646. using the Next and Prev methods.
  647.  
  648. The Insert and Delete methods allow insertion and deletion at the
  649. current location in the card list. The current location is a
  650. state variable maintained by the CardList object.
  651.  
  652.  
  653. CARDFILE.PAS - A SIMPLE CARD FILER APPLCIATION
  654. ----------------------------------------------
  655.  
  656. The CardFile program implements a simple card filer application.
  657. It takes a card file name as a command-line argument, loads that
  658. file, and allows you to scroll through and edit it. A card file
  659. contains a saved Form object followed by a saved CardList object.
  660. The CardFile application is not limited to a specific form
  661. layout--the form is loaded from the a disk file rather than being
  662. statically built in CARDFILE.PAS.
  663.  
  664. A sample card file, CARDS.DTA, is provided on the disk. To run
  665. the card filer with that file, use the command line:
  666.  
  667.   CARDFILE CARDS.DTA
  668.  
  669.  
  670. CARDGEN.PAS - CARD FILER FORMS GENERATOR
  671. ----------------------------------------
  672.  
  673. CARDGEN.PAS is a sample program that defines two forms and saves
  674. them in disk files that can be edited using CARDFILE.PAS. If you
  675. run CARDGEN.PAS, it will create new PARTS.DTA and PEOPLE.DTA
  676. files (and thus overwrite any existing files with those names, so
  677. beware).
  678.