home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / DDJ1289.ZIP / KIENLE.LST < prev    next >
File List  |  1989-10-30  |  19KB  |  713 lines

  1. _NETWORK GRAPHS IN OBJECT PASCAL_
  2. by Steven Kienle
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7. TYPE
  8.     GraphNode =
  9.         OBJECT(TObject)
  10.             Next: GraphNode;
  11.             HotRegion: RgnHandle;
  12.  
  13.             PROCEDURE Initialize;
  14.                 { Drawing Methods }
  15.             PROCEDURE Draw;
  16.             PROCEDURE DrawAll;
  17.             PROCEDURE Erase;
  18.             PROCEDURE EraseAll;
  19.                 { Location Methods }
  20.             PROCEDURE SetRegion;
  21.             FUNCTION PtInNode(Where: Point): Boolean;
  22.             FUNCTION FindNode(Where: Point): GraphNode;
  23.             FUNCTION Connected(Which: GraphNode): Boolean;
  24.             FUNCTION FindConnected(Which: GraphNode): GraphNode;
  25.                 { Freeing Methods }
  26.             PROCEDURE Free; OVERRIDE;
  27.             PROCEDURE FreeAll;
  28.         END;
  29.  
  30.     GraphList =
  31.         OBJECT(TObject)
  32.             FirstNode: GraphNode;
  33.             PROCEDURE Initialize;
  34.                 { Drawing Methods }
  35.             PROCEDURE Erase;
  36.             PROCEDURE Draw;
  37.                 { GraphList Manipulation Methods }
  38.             PROCEDURE AddNode(Which: GraphNode);
  39.             PROCEDURE RemoveNode(Which: GraphNode);
  40.                 { Location Methods }
  41.             FUNCTION FindNode(Where: Point): GraphNode;
  42.             FUNCTION FindConnected(Which: GraphNode): GraphNode;
  43.                 { Freeing Methods }
  44.             PROCEDURE Free; OVERRIDE;
  45.         END;
  46.  
  47.     Vertex =
  48.         OBJECT(GraphNode)
  49.             Center: Point; { Location of Vertex }
  50.             PROCEDURE Initialize; OVERRIDE;
  51.                 { Drawing Methods }
  52.             PROCEDURE Draw; OVERRIDE;
  53.             PROCEDURE Erase; OVERRIDE;
  54.                 { Location Methods }
  55.             PROCEDURE SetRegion; OVERRIDE;
  56.             PROCEDURE SetCenter(thePoint: Point);
  57.         END;
  58.  
  59.     Edge =
  60.         OBJECT(GraphNode)
  61.             FromVertex: Vertex; { End Points of Edge }
  62.             ToVertex: Vertex;
  63.             PROCEDURE Initialize; OVERRIDE;
  64.                 { Drawing Methods }
  65.             PROCEDURE Draw; OVERRIDE;
  66.             PROCEDURE Erase; OVERRIDE;
  67.                 { Location Methods }
  68.             PROCEDURE SetRegion; OVERRIDE;
  69.             FUNCTION Connected(Which: GraphNode): Boolean; 
  70. OVERRIDE;
  71.             PROCEDURE Edge.SetFrom(Which: Vertex);
  72.             PROCEDURE Edge.SetTo(Which: Vertex);
  73.         END;
  74.  
  75.     Graph =
  76.         OBJECT(TObject)
  77.             VertexList: GraphList;
  78.             EdgeList: GraphList;
  79.             PROCEDURE Initialize;
  80.                 { Drawing Methods }
  81.             PROCEDURE Draw;
  82.             PROCEDURE Erase;
  83.                 { Manipulation Routines }
  84.             PROCEDURE AddVertex(Where: Point);
  85.             PROCEDURE AddEdge(FromWhich, ToWhich: Vertex);
  86.             PROCEDURE RemoveVertex(Where: Point);
  87.             PROCEDURE RemoveEdge(Where: Point);
  88.             PROCEDURE SetVertexCenter
  89.                       (Which: Vertex; Where: Point);
  90.                 { Macintosh Support Routines }
  91.             PROCEDURE MoveVertex(Start: Point);
  92.             PROCEDURE LinkVertices(Start: Point);
  93.                 { Freeing Method }
  94.             PROCEDURE Free; OVERRIDE;
  95.         END;
  96.  
  97. { -------------- GraphNode Methods -------------- }
  98. PROCEDURE GraphNode.Initialize;
  99.     BEGIN
  100.         SELF.Next := NIL;
  101.         SELF.HotRegion := NIL;
  102.     END;
  103.  
  104. PROCEDURE GraphNode.Draw;
  105.     BEGIN
  106.     END;
  107.  
  108. PROCEDURE GraphNode.DrawAll;
  109.     BEGIN
  110.         IF SELF.Next <> NIL THEN
  111.             SELF.Next.DrawAll; { Draw next GraphNode }
  112.         SELF.Draw; { Draw this GraphNode }
  113.     END;
  114.  
  115. PROCEDURE GraphNode.Erase;
  116.     BEGIN
  117.     END;
  118.  
  119. PROCEDURE GraphNode.EraseAll;
  120.     BEGIN
  121.         IF SELF.Next <> NIL THEN
  122.             SELF.Next.EraseAll; { Erase next GraphNode }
  123.         SELF.Erase; { Erase this GraphNode }
  124.     END;
  125.  
  126. PROCEDURE GraphNode.SetRegion;
  127.     BEGIN
  128.         IF SELF.HotRegion <> NIL THEN { Drop old Region }
  129.             DisposeRgn(SELF.HotRegion);
  130.         SELF.HotRegion := NewRgn; { Allocate a new one }
  131.     END;
  132.  
  133. FUNCTION GraphNode.PtInNode(Where: Point): Boolean;
  134.     BEGIN
  135.         IF PtInRgn(Where, SELF.HotRegion) THEN
  136.             PtInNode := True
  137.         ELSE
  138.             PtInNode := False;
  139.     END;
  140.  
  141. FUNCTION GraphNode.FindNode(Where: Point): GraphNode;
  142.     BEGIN
  143.         IF SELF.PtInNode(Where) THEN { It's here }
  144.             FindNode := SELF
  145.         ELSE IF SELF.Next = NIL THEN { There are none }
  146.             FindNode := NIL
  147.         ELSE { Try the Next }
  148.             FindNode := SELF.Next.FindNode(Where);
  149.     END;
  150.  
  151. FUNCTION GraphNode.Connected(Which: GraphNode): Boolean;
  152.     BEGIN
  153.         Connected := False;
  154.     END;
  155.  
  156. FUNCTION GraphNode.FindConnected(Which: GraphNode): GraphNode;
  157.     BEGIN
  158.         IF SELF.Connected(Which) THEN { Is this connected }
  159.             FindConnected := SELF
  160.         ELSE IF SELF.Next = NIL THEN { There are none }
  161.             FindConnected := NIL
  162.         ELSE { Try the Next }
  163.             FindConnected := SELF.Next.FindConnected(Which);
  164.     END;
  165.  
  166. PROCEDURE GraphNode.Free;
  167.     BEGIN
  168.         IF SELF.HotRegion <> NIL THEN { Free Region Space }
  169.             DisposeRgn(SELF.HotRegion);
  170.         SELF.Erase; { Erase then Free }
  171.         INHERITED Free;
  172.     END;
  173.  
  174. PROCEDURE GraphNode.FreeAll;
  175.     BEGIN
  176.         IF SELF.Next <> NIL THEN { Free the next GraphNode }
  177.             SELF.Next.FreeAll;
  178.         SELF.Free; { Then Free this GraphNode }
  179.     END;
  180.  
  181. { -------------- GraphList Methods -------------- }
  182. PROCEDURE GraphList.Initialize;
  183.     BEGIN
  184.         SELF.FirstNode := NIL;
  185.     END;
  186.  
  187. PROCEDURE GraphList.Erase;
  188.     BEGIN
  189.         IF SELF.FirstNode <> NIL THEN
  190.             SELF.FirstNode.EraseAll; { Erase the GraphList }
  191.     END;
  192.  
  193. PROCEDURE GraphList.Draw;
  194.     BEGIN
  195.         IF SELF.FirstNode <> NIL THEN
  196.             SELF.FirstNode.DrawAll; { Draw the GraphList }
  197.     END;
  198.  
  199. PROCEDURE GraphList.AddNode(Which: GraphNode);
  200.     BEGIN
  201.         Which.Next := SELF.FirstNode; { Link Which in GraphList }
  202.         SELF.FirstNode := Which;
  203.     END;
  204.  
  205. PROCEDURE GraphList.RemoveNode(Which: GraphNode);
  206.     VAR
  207.         Check: GraphNode;
  208.     BEGIN
  209.         { If it is the head GraphNode, relink the Head }
  210.         IF SELF.FirstNode = Which THEN
  211.             SELF.FirstNode := Which.Next
  212.         ELSE BEGIN
  213.             { Otherwise look for Which GraphNode }
  214.             Check := SELF.FirstNode;
  215.             WHILE (Check <> NIL) DO BEGIN
  216.                 { If Which is found, remove it from GraphList }
  217.                 IF Check.Next = Which THEN
  218.                     Check.Next := Which.Next;
  219.                 Check := Check.Next;
  220.             END;
  221.         END;
  222.  
  223.         Which.Free; { Free this node }
  224.     END;
  225.  
  226. FUNCTION GraphList.FindNode(Where: Point): GraphNode;
  227.     BEGIN { Find the Node at this location }
  228.         IF SELF.FirstNode <> NIL THEN
  229.             FindNode := SELF.FirstNode.FindNode(Where)
  230.         ELSE
  231.             FindNode := NIL;
  232.     END;
  233.  
  234. FUNCTION GraphList.FindConnected(Which: GraphNode): GraphNode;
  235.     BEGIN { Find the Node connected to this one }
  236.         IF SELF.FirstNode <> NIL THEN
  237.             FindConnected := SELF.FirstNode.FindConnected(Which)
  238.         ELSE
  239.             FindConnected := NIL;
  240.     END;
  241.  
  242. PROCEDURE GraphList.Free;
  243.     BEGIN
  244.         IF SELF.FirstNode <> NIL THEN
  245.             SELF.FirstNode.FreeAll; { Free the Nodes }
  246.         INHERITED Free; { Free GraphList }
  247.     END;
  248.  
  249. { -------------- Vertex Methods -------------- }
  250. PROCEDURE Vertex.Initialize;
  251.     BEGIN
  252.         INHERITED Initialize;
  253.         SELF.Center.h := 0;
  254.         SELF.Center.v := 0;
  255.     END;
  256.  
  257. PROCEDURE Vertex.Draw;
  258.     VAR
  259.         theRect: Rect;
  260.     BEGIN
  261.         SELF.Erase; { Erase Vertex Area }
  262.         { Set up Rectangle }
  263.         theRect.top := SELF.Center.v - 10;
  264.         theRect.left := SELF.Center.h - 10;
  265.         theRect.bottom := SELF.Center.v + 10;
  266.         theRect.right := SELF.Center.h + 10;
  267.         { Draw Vertex }
  268.         FrameOval(theRect);
  269.     END;
  270.  
  271. PROCEDURE Vertex.Erase;
  272.     VAR
  273.         theRect: Rect;
  274.     BEGIN
  275.         { Set up Rectangle }
  276.         theRect.top := SELF.Center.v - 10;
  277.         theRect.left := SELF.Center.h - 10;
  278.         theRect.bottom := SELF.Center.v + 10;
  279.         theRect.right := SELF.Center.h + 10;
  280.         { Erase Vertex }
  281.         EraseOval(theRect);
  282.     END;
  283.  
  284. PROCEDURE Vertex.SetRegion;
  285.     BEGIN
  286.         INHERITED SetRegion; { Do default processing }
  287.         OpenRgn; { Create new region area }
  288.         SELF.Draw;
  289.         CloseRgn(SELF.HotRegion);
  290.     END;
  291.  
  292. PROCEDURE Vertex.SetCenter(thePoint: Point);
  293.     BEGIN
  294.         SELF.Erase; { Erase Vertex at old Center }
  295.         SELF.Center := thePoint; { Set the Center }
  296.         SELF.Draw; { Draw Vertex at new Center }
  297.         SELF.SetRegion; { Reset HotRegion }
  298.     END;
  299.  
  300. { -------------- Edge Methods -------------- }
  301. PROCEDURE Edge.Initialize;
  302.     BEGIN
  303.         INHERITED Initialize;
  304.         FromVertex := NIL;
  305.         ToVertex := NIL;
  306.     END;
  307.  
  308. PROCEDURE Edge.Draw;
  309.     VAR
  310.         Where: Point;
  311.     BEGIN
  312.         IF (SELF.FromVertex <> NIL) AND (SELF.ToVertex <> NIL) THEN 
  313. BEGIN
  314.             { Start in center of FromVertex }
  315.             Where := SELF.FromVertex.Center;
  316.             MoveTo(Where.h, Where.v);
  317.             { Draw line to center of ToVertex }
  318.             Where := SELF.ToVertex.Center;
  319.             LineTo(Where.h, Where.v);
  320.         END;
  321.     END;
  322.  
  323. PROCEDURE Edge.Erase;
  324.     VAR
  325.         pnState: PenState;
  326.     BEGIN
  327.         GetPenState(pnState); { Save current settings }
  328.         PenPat(white); { Set color & Draw to erase }
  329.         SELF.Draw;
  330.         SetPenState(pnState); { Reset settings }
  331.         SELF.FromVertex.Draw; { Redraw affected Vertices }
  332.         SELF.ToVertex.Draw;
  333.     END;
  334.  
  335. PROCEDURE Edge.SetRegion;
  336.     BEGIN
  337.         INHERITED SetRegion; { Do default processing }
  338.         OpenRgn; { Create new region area }
  339.             MoveTo(SELF.FromVertex.Center.h + 4, 
  340. SELF.FromVertex.Center.v + 4);
  341.         LineTo(SELF.ToVertex.Center.h + 4, SELF.ToVertex.Center.v + 4);
  342.         LineTo(SELF.ToVertex.Center.h - 4, SELF.ToVertex.Center.v - 4);
  343.             LineTo(SELF.FromVertex.Center.h - 4, 
  344. SELF.FromVertex.Center.v - 4);
  345.             LineTo(SELF.FromVertex.Center.h + 4, 
  346. SELF.FromVertex.Center.v + 4);
  347.         CloseRgn(SELF.HotRegion);
  348.     END;
  349.  
  350. FUNCTION Edge.Connected(Which: GraphNode): Boolean;
  351.     BEGIN
  352.         IF (SELF.FromVertex = Which) OR (SELF.ToVertex = Which) THEN
  353.             Connected := True
  354.         ELSE
  355.             Connected := False;
  356.     END;
  357.  
  358. PROCEDURE Edge.SetFrom(Which: Vertex);
  359.     BEGIN
  360.         IF (SELF.FromVertex <> NIL) AND (SELF.ToVertex <> NIL) THEN 
  361. BEGIN
  362.             { Erase old edge and redraw unlinked Vertex }
  363.             SELF.Erase;
  364.             SELF.FromVertex.Draw;
  365.         END;
  366.         SELF.FromVertex := Which;
  367.         IF (SELF.FromVertex <> NIL) AND (SELF.ToVertex <> NIL) THEN 
  368. BEGIN
  369.             { Draw new edge and redraw linked Vertices }
  370.             SELF.Draw;
  371.             SELF.FromVertex.Draw;
  372.             SELF.ToVertex.Draw;
  373.             SELF.SetRegion; { Reset HotRegion }
  374.         END;
  375.     END;
  376.  
  377. PROCEDURE Edge.SetTo(Which: Vertex);
  378.     BEGIN
  379.         IF (SELF.FromVertex <> NIL) AND (SELF.ToVertex <> NIL) THEN 
  380. BEGIN
  381.             { Erase old edge and redraw unlinked Vertex }
  382.             SELF.Erase;
  383.             SELF.ToVertex.Draw;
  384.         END;
  385.         SELF.ToVertex := Which;
  386.         IF (SELF.FromVertex <> NIL) AND (SELF.ToVertex <> NIL) THEN 
  387. BEGIN
  388.             { Draw new edge and redraw linked Vertices }
  389.             SELF.Draw;
  390.             SELF.FromVertex.Draw;
  391.             SELF.ToVertex.Draw;
  392.             SELF.SetRegion; { Reset HotRegion }
  393.         END;
  394.     END;
  395.  
  396. { -------------- Graph Methods -------------- }
  397. PROCEDURE Graph.Initialize;
  398.     BEGIN
  399.         New(SELF.VertexList);
  400.         SELF.VertexList.Initialize;
  401.         New(SELF.EdgeList);
  402.         SELF.EdgeList.Initialize;
  403.     END;
  404.  
  405. PROCEDURE Graph.Draw;
  406.     BEGIN
  407.         IF SELF.EdgeList <> NIL THEN
  408.             SELF.EdgeList.Draw;
  409.         IF SELF.VertexList <> NIL THEN
  410.             SELF.VertexList.Draw;
  411.     END;
  412.  
  413. PROCEDURE Graph.Erase;
  414.     BEGIN
  415.         SELF.EdgeList.Erase;
  416.         SELF.VertexList.Erase;
  417.     END;
  418.  
  419. PROCEDURE Graph.AddVertex(Where: Point);
  420.     VAR
  421.         NewVertex: Vertex;
  422.     BEGIN
  423.         { Create and initialize a new Vertex at Where }
  424.         New(NewVertex);
  425.         NewVertex.Initialize;
  426.         NewVertex.SetCenter(Where);
  427.         { Add new vertex to list, typecasting is required }
  428.         SELF.VertexList.AddNode(GraphNode(NewVertex));
  429.     END;
  430.  
  431. PROCEDURE Graph.RemoveVertex(Where: Point);
  432.     VAR
  433.         WhichEdge: GraphNode;
  434.         WhichVertex: GraphNode;
  435.     BEGIN
  436.         { Find the appropriate Node }
  437.         WhichVertex := SELF.VertexList.FindNode(Where);
  438.         { If it exists... }
  439.         IF WhichVertex <> NIL THEN BEGIN
  440.             REPEAT
  441.                 { Find Edges Connected to the Vertex }
  442.                 WhichEdge := 
  443. SELF.EdgeList.FindConnected(WhichVertex);
  444.                 { If an Edge exists, remove it }
  445.                 IF WhichEdge <> NIL THEN
  446.                     SELF.EdgeList.RemoveNode(WhichEdge);
  447.             UNTIL (WhichEdge = NIL);
  448.             { Finally, remove the Vertex }
  449.             SELF.VertexList.RemoveNode(WhichVertex);
  450.         END;
  451.     END;
  452.  
  453. PROCEDURE Graph.AddEdge(FromWhich, ToWhich: Vertex);
  454.     VAR
  455.         NewEdge: Edge;
  456.     BEGIN
  457.         { Create and initialize a new Vertex at Where }
  458.         New(NewEdge);
  459.         NewEdge.Initialize;
  460.         NewEdge.SetFrom(FromWhich);
  461.         NewEdge.SetTo(ToWhich);
  462.         { Add new vertex to list, typecasting is required }
  463.         SELF.EdgeList.AddNode(GraphNode(NewEdge));
  464.     END;
  465.  
  466. PROCEDURE Graph.RemoveEdge(Where: Point);
  467.     VAR
  468.         WhichEdge: GraphNode;
  469.     BEGIN
  470.         { Find the appropriate Node }
  471.         WhichEdge := SELF.EdgeList.FindNode(Where);
  472.         { If it exists, remove it }
  473.         IF WhichEdge <> NIL THEN
  474.             SELF.EdgeList.RemoveNode(WhichEdge);
  475.     END;
  476.  
  477. PROCEDURE Graph.SetVertexCenter(Which: Vertex; Where: Point);
  478.     VAR
  479.         anEdge: Edge;
  480.     BEGIN
  481.         { Move through the EdgeList finding Connected Instances}
  482.         anEdge := Edge(SELF.EdgeList.FindConnected(GraphNode(Which)));
  483.         WHILE (anEdge <> NIL) DO BEGIN
  484.             anEdge.Erase; { Erase them and move on }
  485.             IF anEdge.Next <> NIL THEN
  486.                 anEdge := 
  487. Edge(anEdge.Next.FindConnected(GraphNode(Which)))
  488.             ELSE
  489.                 anEdge := NIL;
  490.         END;
  491.         Which.SetCenter(Where); { Set the Vertex instance's center }
  492.         { Move through the EdgeList finding Connected Instances}
  493.         anEdge := Edge(SELF.EdgeList.FindConnected(GraphNode(Which)));
  494.         WHILE (anEdge <> NIL) DO BEGIN
  495.             anEdge.Draw; { Draw them and their vertices; move on }
  496.             anEdge.FromVertex.Draw;
  497.             anEdge.ToVertex.Draw;
  498.             IF anEdge.Next <> NIL THEN
  499.                 anEdge := 
  500. Edge(anEdge.Next.FindConnected(GraphNode(Which)))
  501.             ELSE
  502.                 anEdge := NIL;
  503.         END;
  504.     END;
  505.  
  506. PROCEDURE Graph.MoveVertex(Start: Point);
  507.     VAR
  508.         Displacement: Point;
  509.         NewCenter: Point;
  510.         WhichVertex: Vertex;
  511.     BEGIN
  512.         WhichVertex := Vertex(SELF.VertexList.FindNode(Start));
  513.             { If the vertex is moved, find the new center and
  514.                  place the Vertex and redraw affected Edges }
  515.         IF WhichVertex <> NIL THEN
  516.             IF DragRegion(WhichVertex.HotRegion, Start, Displacement.h,
  517.                           Displacement.v) THEN BEGIN
  518.                 NewCenter := WhichVertex.Center;
  519.                 AddPt(Displacement, NewCenter);
  520.                 SELF.SetVertexCenter(WhichVertex, NewCenter);
  521.             END;
  522.     END;
  523.  
  524. PROCEDURE Graph.LinkVertices(Start: Point);
  525.     VAR
  526.         FirstVertex: Vertex;
  527.         LastVertex: Vertex;
  528.         Stop: Point;
  529.     BEGIN
  530.         { Find the FromVertex }
  531.         FirstVertex := Vertex(SELF.VertexList.FindNode(Start));
  532.         IF FirstVertex <> NIL THEN BEGIN
  533.                     DragGrayLine(Start, Stop); { Drag a line around }
  534.             { Find the ToVertex }
  535.             LastVertex := Vertex(SELF.VertexList.FindNode(Stop));
  536.             IF (LastVertex <> NIL) AND (FirstVertex <> LastVertex) THEN
  537.                 SELF.AddEdge(FirstVertex, LastVertex);
  538.         END;
  539.     END;
  540.  
  541. PROCEDURE Graph.Free;
  542.     BEGIN
  543.         SELF.EdgeList.Free;
  544.         SELF.VertexList.Free;
  545.         INHERITED Free;
  546.     END;
  547.  
  548.  
  549. [LISTING TWO]
  550.  
  551.  
  552. Type
  553.     Circle = Object (TObject)        { The Circle class declaration }
  554.             { Instance Variables }
  555.         Center : Point ;        { The Center of the Circle }
  556.         Radius : Integer ;        { The Radius of the Circle }
  557.             { Methods }
  558.         Procedure Draw ;        { Draw the Circle }
  559.         Procedure Erase ;        { Erase the Circle }
  560.     end ;
  561. Procedure Circle.Draw ;
  562.     Var
  563.         theRect : Rect ;        { Rectangular area of the Circle }
  564.     Begin
  565.             { Set up the Rectangle }
  566.         theRect.top := SELF.Center.v - SELF.Radius ;
  567.         theRect.left := SELF.Center.h - SELF.Radius ;
  568.         theRect.bottom := SELF.Center.v + SELF.Radius ;
  569.         theRect.right := SELF.Cener.h + SELF.Radius ;
  570.         FrameOval (theRect) ;        { Draw it }
  571.     End ;
  572. Procedure Circle.Erase ;
  573.     Var
  574.         theRect : Rect ;       { Rectangular area of the Circle }
  575.     Begin
  576.             { Set up the Rectangle }
  577.         theRect.top := SELF.Center.v - SELF.Radius ;
  578.         theRect.left := SELF.Center.h - SELF.Radius ;
  579.         theRect.bottom := SELF.Center.v + SELF.Radius ;
  580.         theRect.right := SELF.Cener.h + SELF.Radius ;
  581.         
  582.         EraseOval (theRect) ;            { Erase it }
  583.     End ;
  584.  
  585.  
  586.  
  587.  
  588. [LISTING THREE]
  589.  
  590. Program DrawtheCircle ;
  591.  
  592. < Circle's type declaration >
  593. Var
  594.     aCircle : Circle ;
  595.  
  596. < Circle's method definitions >
  597. Begin
  598.     new(aCircle) ;                { Get a new instance }
  599.  
  600.     aCircle.Center.h := 50 ;        { Set up instance variables }
  601.     aCircle.Center.v := 50 ;
  602.     aCirlce.Radius := 50 ;
  603.  
  604.     aCircle.Draw ;            {Draw it and free it }
  605.     aCircle.Free ;
  606. End.
  607.  
  608. [LISTING FOUR]
  609.  
  610. Type
  611.     Circle = Object (TObject)       { The Circle class declaration }
  612.             { Instance Variables }
  613.         Center : Point ;        { The Center of the Circle }
  614.         Radius : Integer ;        { The Radius of the Circle }
  615.             { Methods }
  616.         Procedure Draw ;        { Draw the Circle }
  617.         Procedure Erase ;        { Erase the Circle }
  618.         Procedure Free ; Override ; { The Free method needs changes }
  619.     end ;
  620.  
  621. Procedure Circle.Draw ;
  622.     as before
  623. Procedure Circle.Erase ;
  624.     as before
  625. Procedure Cirlce.Free ;
  626.     Begin
  627.         SELF.Erase ;
  628.         Inherited Free ;
  629.     End ;
  630.  
  631.  
  632. [LISTING FIVE]
  633. [Listing Four]
  634.  
  635. Type
  636.     DrawObject = Object (TObject)    { The DrawObject class declaration }
  637.             { Instance Variables }
  638.          Location : Point ;        { The location of the Object }
  639.             { Methods }
  640.          Procedure Draw ;            { Draw the Object }
  641.          Procedure Erase ;            { Erase the Object }
  642.          Procedure Offset (dh, dv : Integer) ; { Offset Object by dh, dv }
  643.          Procedure Free ; Override ;     { The Free method needs changes }
  644.     end ;
  645.     Circle = Object (DrawObject)          { The Circle class declaration }
  646.             { Instance Variables }
  647.         Radius : Integer ;              { The Radius of the Circle }
  648.             { Methods }
  649.         Procedure Draw ; Override ;        { Draw the Circle }
  650.         Procedure Erase ; Override ;        { Erase the Circle }
  651.     end ;
  652.     Rectangle = Object (DrawObject)    { The Rectangle class declaration }
  653.             { Instance Variables }
  654.         horSize : Integer ;   { The Horizontal Size of the Rectangle }
  655.         verSize : Integer ;      { The Verical Size of the Rectangle }
  656.             { Methods }
  657.         Procedure Draw ; Override ;        { Draw the Rectangle }
  658.         Procedure Erase ; Override ;        { Erase the Rectangle }
  659.     end ;
  660.  
  661. { --------------- The DrawObject Methods --------------- }
  662. Procedure DrawObject .Draw ;
  663.     Begin
  664.     End ;
  665. Procedure DrawObject .Erase ;
  666.     Begin
  667.     End ;
  668. Procedure DrawObject .Offset (dh, dv : Integer) ; { Offset Object by dh, dv }
  669.     Begin
  670.         SELF.Erase ;         { Erase Object at its present location }
  671.             { Change the location of the Object }
  672.         SELF.Location.h := SELF.Location.h + dh ;
  673.         SELF.Location.v := SELF.Location.v + dv ;
  674.         SELF.Draw ;        { Draw Object at its new location }
  675.     End ;
  676. Procedure DrawObject.Free ;
  677.     Begin
  678.         SELF.Erase ;
  679.         Inherited Free ;
  680.     End ;
  681.  
  682. { --------------- The Circle Methods --------------- }
  683. Procedure Circle.Draw ;
  684.     as before
  685. Procedure Circle.Erase ;
  686.     as before
  687.  
  688. { --------------- The Rectangle Methods --------------- }
  689. Procedure Rectangle .Draw ;
  690.     Var
  691.         theRect : Rect ;    { Rectangular area of the Circle }
  692.     Begin
  693.             { Set up the Rectangle }
  694.         theRect.top := SELF.Location.v ;
  695.         theRect.left := SELF.Location.h ;
  696.         theRect.bottom := SELF.Location.v + SELF.verSize ;
  697.         theRect.right := SELF.Location.h + SELF.horSize ;
  698.         FrameRect (theRect) ;        { Draw it }
  699.     End ;
  700. Procedure Circle.Erase ;
  701.     Var
  702.         theRect : Rect ;        { Rectangular area of the Circle }
  703.     Begin
  704.             { Set up the Rectangle }
  705.         theRect.top := SELF.Location.v ;
  706.         theRect.left := SELF.Location.h ;
  707.         theRect.bottom := SELF.Location.v + SELF.verSize ;
  708.         theRect.right := SELF.Location.h + SELF.horSize ;
  709.         EraseRect (theRect) ;        { Draw it }
  710.     End ;
  711.  
  712.  
  713.