UNIT UPexample; INTERFACE USES {$U UObject} UObject, {$U QuickDraw} QuickDraw; TYPE EShape = (kArc, kRoundRect); TCmdLine = string[80]; TShape = ^PShape; PShape = ^AShape; AShape = RECORD boundRect: Rect; CASE kind: EShape of kArc: (startAngle, arcAngle: INTEGER); kRoundRect: (ovalWidth, ovalHeight: INTEGER); END; PROCEDURE Run(commandLine: TCmdLine; commandBox: Rect; itsHeap:THeap); IMPLEMENTATION {EXTERNAL routines called by HFree; do not call these directly, instead use HFree} FUNCTION HzFromH(h: Handle): THeap; EXTERNAL; PROCEDURE FreeH(heap: THeap; h: Handle); EXTERNAL; {Allocate a handle of a certain size; EXTERNAL because not defined in any INTERFACE we can USE} FUNCTION HAllocate(heap: THeap; size: INTEGER): Handle; EXTERNAL; {Free a handle that was allocated by HAllocate} PROCEDURE HFree(h: Handle); BEGIN FreeH(HzFromH(h), h); END; PROCEDURE DrawShape(pat: Pattern; SELF: TShape); BEGIN CASE SELF^^.kind of kArc: FillArc(SELF^^.boundRect, SELF^^.startAngle, SELF^^.arcAngle, pat); kRoundRect: FillRoundRect(SELF^^.boundRect, SELF^^.ovalWidth, SELF^^.ovalHeight, pat); END; END; PROCEDURE EraseShape(SELF: TShape); BEGIN CASE SELF^^.kind of kArc: EraseArc(SELF^^.boundRect, SELF^^.startAngle, SELF^^.arcAngle); kRoundRect: EraseRoundRect(SELF^^.boundRect, SELF^^.ovalWidth, SELF^^.ovalHeight); END; END; PROCEDURE RandomRect(SELF: TShape); BEGIN SELF^^.boundRect.left := ABS (Random) MOD 600; SELF^^.boundRect.top := (ABS (Random) MOD 150) + 75; SELF^^.boundRect.right := SELF^^.boundRect.left + 40; SELF^^.boundRect.bottom := SELF^^.boundRect.top + 40; END; FUNCTION NewArc(itsheap: THeap): TShape; VAR SELF: TShape; rands, randa: INTEGER; BEGIN SELF := POINTER(ORD(HAllocate(itsHeap, SIZEOF(AShape)))); RandomRect(SELF); rands := Abs (Random) MOD 270; SELF^^.startAngle := rands; randa := Abs (Random) MOD 270; SELF^^.arcAngle := randa; SELF^^.kind := kArc; NewArc := SELF; END; FUNCTION NewRoundRect(itsheap: THeap): TShape; VAR SELF: TShape; BEGIN SELF := POINTER(ORD(HAllocate(itsHeap, SIZEOF(AShape)))); RandomRect(SELF); SELF^^.ovalWidth := 20; SELF^^.ovalHeight := 15; SELF^^.kind := kRoundRect; NewRoundRect:= SELF; END; PROCEDURE Run {commandLine: TCmdLine; commandBox: Rect; itsHeap: THeap}; VAR ch: char; SELF: TShape; consoleFile: TEXT; {used to allow Read(Ln) or Write(Ln) with the main console} BEGIN SELF := NIL; Reset(consoleFile, '-mainconsole-dummyFileName'); EraseRect(commandBox); MoveTo(commandBox.left, commandBox.bottom); DrawString(commandLine); REPEAT Read(consoleFile, ch); CASE ch OF 'r','R','a','A': BEGIN IF SELF <> NIL THEN BEGIN EraseShape(SELF); HFree(Pointer(ORD(SELF))); END; IF (ch = 'r') or (ch = 'R') THEN SELF := NewRoundRect(itsHeap) ELSE SELF := NewArc(itsHeap); DrawShape(gray, SELF); END; 'm','M': IF SELF <> NIL THEN BEGIN EraseShape(SELF); RandomRect(SELF); DrawShape(gray, SELF); END; END; UNTIL (ch = 'q') or (ch = 'Q'); END; END.