Borland Turbo Pascal v6

This commit is contained in:
davidly 2024-07-02 07:11:05 -07:00
parent 3ccb69b30f
commit c8956768f2
202 changed files with 227881 additions and 0 deletions

View File

@ -0,0 +1,383 @@
{ Turbo Art }
{ Copyright (c) 1985, 1990 by Borland International, Inc. }
program Arty;
{ This program is a demonstration of the Borland Graphics Interface
(BGI) provided with Turbo Pascal 6.0.
To run this program you will need the following files:
TURBO.EXE (or TPC.EXE)
TURBO.TPL - The standard units
GRAPH.TPU - The Graphics unit
*.BGI - The graphics device drivers
Runtime Commands for ARTY
-------------------------
<B> - changes background color
<C> - changes drawcolor
<ESC> - exits program
Any other key pauses, then regenerates the drawing
Note: If a /H command-line parameter is specified, the highest
resolution mode will be used (if possible).
}
uses
Crt, Graph;
const
Memory = 100;
Windows = 4;
type
ResolutionPreference = (Lower, Higher);
ColorList = array [1..Windows] of integer;
var
Xmax,
Ymax,
ViewXmax,
ViewYmax : integer;
Line: array [1..Memory] of record
LX1,LY1: integer;
LX2,LY2: integer;
LColor : ColorList;
end;
X1,X2,Y1,Y2,
CurrentLine,
ColorCount,
IncrementCount,
DeltaX1,DeltaY1,DeltaX2,DeltaY2: integer;
Colors: ColorList;
Ch: char;
BackColor:integer;
GraphDriver, GraphMode : integer;
MaxColors : word;
MaxDelta : integer;
ChangeColors: Boolean;
procedure Frame;
begin
SetViewPort(0, 0, Xmax, Ymax-(TextHeight('M')+4)-1,ClipOn);
SetColor(MaxColors);
Rectangle(0, 0, Xmax-1, (Ymax-(TextHeight('M')+4)-1)-1);
SetViewPort(1, 1, Xmax-2, (Ymax-(TextHeight('M')+4)-1)-2,ClipOn);
end { Frame };
procedure FullPort;
{ Set the view port to the entire screen }
begin
SetViewPort(0, 0, Xmax, Ymax, ClipOn);
end; { FullPort }
procedure MessageFrame(Msg:string);
begin
FullPort;
SetColor(MaxColors);
SetTextStyle(DefaultFont, HorizDir, 1);
SetTextJustify(CenterText, TopText);
SetLineStyle(SolidLn, 0, NormWidth);
SetFillStyle(EmptyFill, 0);
Bar(0, Ymax-(TextHeight('M')+4), Xmax, Ymax);
Rectangle(0, Ymax-(TextHeight('M')+4), Xmax, Ymax);
OutTextXY(Xmax div 2, Ymax-(TextHeight('M')+2), Msg);
{ Go back to the main window }
Frame;
end { MessageFrame };
procedure WaitToGo;
var
Ch : char;
begin
MessageFrame('Press any key to continue... Esc aborts');
repeat until KeyPressed;
Ch := ReadKey;
if Ch = #27 then begin
CloseGraph;
Writeln('All done.');
Halt(1);
end
else
ClearViewPort;
MessageFrame('Press a key to stop action, Esc quits.');
end; { WaitToGo }
procedure TestGraphError(GraphErr: integer);
begin
if GraphErr <> grOk then begin
Writeln('Graphics error: ', GraphErrorMsg(GraphErr));
repeat until keypressed;
ch := readkey;
Halt(1);
end;
end;
procedure Init;
var
Err, I: integer;
StartX, StartY: integer;
Resolution: ResolutionPreference;
s: string;
begin
Resolution := Lower;
if paramcount > 0 then begin
s := paramstr(1);
if s[1] = '/' then
if upcase(s[2]) = 'H' then
Resolution := Higher;
end;
CurrentLine := 1;
ColorCount := 0;
IncrementCount := 0;
Ch := ' ';
GraphDriver := Detect;
DetectGraph(GraphDriver, GraphMode);
TestGraphError(GraphResult);
case GraphDriver of
CGA : begin
MaxDelta := 7;
GraphDriver := CGA;
GraphMode := CGAC1;
end;
MCGA : begin
MaxDelta := 7;
case GraphMode of
MCGAMed, MCGAHi: GraphMode := MCGAC1;
end;
end;
EGA : begin
MaxDelta := 16;
If Resolution = Lower then
GraphMode := EGALo
else
GraphMode := EGAHi;
end;
EGA64 : begin
MaxDelta := 16;
If Resolution = Lower then
GraphMode := EGA64Lo
else
GraphMode := EGA64Hi;
end;
HercMono : MaxDelta := 16;
EGAMono : MaxDelta := 16;
PC3270 : begin
MaxDelta := 7;
GraphDriver := CGA;
GraphMode := CGAC1;
end;
ATT400 : case GraphMode of
ATT400C1,
ATT400C2,
ATT400Med,
ATT400Hi :
begin
MaxDelta := 7;
GraphMode := ATT400C1;
end;
end;
VGA : begin
MaxDelta := 16;
end;
end;
InitGraph(GraphDriver, GraphMode, '');
TestGraphError(GraphResult);
SetTextStyle(DefaultFont, HorizDir, 1);
SetTextJustify(CenterText, TopText);
MaxColors := GetMaxColor;
BackColor := 0;
ChangeColors := TRUE;
Xmax := GetMaxX;
Ymax := GetMaxY;
ViewXmax := Xmax-2;
ViewYmax := (Ymax-(TextHeight('M')+4)-1)-2;
StartX := Xmax div 2;
StartY := Ymax div 2;
for I := 1 to Memory do with Line[I] do begin
LX1 := StartX; LX2 := StartX;
LY1 := StartY; LY2 := StartY;
end;
X1 := StartX;
X2 := StartX;
Y1 := StartY;
Y2 := StartY;
end; {init}
procedure AdjustX(var X,DeltaX: integer);
var
TestX: integer;
begin
TestX := X+DeltaX;
if (TestX<1) or (TestX>ViewXmax) then begin
TestX := X;
DeltaX := -DeltaX;
end;
X := TestX;
end;
procedure AdjustY(var Y,DeltaY: integer);
var
TestY: integer;
begin
TestY := Y+DeltaY;
if (TestY<1) or (TestY>ViewYmax) then begin
TestY := Y;
DeltaY := -DeltaY;
end;
Y := TestY;
end;
procedure SelectNewColors;
begin
if not ChangeColors then exit;
Colors[1] := Random(MaxColors)+1;
Colors[2] := Random(MaxColors)+1;
Colors[3] := Random(MaxColors)+1;
Colors[4] := Random(MaxColors)+1;
ColorCount := 3*(1+Random(5));
end;
procedure SelectNewDeltaValues;
begin
DeltaX1 := Random(MaxDelta)-(MaxDelta Div 2);
DeltaX2 := Random(MaxDelta)-(MaxDelta Div 2);
DeltaY1 := Random(MaxDelta)-(MaxDelta Div 2);
DeltaY2 := Random(MaxDelta)-(MaxDelta Div 2);
IncrementCount := 2*(1+Random(4));
end;
procedure SaveCurrentLine(CurrentColors: ColorList);
begin
with Line[CurrentLine] do
begin
LX1 := X1;
LY1 := Y1;
LX2 := X2;
LY2 := Y2;
LColor := CurrentColors;
end;
end;
procedure Draw(x1,y1,x2,y2,color:word);
begin
SetColor(color);
Graph.Line(x1,y1,x2,y2);
end;
procedure Regenerate;
var
I: integer;
begin
Frame;
for I := 1 to Memory do with Line[I] do begin
Draw(LX1,LY1,LX2,LY2,LColor[1]);
Draw(ViewXmax-LX1,LY1,ViewXmax-LX2,LY2,LColor[2]);
Draw(LX1,ViewYmax-LY1,LX2,ViewYmax-LY2,LColor[3]);
Draw(ViewXmax-LX1,ViewYmax-LY1,ViewXmax-LX2,ViewYmax-LY2,LColor[4]);
end;
WaitToGo;
Frame;
end;
procedure Updateline;
begin
Inc(CurrentLine);
if CurrentLine > Memory then CurrentLine := 1;
Dec(ColorCount);
Dec(IncrementCount);
end;
procedure CheckForUserInput;
begin
if KeyPressed then begin
Ch := ReadKey;
if Upcase(Ch) = 'B' then begin
if BackColor > MaxColors then BackColor := 0 else Inc(BackColor);
SetBkColor(BackColor);
end
else
if Upcase(Ch) = 'C' then begin
if ChangeColors then ChangeColors := FALSE else ChangeColors := TRUE;
ColorCount := 0;
end
else if Ch<>#27 then Regenerate;
end;
end;
procedure DrawCurrentLine;
var c1,c2,c3,c4: integer;
begin
c1 := Colors[1];
c2 := Colors[2];
c3 := Colors[3];
c4 := Colors[4];
if MaxColors = 1 then begin
c2 := c1; c3 := c1; c4 := c1;
end;
Draw(X1,Y1,X2,Y2,c1);
Draw(ViewXmax-X1,Y1,ViewXmax-X2,Y2,c2);
Draw(X1,ViewYmax-Y1,X2,ViewYmax-Y2,c3);
if MaxColors = 3 then c4 := Random(3)+1; { alternate colors }
Draw(ViewXmax-X1,ViewYmax-Y1,ViewXmax-X2,ViewYmax-Y2,c4);
SaveCurrentLine(Colors);
end;
procedure EraseCurrentLine;
begin
with Line[CurrentLine] do begin
Draw(LX1,LY1,LX2,LY2,0);
Draw(ViewXmax-LX1,LY1,ViewXmax-LX2,LY2,0);
Draw(LX1,ViewYmax-LY1,LX2,ViewYmax-LY2,0);
Draw(ViewXmax-LX1,ViewYmax-LY1,ViewXmax-LX2,ViewYmax-LY2,0);
end;
end;
procedure DoArt;
begin
SelectNewColors;
repeat
EraseCurrentLine;
if ColorCount = 0 then SelectNewColors;
if IncrementCount=0 then SelectNewDeltaValues;
AdjustX(X1,DeltaX1); AdjustX(X2,DeltaX2);
AdjustY(Y1,DeltaY1); AdjustY(Y2,DeltaY2);
if Random(5)=3 then begin
x1 := (x1+x2) div 2; { shorten the lines }
y2 := (y1+y2) div 2;
end;
DrawCurrentLine;
Updateline;
CheckForUserInput;
until Ch=#27;
end;
begin
Init;
Frame;
MessageFrame('Press a key to stop action, Esc quits.');
DoArt;
CloseGraph;
RestoreCrtMode;
Writeln('The End.');
end.


Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
{ Copyright (c) 1985, 1990 by Borland International, Inc. }
unit BGIDriv;
{ Sample unit to accompany BGILINK.PAS. This unit links the BGI graphics
driver into a single TPU file. This makes it easy to link the driver files
directly into an .EXE file. See BGILINK.PAS for more information.
}
interface
procedure ATTDriverProc;
procedure CgaDriverProc;
procedure EgaVgaDriverProc;
procedure HercDriverProc;
procedure PC3270DriverProc;
implementation
procedure ATTDriverProc; external;
{$L ATT.OBJ }
procedure CgaDriverProc; external;
{$L CGA.OBJ }
procedure EgaVgaDriverProc; external;
{$L EGAVGA.OBJ }
procedure HercDriverProc; external;
{$L HERC.OBJ }
procedure PC3270DriverProc; external;
{$L PC3270.OBJ }
end.


View File

@ -0,0 +1,31 @@
{ Copyright (c) 1985, 1990 by Borland International, Inc. }
unit BGIFont;
{ Sample unit to accompany BGILINK.PAS. This unit links all the BGI graphics
fonts into a single TPU file. This makes it easy to incorporate the font
files directly into an .EXE file. See BGILINK.PAS for more information.
}
interface
procedure GothicFontProc;
procedure SansSerifFontProc;
procedure SmallFontProc;
procedure TriplexFontProc;
implementation
procedure GothicFontProc; external;
{$L GOTH.OBJ }
procedure SansSerifFontProc; external;
{$L SANS.OBJ }
procedure SmallFontProc; external;
{$L LITT.OBJ }
procedure TriplexFontProc; external;
{$L TRIP.OBJ }
end.


View File

@ -0,0 +1,31 @@
# Build sample program that uses BGIFONT.TPU and BGIDRIV.TPU
bgilink.exe: bgidriv.tpu bgifont.tpu
tpc bgilink /m
# Build unit with all fonts linked in
bgifont.tpu: bgifont.pas goth.obj litt.obj sans.obj trip.obj
tpc bgifont
goth.obj: goth.chr
binobj goth.chr goth GothicFontProc
litt.obj: litt.chr
binobj litt.chr litt SmallFontProc
sans.obj: sans.chr
binobj sans.chr sans SansSerifFontProc
trip.obj: trip.chr
binobj trip.chr trip TriplexFontProc
# Build unit with all drivers linked in
bgidriv.tpu: bgidriv.pas cga.obj egavga.obj herc.obj pc3270.obj att.obj
tpc bgidriv
cga.obj: cga.bgi
binobj cga.bgi cga CGADriverProc
egavga.obj: egavga.bgi
binobj egavga.bgi egavga EGAVGADriverProc
herc.obj: herc.bgi
binobj herc.bgi herc HercDriverProc
pc3270.obj: pc3270.bgi
binobj pc3270.bgi pc3270 PC3270DriverProc
att.obj: att.bgi
binobj att.bgi att ATTDriverProc


View File

@ -0,0 +1,126 @@
{ Copyright (c) 1985, 1990 by Borland International, Inc. }
program BgiLink;
{ This program demonstrates how to link graphics driver and font files
into an EXE file. BGI graphic's drivers and fonts are kept in
separate disk files so they may be dynamically loaded at runtime.
However, sometimes it is preferable to place all auxiliary files
directly into an .EXE. This program, along with its make file
(BGILINK.MAK) and two units (BGIDRIV.PAS and BGIFONT.PAS) links all
the drivers and fonts directly into BGILINK.EXE.
Have these 3 programs in the current drive or directory, or
have them available via a path (both are on Disk II):
MAKE.EXE - Make utility that will build BGILINK.EXE
BINOBJ.EXE - utility program to convert any file into an .OBJ file
Place in the current drive or directory the following files (all
are on Disk III):
BGILINK.PAS - this sample program
BGIDRIV.PAS - Pascal unit that will link in all BGI drivers
BGIFONT.PAS - Pascal unit that will link in all BGI fonts
*.CHR - BGI font files
*.BGI - BGI driver files
BGILINK.MAK - "make" file that builds BGIDRIV.TPU, BGIFONT.TPU, and
finally BGILINK.EXE
DIRECTIONS:
1. Run MAKE on the BGILINK.MAK file by typing the following command
at a DOS prompt:
make -fBGIlink.mak
Using BINOBJ.EXE, this will first build .OBJ files out of the driver
files (*.BGI) and then call Turbo Pascal to compile BGIDRIV.PAS.
Next, the font files (*.CHR) will be converted to .OBJs and
BGIFONT.PAS will be compiled. Finally, BGILINK.PAS will be compiled
(it uses BGIDRIV.TPU and BGIFONT.TPU).
2. Run BGILINK.EXE. It contains all the drivers and all the fonts, so it
will run on any system with a graphics card supported by the Graph
unit (CGA, EGA, EGA 64 K, EGA monochrome, Hercules monochrome,
VGA, MCGA, IBM 3270 PC and AT&T 6400).
EXPLANATION
BGILINK.PAS uses BGIDRIV.TPU and BGIFONT.TPU in its uses statement:
uses BGIDriv, BGIFont;
Then, it "registers" the drivers it intends to use (in this case,
all of them, so it will run on any graphics card). Then it registers
all of the fonts it will use (again all of them, just for demonstration
purposes) and finally it does some very modest graphics.
You can easily modify BGILINK.PAS for your own use by commenting out
the calls to RegisterBGIdriver and RegisterBGIfont for drivers and
fonts that your program doesn't use.
For a detailed explanation of registering and linking drivers and fonts,
refer to the RegisterBGIdriver and RegisterBGIfont descriptions in
GRAPH.DOC (on Disk III).
}
uses Graph, { library of graphics routines }
BGIDriv, { all the BGI drivers }
BGIFont; { all the BGI fonts }
var
GraphDriver, GraphMode, Error : integer;
procedure Abort(Msg : string);
begin
Writeln(Msg, ': ', GraphErrorMsg(GraphResult));
Halt(1);
end;
begin
{ Register all the drivers }
if RegisterBGIdriver(@CGADriverProc) < 0 then
Abort('CGA');
if RegisterBGIdriver(@EGAVGADriverProc) < 0 then
Abort('EGA/VGA');
if RegisterBGIdriver(@HercDriverProc) < 0 then
Abort('Herc');
if RegisterBGIdriver(@ATTDriverProc) < 0 then
Abort('AT&T');
if RegisterBGIdriver(@PC3270DriverProc) < 0 then
Abort('PC 3270');
{ Register all the fonts }
if RegisterBGIfont(@GothicFontProc) < 0 then
Abort('Gothic');
if RegisterBGIfont(@SansSerifFontProc) < 0 then
Abort('SansSerif');
if RegisterBGIfont(@SmallFontProc) < 0 then
Abort('Small');
if RegisterBGIfont(@TriplexFontProc) < 0 then
Abort('Triplex');
GraphDriver := Detect; { autodetect the hardware }
InitGraph(GraphDriver, GraphMode, ''); { activate graphics }
if GraphResult <> grOk then { any errors? }
begin
Writeln('Graphics init error: ', GraphErrorMsg(GraphDriver));
Halt(1);
end;
MoveTo(5, 5);
OutText('Drivers and fonts were ');
MoveTo(5, 20);
SetTextStyle(GothicFont, HorizDir, 4);
OutText('Built ');
SetTextStyle(SmallFont, HorizDir, 4);
OutText('into ');
SetTextStyle(TriplexFont, HorizDir, 4);
OutText('EXE ');
SetTextStyle(SansSerifFont, HorizDir, 4);
OutText('file!');
Rectangle(0, 0, GetX, GetY + TextHeight('file!') + 1);
Readln;
CloseGraph;
end.


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,328 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit Bounds;
{ Turbo Pascal 6.0 object-oriented example.
See BREAKOUT.PAS.
Contains the Paddle object type and the object types that
define the boundaries of the playfield.
This unit is part of the BREAKOUT.PAS example.
}
interface
uses Screen, Bricks, Count, Crt;
type
ObstaclePtr = ^Obstacle;
{ An ObstacleList is a list of instances of objects derived from the
object Obstacle. In order to use all these instances polymorphically,
All their virtual functions have to have corresponding virtual functions
in Obstacle, even if they are never used. }
Obstacle = object(Location)
Width : Integer;
Trap : Boolean;
NextPtr : ObstaclePtr;
constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
destructor Done; virtual;
function Collide(var B : Ball) : Boolean; virtual;
function IsTrap : Boolean; virtual;
function GetValue : Integer; virtual;
end;
ObstacleList = object
Head : Obstacle;
Tail : ObstaclePtr;
constructor Init;
destructor Done; virtual;
procedure Append(NewObstacle : ObstaclePtr);
procedure Show;
procedure Hide;
function CheckCollisions(var B : Ball; var Score : Counter) : Boolean;
end;
Paddle = object(Obstacle)
Color : Integer;
constructor Init(InitX, InitY, InitColor : Integer);
destructor Done; virtual;
procedure Show; virtual;
procedure Hide; virtual;
procedure MoveTo(NewX, NewY : Integer); virtual;
function Collide(var B : Ball) : Boolean; virtual;
end;
{ There are no instances of the object Boundary. It's here to provide
a common basis for the next four objects. }
Boundary = object(Obstacle)
constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
end;
LeftBound = object(Boundary)
constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
function Collide(var B : Ball) : Boolean; virtual;
end;
UpperBound = object(Boundary)
constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
function Collide(var B : Ball) : Boolean; virtual;
end;
RightBound = object(Boundary)
constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
function Collide(var B : Ball) : Boolean; virtual;
end;
LowerBound = object(Boundary)
constructor Init(InitX, InitY, InitWidth : Integer; SetTrap : Boolean);
function Collide(var B : Ball) : Boolean; virtual;
end;
implementation
constructor Obstacle.Init(InitX, InitY, InitWidth : Integer;
SetTrap : Boolean);
begin
Location.Init(InitX, InitY);
Width := InitWidth;
Trap := SetTrap;
NextPtr := nil;
end;
destructor Obstacle.Done;
begin
end;
function Obstacle.Collide(var B : Ball) : Boolean;
begin
Collide := True;
end;
function Obstacle.IsTrap : Boolean;
begin
IsTrap := Trap;
end;
function Obstacle.GetValue : Integer;
begin
GetValue := 0;
end;
constructor ObstacleList.Init;
begin
Head.Init(0, 0, 0, False);
Tail := @Head;
end;
destructor ObstacleList.Done;
var
Temp1, Temp2 : ObstaclePtr;
begin
Temp1 := Head.NextPtr;
while Temp1 <> nil do
begin
Temp2 := Temp1;
Temp1 := Temp1^.NextPtr;
Temp2^.Done;
end;
end;
procedure ObstacleList.Append(NewObstacle : ObstaclePtr);
begin
Tail^.NextPtr := NewObstacle;
Tail := NewObstacle;
end;
procedure ObstacleList.Show;
var
Current : ObstaclePtr;
begin
Current := Head.NextPtr;
while Current <> nil do
begin
Current^.Show;
Current := Current^.NextPtr;
end;
end;
procedure ObstacleList.Hide;
var
Current : ObstaclePtr;
begin
Current := Head.NextPtr;
while Current <> nil do
begin
Current^.Hide;
Current := Current^.NextPtr;
end;
end;
{ This function is a little more complex than I like. It checks
whether a collision occurs, and updates the score if one does. }
function ObstacleList.CheckCollisions(var B : Ball;
var Score : Counter) : Boolean;
var
Current : ObstaclePtr;
begin
CheckCollisions := False;
Current := Head.NextPtr;
while Current <> nil do
begin
if Current^.Collide(B) then
begin
Score.Add(Current^.GetValue);
if Current^.IsTrap then
CheckCollisions := True;
end;
Current := Current^.NextPtr;
end;
end;
constructor Paddle.Init(InitX, InitY, InitColor : Integer);
begin
Obstacle.Init(InitX, InitY, 5, False);
Color := InitColor;
end;
destructor Paddle.Done;
begin
Obstacle.Done;
end;
procedure Paddle.Show;
var
Str : String[10];
begin
FillChar(Str[1], Width, Chr(223));
Str[0] := Chr(Width);
Location.Show;
TextColor(Color);
GoToXY(X, Y);
Write(Str);
end;
procedure Paddle.Hide;
begin
Location.Hide;
GoToXY(X, Y);
Write('' : Width);
end;
{ The motion of Paddle is restricted to the 80-character screen }
procedure Paddle.MoveTo(NewX, NewY : Integer);
begin
Hide;
if NewX < 1 then
X := 1
else if NewX > 81 - Width then
X := 81 - Width
else
X := NewX;
Y := NewY;
Show;
end;
{ If the ball hits the paddle we have to change the ball's direction.
Also, to keep the overall logic simpler, if the paddle is at the
edge of the screen and the ball would miss the paddle and go off the
edge, we call it a hit. If we don't do this here, we get into some
complications with bouncing off the sides of the screen }
function Paddle.Collide(var B : Ball) : Boolean;
var
NewX, NewY : Integer;
begin
NewX := B.NextX;
NewY := B.NextY;
Collide := False;
if (NewY = Y) then
if ((NewX >= X) and (NewX < X + Width)) or
((NewX < 1) and (X = 1)) or
((NewX > 80) and (X + Width = 81)) then
begin
B.ReverseY;
{$IFDEF Test} { If the paddle is following the ball, we have to put
in some random behavior so it doesn't get boring. }
B.ChangeXVel(Integer(Random(2))*2-1);
{$ELSE}
B.ChangeXVel(B.GetX - X - 2);
{$ENDIF}
Collide := True;
end;
end;
constructor Boundary.Init(InitX, InitY, InitWidth : Integer;
SetTrap : Boolean);
begin
Obstacle.Init(InitX, InitY, InitWidth, SetTrap);
end;
constructor LeftBound.Init(InitX, InitY, InitWidth : Integer;
SetTrap : Boolean);
begin
Boundary.Init(InitX, InitY, InitWidth, SetTrap);
end;
function LeftBound.Collide(var B : Ball) : Boolean;
begin
Collide := False;
if (B.NextX <= X) and (B.NextY >= Y) and (B.NextY <= Y + Width) then
begin
B.ReverseX;
Collide := True;
end;
end;
constructor UpperBound.Init(InitX, InitY, InitWidth : Integer;
SetTrap : Boolean);
begin
Boundary.Init(InitX, InitY, InitWidth, SetTrap);
end;
function UpperBound.Collide(var B : Ball) : Boolean;
begin
Collide := False;
if (B.NextY <= Y) and (B.NextX >= X) and (B.NextX <= X + Width) then
begin
B.ReverseY;
Collide := True;
end;
end;
constructor RightBound.Init(InitX, InitY, InitWidth : Integer;
SetTrap : Boolean);
begin
Boundary.Init(InitX, InitY, InitWidth, SetTrap);
end;
function RightBound.Collide(var B : Ball) : Boolean;
begin
Collide := False;
if (B.NextX >= X) and (B.NextY >= Y) and (B.NextY <= Y + Width) then
begin
B.ReverseX;
Collide := True;
end;
end;
constructor LowerBound.Init(InitX, InitY, InitWidth : Integer;
SetTrap : Boolean);
begin
Boundary.Init(InitX, InitY, InitWidth, SetTrap);
end;
function LowerBound.Collide(var B : Ball) : Boolean;
begin
Collide := False;
if (B.NextY >= Y) and (B.NextX >= X) and (B.NextX <= X + Width) then
begin
B.ReverseY;
Collide := True;
end;
end;
end.

View File

@ -0,0 +1,301 @@
{ Turbo Breakout }
{ Copyright (c) 1989,90 by Borland International, Inc. }
program Breakout;
{ Turbo Pascal 6.0 object-oriented example.
This is a version of the classic arcade game, Breakout.
SCREEN.PAS
COUNT.PAS
BRICKS.PAS
BOUNDS.PAS
WALLS.PAS
BREAKOUT.PAS
To build an executable file, compile from the command line with:
tpc /m breakout
or load BREAKOUT.PAS into the integrated development
environment and press F9.
When testing the program, you may want to force the paddle to
follow the ball, so you'll never miss. The program contains
conditional compilation directives to produce this version, and
you can build it from the command line with:
tpc /DTest breakout
or load BREAKOUT.PAS into the integrated development
environment, select Alt-O/C/Alt-C, type 'Test' (without the quotes,
of course) followed by the Enter key, then select Alt-C/B to
rebuild the executable file.
}
uses Screen, Count, Bricks, Bounds, Walls, Crt, Dos;
var
ss : SaveScreen;
w : Wall;
b : Ball;
p : Paddle;
Speed : LimitCounter;
Left : LeftBound;
Top : UpperBound;
Right : RightBound;
Bottom : LowerBound;
Obstacles : ObstacleList;
PaddleMsg,
SpeedMsg,
StartMsg,
QuitMsg,
PauseMsg1,
PauseMsg2,
TypeMsg : TextString;
Score : Counter;
Highest : Counter;
Balls : DownCounter;
X : Integer;
Finished : Boolean;
FirstGame : Boolean;
TypeInc,
ch : Char;
procedure Startup;
begin
{ First set up the screen and the cursor }
ss.Init;
TextBackground(BLACK);
ClrScr;
{ Create the boundaries of the playfield }
Left.Init(0, 0, 27, False);
Top.Init(0, 0, 82, False);
Right.Init(81, 0, 27, False);
Bottom.Init(0, 24, 82, True);
{ Initialize the score displays }
Score.Init(0, 65, 24, 'Score', 15);
Score.Show;
Highest.Init(0, 60, 25, 'High Score', 14);
Highest.Show;
{ Set up the various menu messages }
PauseMsg1.Init(31, 18, 'Paused. Press any', 15);
PauseMsg2.Init(31, 19, ' key to continue.', 15);
SpeedMsg.Init(5, 23, #24 + #25 + ' to change speed', 14);
StartMsg.Init(5, 24, #17 + #196 + #217 + ' to begin game', 14);
PaddleMsg.Init(5, 24, #27 + #26 + ' to move paddle', 14);
QuitMsg.Init(5, 25, 'ESC to quit', 14);
QuitMsg.Show;
{ Set up the information messages }
Balls.Init(5, 40, 24, -1, 'Balls', 15);
Balls.Show;
Speed.Init(1, 40, 25, 1, 10, 'Speed', 14);
Speed.Show;
{ Build the wall }
w.Init(1, 1, 16, 10);
w.Show;
{ Need to initialize these, even though we're going to move them later }
b.Init(10, 22, 1, -1, YELLOW);
p.Init(8, 23, WHITE);
{ Put the various obstacles into a list. We don't really need
to do this, but it makes changing things around much easier }
Obstacles.Init;
Obstacles.Append(@p);
Obstacles.Append(@w);
Obstacles.Append(@Left);
Obstacles.Append(@Top);
Obstacles.Append(@Right);
Obstacles.Append(@Bottom);
TypeMsg.Init(22, 12, 'Increase typematic rate? (y/n) ', WHITE);
TypeMsg.Show;
repeat
TypeInc := UpCase(ReadKey);
until (TypeInc = 'Y') or (TypeInc = 'N');
TypeMsg.Hide;
if TypeInc = 'Y' then
ss.Speedup;
ss.SetCursor($2000);
Randomize;
FirstGame := True;
end;
procedure NewGame;
begin
Balls.Reset;
Score.Reset;
if not FirstGame then
w.Reset;
X := Random(78) + 3;
b.MoveTo(X, 22);
p.MoveTo(X-2, 23);
b.Show;
p.Show;
Balls.Decrement;
FirstGame := False;
end;
{ This procedure handles keystrokes between games.
It returns False if the user presses ESC, otherwise it returns True. }
function MainMenu : Boolean;
var
Done : Boolean;
begin
MainMenu := True;
Done := False;
SpeedMsg.Show;
StartMsg.Show;
while not Done do
begin
ch := ReadKey;
case ch of
Chr(27) :
begin
MainMenu := False;
Done := True;
end;
#13 : Done := True;
#0 :
begin
ch := ReadKey;
if Ord(ch) = 72 then
Speed.Increment
else if Ord(ch) = 80 then
Speed.Decrement;
end;
end;
end;
SpeedMsg.Hide;
StartMsg.Hide;
end;
{ This procedure handles keystrokes while the game is in progress }
procedure ProcessKeyStroke;
{ Pause the game }
procedure Pause;
begin
PauseMsg1.Show;
PauseMsg2.Show;
ch := ReadKey;
if KeyPressed then
ch := ReadKey; { Swallow extended keystrokes }
PauseMsg1.Hide;
PauseMsg2.Hide;
b.Show;
end;
begin
ch := ReadKey;
case ch of
Chr(27) : Finished := True;
Chr(0) :
begin
ch := ReadKey;
{$IFNDEF Test}
case Ord(ch) of
75: p.MoveTo(p.GetX - 1, p.GetY); { Left Arrow }
77: p.MoveTo(p.GetX + 1, p.GetY); { Right Arrow }
else
Pause;
end;
{$ELSE}
Pause;
{$ENDIF}
end
else
Pause;
end;
end;
{ This procedure checks for collisions with any of the obstacles
and updates the screen accordingly. }
procedure Update;
var
Offset : Integer;
begin
if Obstacles.CheckCollisions(b, Score) then
begin
b.MoveY;
p.MoveTo(b.GetX - 2, p.GetY);
sound(150);
Delay(300);
nosound;
Balls.Decrement;
while KeyPressed do
ch := ReadKey;
end;
b.MoveX;
b.MoveY;
{$IFDEF Test}
p.MoveTo(b.NextX -2, p.GetY);
{$ENDIF}
end;
{ This procedure cleans up when we're exiting from the program }
procedure ShutDown;
begin
b.Hide;
Obstacles.Hide;
Balls.Hide;
Score.Hide;
Obstacles.Done;
ss.Restore;
if TypeInc = 'Y' then
ss.Slowdown;
ClrScr;
end;
{ This procedure plays a game. The main loop allows up to ten keystrokes,
then moves the ball and checks for collisions }
procedure Play;
var
KeyLoops : Integer;
begin
NewGame;
{$IFNDEF Test}
PaddleMsg.Show;
{$ENDIF}
Finished := False;
KeyLoops := 0;
repeat
if KeyPressed then
ProcessKeyStroke;
Inc(KeyLoops);
if (KeyLoops = 10) and not Finished then
begin
KeyLoops := 0;
UpDate;
end;
Delay(12 - Speed.GetValue);
until Finished or Balls.Last;
PaddleMsg.Hide;
end;
begin
Startup;
while MainMenu do
begin
Play;
Balls.Reset;
b.Hide;
p.Hide;
if Score.GetValue > Highest.GetValue then
Highest.SetValue(Score.GetValue);
end;
ShutDown;
end.

View File

@ -0,0 +1,150 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit Bricks;
{ Turbo Pascal 6.0 object-oriented example.
See BREAKOUT.PAS.
This unit contains the Ball object and the object types that
end up as bricks on the screen.
}
interface
uses Screen, Count;
type
Block = object(Location)
Color : Integer;
Width : Integer;
BChar : Char;
constructor Init(InitX, InitY, InitColor, InitWidth : Integer;
InitChr : Char);
procedure Show; virtual;
procedure Hide; virtual;
end;
Ball = object(Block)
XVel : Integer;
YVel : Integer;
constructor Init(InitX, InitY, InitXVel, InitYVel, InitColor : Integer);
function NextX : Integer;
function NextY : Integer;
procedure MoveX;
procedure MoveY;
procedure ReverseX;
procedure ReverseY;
procedure ChangeXVel(Delta : Integer);
end;
Brick = object(Block)
Value : Integer;
constructor Init(InitX, InitY, InitColor, InitValue : Integer);
function GetValue : Integer;
end;
implementation
uses Crt;
constructor Block.Init(InitX, InitY, InitColor, InitWidth : Integer;
InitChr : Char);
begin
Location.Init(InitX, InitY);
Color := InitColor;
Width := InitWidth;
BChar := InitChr;
end;
procedure Block.Show;
var
Str : String[10];
begin
FillChar(Str[1], Width, BChar);
Str[0] := Chr(Width);
Location.Show;
TextColor(Color);
GoToXY(X, Y);
Write(Str);
end;
procedure Block.Hide;
begin
Location.Hide;
GoToXY(X, Y);
Write('' : Width);
end;
constructor Brick.Init(InitX, InitY, InitColor, InitValue : Integer);
var
BlockChar : Char;
begin
BlockChar := Chr($B2);
if (LastMode = Mono) and Odd(InitX + InitY) then
BlockChar := Chr($B0);
Block.Init(InitX, InitY, InitColor, 5, BlockChar);
Value := InitValue;
end;
function Brick.GetValue : Integer;
begin
GetValue := Value;
end;
constructor Ball.Init(InitX, InitY, InitXVel, InitYVel, InitColor : Integer);
begin
Block.Init(InitX, InitY, InitColor, 1, Chr(15));
XVel := InitXVel;
YVel := InitYVel;
end;
function Ball.NextX : Integer;
begin
NextX := X + XVel;
end;
function Ball.NextY : Integer;
begin
NextY := Y + YVel;
end;
procedure Ball.MoveX;
begin
Hide;
X := NextX;
Show;
end;
procedure Ball.MoveY;
begin
Hide;
Y := NextY;
Show;
end;
procedure Ball.ReverseX;
begin
XVel := -XVel;
end;
procedure Ball.ReverseY;
begin
YVel := -YVel;
end;
{ This procedure introduces the variations in horizontal velocity for
the ball. Horizontal velocity ranges from -2 to 2. If you hit the
ball with the edge of the paddle, you'll get a large change in
horizontal velocity. }
procedure Ball.ChangeXVel(Delta : Integer);
begin
Inc(XVel, Delta);
if XVel < -2 then
XVel := -2
else if XVel > 2 then
XVel := 2
else if XVel = 0 then
XVel := Integer(Random(2))*2 - 1;
end;
end.

View File

@ -0,0 +1,23 @@
{ Turbo Reference }
{ Copyright (c) 1985,90 by Borland International, Inc. }
program Circular;
{ Simple program that demonstrates circular unit references via
a USES clause in the implementation section.
Note that it is NOT possible for the two units to "USE" each
other in their interface sections. It is possible for AA's
interface to use BB, and BB's implementation to use AA, but
this is tricky and depends on compilation order. We don't
document or recommend it.
}
uses
Crt, Display, Error;
begin
ClrScr;
WriteXY(1, 1, 'Upper left');
WriteXY(100, 100, 'Off the screen');
WriteXY(81 - Length('Back to reality'), 15, 'Back to reality');
end.

View File

@ -0,0 +1,238 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit Count;
{ Turbo Pascal 6.0 object-oriented example.
See BREAKOUT.PAS.
This unit provides several text display object types, most of
which are coupled with various types of counters.
}
interface
uses Screen;
const
StrSize = 40;
type
TextStr = String[StrSize];
TextPtr = ^TextStr;
TextString = object(Location)
Text : TextPtr;
Attr : Byte;
constructor Init(InitX, InitY : Integer;
InitText : TextStr;
InitAttr : Byte);
procedure Show; virtual;
procedure Hide; virtual;
end;
Counter = object(TextString)
Value : Integer;
BaseValue : Integer;
constructor Init(InitValue, InitX, InitY : Integer;
InitName : TextStr;
InitAttr : Byte);
procedure Show; virtual;
procedure Hide; virtual;
procedure ShowVal; virtual;
procedure HideVal; virtual;
procedure SetValue(NewValue : Integer);
procedure Reset;
procedure Increment;
procedure Decrement;
procedure Add(Incr : Integer);
function Equal(TestValue : Integer) : Boolean;
function GetValue : Integer;
end;
DownCounter = object(Counter)
Minimum : Integer;
constructor Init(InitValue, InitX, InitY, InitMin : Integer;
InitName : TextStr;
InitAttr : Byte);
procedure Decrement;
procedure Add(Incr : Integer);
function Last : Boolean;
end;
LimitCounter = object(DownCounter)
Maximum : Integer;
constructor Init(InitValue, InitX, InitY, InitMin, InitMax : Integer;
InitName : TextStr;
InitAttr : Byte);
procedure Increment;
procedure Add(Incr : Integer);
end;
implementation
uses Crt;
constructor TextString.Init(InitX, InitY : Integer;
InitText : TextStr;
InitAttr : Byte);
begin
Location.Init(InitX, InitY);
Attr := InitAttr;
GetMem(Text, Length(InitText) + 1);
Move(InitText, Text^, Length(InitText) + 1);
end;
procedure TextString.Show;
begin
Visible := True;
GoToXY(X, Y);
TextColor(Attr);
Write(Text^);
end;
procedure TextString.Hide;
begin
Visible := False;
GoToXY(X, Y);
TextAttr := Attr;
Write('' : Length(Text^));
end;
constructor Counter.Init(InitValue, InitX, InitY : Integer;
InitName : TextStr;
InitAttr : Byte);
begin
TextString.Init(InitX, InitY, InitName, InitAttr);
BaseValue := InitValue;
Value := InitValue;
end;
procedure Counter.Show;
begin
Visible := True;
GoToXY(X, Y);
TextColor(Attr);
Write(Text^, ': ', Value);
end;
procedure Counter.Hide;
begin
Visible := False;
GoToXY(X, Y);
TextAttr := Attr;
Write('' : Length(Text^) + 7);
end;
procedure Counter.ShowVal;
begin
Visible := True;
GoToXY(X + Length(Text^) + 2, Y);
TextColor(Attr);
Write(Value);
end;
procedure Counter.HideVal;
begin
Visible := False;
GoToXY(X + Length(Text^) + 2, Y);
TextAttr := Attr;
Write('' : 5);
end;
procedure Counter.SetValue(NewValue : Integer);
var
Vis : Boolean;
begin
Vis := Visible;
if Vis then
HideVal;
Value := NewValue;
if Vis then
ShowVal;
end;
procedure Counter.Increment;
begin
SetValue(Value + 1);
end;
procedure Counter.Decrement;
begin
SetValue(Value - 1);
end;
procedure Counter.Add(Incr : Integer);
begin
SetValue(Value + Incr);
end;
procedure Counter.Reset;
begin
SetValue(BaseValue);
end;
function Counter.Equal(TestValue : Integer) : Boolean;
begin
Equal := (Value = TestValue);
end;
function Counter.GetValue : Integer;
begin
GetValue := Value;
end;
constructor DownCounter.Init(InitValue, InitX, InitY, InitMin : Integer;
InitName : TextStr;
InitAttr : Byte);
begin
Counter.Init(InitValue, InitX, InitY, InitName, InitAttr);
Minimum := InitMin;
end;
procedure DownCounter.Decrement;
begin
if Value > Minimum then
Counter.Decrement;
end;
procedure DownCounter.Add(Incr : Integer);
var
Temp : Integer;
begin
Temp := GetValue + Incr;
if Temp >= Minimum then
SetValue(Temp);
end;
function DownCounter.Last : Boolean;
begin
Last := (Value = Minimum);
end;
constructor LimitCounter.Init(InitValue,
InitX,
InitY,
InitMin,
InitMax : Integer;
InitName : TextStr;
InitAttr : Byte);
begin
DownCounter.Init(InitValue, InitX, InitY, InitMin, InitName, InitAttr);
Maximum := InitMax;
end;
procedure LimitCounter.Increment;
begin
if Value < Maximum then
Counter.Increment;
end;
procedure LimitCounter.Add(Incr : Integer);
var
Temp : Integer;
begin
Temp := Value + Incr;
if (Temp <= Maximum) and (Temp >= Minimum) then
SetValue(Temp);
end;
end.

View File

@ -0,0 +1,74 @@
/* Copyright (c) 1985,90 by Borland International, Inc.
This module demonstrates how to write Turbo C and Turbo C++
routines that can be linked into a Turbo Pascal program.
Routines in this module call Turbo Pascal routines in CPASDEMO.PAS.
See the instructions in the file CPASDEMO.PAS on running
this demonstration program */
typedef unsigned int word;
typedef unsigned char byte;
typedef unsigned long longword;
extern void setcolor(byte newcolor); /* procedure defined in
Turbo Pascal program */
extern word factor; /* variable declared in Turbo Pascal program */
word sqr(int i)
{
setcolor(1);
return(i * i);
} /* sqr */
word hibits(word w)
{
setcolor(2);
return(w >> 8);
} /* hibits */
byte suc(byte b)
{
setcolor(3);
return(++b);
} /* suc */
byte upr(byte c)
{
setcolor(4);
return((c >= 'a') && (c <= 'z') ? c - 32 : c);
} /* upr */
char prd(char s)
{
setcolor(5);
return(--s);
} /* prd */
long lobits(long l)
{
setcolor(6);
return((longword)l & 65535);
} /* lobits */
void strupr(char far *s)
{
int counter;
for (counter = 1; counter <= s[0]; counter++) /* Note that the routine */
s[counter] = upr(s[counter]); /* skips Turbo Pascal's */
setcolor(7); /* length byte */
} /* strupr */
byte boolnot(byte b)
{
setcolor(8);
return(b == 0 ? 1 : 0);
} /* boolnot */
word multbyfactor(word w)
{
setcolor(9); /* note that this function accesses the Turbo Pascal */
return(w * factor); /* declared variable factor */
} /* multbyfactor */

View File

@ -0,0 +1,115 @@
{ Copyright (c) 1985,90 by Borland International, Inc. }
program CPASDEMO;
(*
This program demonstrates how to interface Turbo Pascal and Turbo C++
(or Turbo C). Turbo C++'s command-line compiler, TCC.EXE, can be used to
generate an .OBJ file (CPASDEMO.OBJ). The .OBJ file can then linked into
this Turbo Pascal program using the {$L} compiler directive.
NOTES:
1. Data declared in the Turbo C++ module cannot be accessed from
the Turbo Pascal program. Shared data must be declared in
Pascal.
2. If the C++ functions are only used in the implementation section
of a unit, declare them NEAR. If they are declared in the
interface section of a unit, declare them FAR. Always compile
the Turbo C++ modules using the small memory model.
3. Turbo C++ runtime library routines cannot be used because their
modules do not have the correct segment names. However, if you have
the Turbo C++ runtime library source (available from Borland),
you can use individual library modules by recompiling them using
the TURBOC.CFG configuration file provided. If you do recompile
them, make sure that you include prototypes in your C++ module
for all C++ library functions that you use.
4. Some of the code that Turbo C++ generates are calls to internal
routines. These cannot be used without recompiling the relevant
parts of the Turbo C++ runtime library source code.
In order to run this demonstration program you will need all the
files required to build a Turbo C++ (or Turbo C) and the TURBOC.CFG
configuration file provided with the Turbo Pascal 6.0 distribution
diskettes.
To build and run the CPASDEMO progarm, do the following:
1. First create a CPASDEMO.OBJ file compatible with Turbo Pascal 6.0
using Turbo C++ (or Turbo C) by typing the following at the DOS
prompt:
TCC CPASDEMO.C
Make sure you use the TURBOC.CFG configuration file provided
on the Turbo Pascal distribution diskettes (in \TP\DEMOS)
when you create the .OBJ file using TCC.
2. Compile and execute the Turbo Pascal program CPASDEMO.PAS
This simple program calls each of the functions defined in the Turbo C++
module. Each of the Turbo C++ functions changes the current display color
by calling the Turbo Pascal procedure SetColor.
*)
uses Crt;
var
Factor : Word;
{$L CPASDEMO.OBJ} { link in the Turbo C++ .OBJ module }
function Sqr(I : Integer) : Word; external;
{ Change the text color and return the square of I }
function HiBits(W : Word) : Word; external;
{ Change the text color and return the high byte of W }
function Suc(B : Byte) : Byte; external;
{ Change the text color and return B + 1 }
function Upr(C : Char) : Char; external;
{ Change the text color and return the upper case of C }
function Prd(S : ShortInt) : ShortInt; external;
{ Change the text color and return S - 1 }
function LoBits(L : LongInt) : LongInt; external;
{ Change the text color and return the low word of L }
procedure StrUpr(var S : string); external;
{ Change the text color and return the upper case of S - Note that the Turbo }
{ C++ routine must skip the length byte of the string. }
function BoolNot(B : Boolean) : Boolean; external;
{ Change the text color and return NOT B }
function MultByFactor(W : Word) : Word; external;
{ Change the text color and return W * Factor - note Turbo C++'s access of }
{ Turbo Pascal's global variable. }
procedure SetColor(NewColor : Byte); { A procedure that changes the current }
begin { display color by changing the CRT }
TextAttr := NewColor; { variable TextAttr }
end; { SetColor }
var
S : string;
begin
Writeln(Sqr(10)); { Call each of the functions defined }
Writeln(HiBits(30000)); { passing it the appropriate info. }
Writeln(Suc(200));
Writeln(Upr('x'));
Writeln(Prd(-100));
Writeln(LoBits(100000));
S := 'abcdefg';
StrUpr(S);
Writeln(S);
Writeln(BoolNot(False));
Factor := 100;
Writeln(MultbyFactor(10));
SetColor(LightGray);
end.

View File

@ -0,0 +1,146 @@
{ Turbo Crt }
{ Copyright (c) 1985,90 by Borland International, Inc. }
program CrtDemo;
{ Example program that uses the Crt unit. Uses the following routines
from the Crt unit:
ClrScr
DelLine
GoToXY
InsLine
KeyPressed
ReadKey
TextBackground
TextColor
TextMode
WhereX
WhereY
Window
Write
WriteLn;
Also uses LastMode and WindMax variables from Crt unit.
1. Init routine:
- Save original video mode. On an EGA or VGA, use the 8x8 font
(43 lines on an EGA, 50 on VGA).
- Setup LastRow to preserve last line on screen for messages
(preserves last 2 lines in 40-column mode). Setup LastCol.
- Initialize the random number generator.
2. MakeWindow routine:
- Puts up random-sized, random-colored windows on screen.
3. Program body:
- Call Init
- Loop until Contrl-C is typed:
- Echo keystrokes (Turbo Pascal windows automatically wrap
and scroll).
- Support special keys:
<Ins> inserts a line at the cursor
<Del> deletes a line at the cursor
<Up>,
<Dn>,
<Right>,
<Left> position the cursor in the window
<Alt-R> generate random text until a key is pressed
<Alt-W> creates another random window
<ESC> exits the program
}
uses Crt;
var
OrigMode,LastCol,LastRow: Word;
Ch: Char;
Done: Boolean;
procedure Initialize;
{ Initialize the video mode, LastCol, LastRow, and the random number }
{ generator. Paint the help line. }
begin
CheckBreak:=False; { turn off Contrl-C checking }
OrigMode:=LastMode; { Remember original video mode }
TextMode(Lo(LastMode)+Font8x8); { use 43 or 50 lines on EGA/VGA }
LastCol:=Lo(WindMax)+1; { get last column, row }
LastRow:=Hi(WindMax)+1;
GoToXY(1,LastRow); { put message line on screen }
TextBackground(Black);
TextColor(White);
Write(' Ins-InsLine ',
'Del-DelLine ',
#27#24#25#26'-Cursor ',
'Alt-W-Window ',
'Alt-R-Random ',
'Esc-Exit');
Dec(LastRow,80 div LastCol); { don't write on message line }
Randomize; { init random number generator }
end; { Init }
procedure MakeWindow;
{ Make a random window, with random background and foreground colors }
var
X,Y,Width,Height: Word;
begin
Width:=Random(LastCol-2)+2; { random window size }
Height:=Random(LastRow-2)+2;
X:=Random(LastCol-Width)+1; { random position on screen }
Y:=Random(LastRow-Height)+1;
Window(X,Y,X+Width,Y+Height);
if OrigMode = Mono then
begin
TextBackground(White);
TextColor(Black);
ClrScr;
Window(X+1,Y+1,X+Width-1,Y+Height-1);
TextBackground(Black);
TextColor(White);
ClrScr;
end
else
begin
TextBackground(Random(8));
TextColor(Random(7)+9);
end;
ClrScr;
end; { MakeWindow }
procedure RandomText;
{ Generate random text until a key is pressed. Filter out }
{ control characters. }
begin
repeat
Write(Chr(Random(256-32)+32));
until KeyPressed;
end; { RandomText }
begin { program body }
Initialize;
MakeWindow;
Done:=False;
repeat
Ch:=ReadKey;
case Ch of
#0: { Function keys }
begin
Ch:=ReadKey;
case Ch of
#17: MakeWindow; { Alt-W }
#19: RandomText; { Alt-R }
#45: Done:=True; { Alt-X }
#72: GotoXY(WhereX,WhereY-1); { Up }
#75: GotoXY(WhereX-1,WhereY); { Left }
#77: GotoXY(WhereX+1,WhereY); { Right }
#80: GotoXY(WhereX,WhereY+1); { Down }
#82: InsLine; { Ins }
#83: DelLine; { Del }
end;
end;
#3: Done:=True; { Ctrl-C }
#13: WriteLn; { Enter }
#27: Done:=True; { Esc }
else
Write(Ch);
end;
until Done;
TextMode(OrigMode);
end.

View File

@ -0,0 +1,239 @@
{ Turbo Directory }
{ Copyright (c) 1985,90 by Borland International, Inc. }
program DirDemo;
{ Demonstration program that shows how to use:
o Directory routines from DOS unit
o Procedural types (used by QuickSort)
Usage:
dirdemo [options] [directory mask]
Options:
-W Wide display
-N Sort by file name
-S Sort by file size
-T Sort by file date and time
Directory mask:
Path, Filename, wildcards, etc.
}
{$I-,S-}
{$M 8192,8192,655360}
uses Dos;
const
MaxDirSize = 512;
MonthStr: array[1..12] of string[3] = (
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
type
DirPtr = ^DirRec;
DirRec = record
Attr: Byte;
Time: Longint;
Size: Longint;
Name: string[12];
end;
DirList = array[0..MaxDirSize - 1] of DirPtr;
LessFunc = function(X, Y: DirPtr): Boolean;
var
WideDir: Boolean;
Count: Integer;
Less: LessFunc;
Path: PathStr;
Dir: DirList;
function NumStr(N, D: Integer): String;
begin
NumStr[0] := Chr(D);
while D > 0 do
begin
NumStr[D] := Chr(N mod 10 + Ord('0'));
N := N div 10;
Dec(D);
end;
end;
{$F+}
function LessName(X, Y: DirPtr): Boolean;
begin
LessName := X^.Name < Y^.Name;
end;
function LessSize(X, Y: DirPtr): Boolean;
begin
LessSize := X^.Size < Y^.Size;
end;
function LessTime(X, Y: DirPtr): Boolean;
begin
LessTime := X^.Time > Y^.Time;
end;
{$F-}
procedure QuickSort(L, R: Integer);
var
I, J: Integer;
X, Y: DirPtr;
begin
I := L;
J := R;
X := Dir[(L + R) div 2];
repeat
while Less(Dir[I], X) do Inc(I);
while Less(X, Dir[J]) do Dec(J);
if I <= J then
begin
Y := Dir[I];
Dir[I] := Dir[J];
Dir[J] := Y;
Inc(I);
Dec(J);
end;
until I > J;
if L < J then QuickSort(L, J);
if I < R then QuickSort(I, R);
end;
procedure GetCommand;
var
I,J: Integer;
Attr: Word;
S: PathStr;
D: DirStr;
N: NameStr;
E: ExtStr;
F: File;
begin
WideDir := False;
@Less := nil;
Path := '';
for I := 1 to ParamCount do
begin
S := ParamStr(I);
if S[1] = '-' then
for J := 2 to Length(S) do
case UpCase(S[J]) of
'N': Less := LessName;
'S': Less := LessSize;
'T': Less := LessTime;
'W': WideDir := True;
else
WriteLn('Invalid option: ', S[J]);
Halt(1);
end
else
Path := S;
end;
Path := FExpand(Path);
if Path[Length(Path)] <> '\' then
begin
Assign(F, Path);
GetFAttr(F, Attr);
if (DosError = 0) and (Attr and Directory <> 0) then
Path := Path + '\';
end;
FSplit(Path, D, N, E);
if N = '' then N := '*';
if E = '' then E := '.*';
Path := D + N + E;
end;
procedure FindFiles;
var
F: SearchRec;
begin
Count := 0;
FindFirst(Path, ReadOnly + Directory + Archive, F);
while (DosError = 0) and (Count < MaxDirSize) do
begin
GetMem(Dir[Count], Length(F.Name) + 10);
Move(F.Attr, Dir[Count]^, Length(F.Name) + 10);
Inc(Count);
FindNext(F);
end;
end;
procedure SortFiles;
begin
if (Count <> 0) and (@Less <> nil) then
QuickSort(0, Count - 1);
end;
procedure PrintFiles;
var
I, P: Integer;
Total: Longint;
T: DateTime;
N: NameStr;
E: ExtStr;
begin
WriteLn('Directory of ', Path);
if Count = 0 then
begin
WriteLn('No matching files');
Exit;
end;
Total := 0;
for I := 0 to Count-1 do
with Dir[I]^ do
begin
P := Pos('.', Name);
if P > 1 then
begin
N := Copy(Name, 1, P - 1);
E := Copy(Name, P + 1, 3);
end else
begin
N := Name;
E := '';
end;
Write(N, ' ': 9 - Length(N), E, ' ': 4 - Length(E));
if WideDir then
begin
if Attr and Directory <> 0 then
Write(' DIR')
else
Write((Size + 1023) shr 10: 3, 'k');
if I and 3 <> 3 then
Write(' ': 3)
else
WriteLn;
end else
begin
if Attr and Directory <> 0 then
Write('<DIR> ')
else
Write(Size: 8);
UnpackTime(Time, T);
WriteLn(T.Day: 4, '-',
MonthStr[T.Month], '-',
NumStr(T.Year mod 100, 2),
T.Hour: 4, ':',
NumStr(T.Min, 2));
end;
Inc(Total, Size);
end;
if WideDir and (Count and 3 <> 0) then WriteLn;
WriteLn(Count, ' files, ', Total, ' bytes, ',
DiskFree(Ord(Path[1])-64), ' bytes free');
end;
begin
GetCommand;
FindFiles;
SortFiles;
PrintFiles;
end.

View File

@ -0,0 +1,26 @@
{ Copyright (c) 1985,90 by Borland International, Inc. }
unit Display;
{ Sample unit for CIRCULAR.PAS }
interface
procedure WriteXY(x, y : integer; s : string);
implementation
uses
Crt, Error;
procedure WriteXY(x, y : integer; s : string);
begin
if (x in [1..80]) and (y in [1..25]) then
begin
GoToXY(x, y);
Write(s);
end
else
ShowError('Invalid WriteXY coordinates');
end;
end.

View File

@ -0,0 +1,21 @@
{ Copyright (c) 1985,90 by Borland International, Inc. }
unit Error;
{ Sample unit for CIRCULAR.PAS }
interface
procedure ShowError(Msg : string);
implementation
uses
Crt, Display;
procedure ShowError(Msg : string);
begin
WriteXY(1, 25, 'Error: ' + Msg);
end;
end.

View File

@ -0,0 +1,40 @@
{ Turbo Exec }
{ Copyright (c) 1985,90 by Borland International, Inc. }
program ExecDemo;
(*
Demonstration program that shows how to use the Dos
unit's Exec procedure to execute DOS commands (including
running other programs or batch files).
This program keeps prompting you for a DOS command until
you enter a blank line.
When using Exec, make sure you specify a {$M} directive
so the heap leaves some memory available for the child
process.
*)
{$M 8192,0,0} { Leave memory for child process }
uses Dos;
var
Command: string[127];
begin
repeat
Write('Enter DOS command: ');
ReadLn(Command);
if Command <> '' then
begin
SwapVectors;
Exec(GetEnv('COMSPEC'), '/C ' + Command);
SwapVectors;
if DosError <> 0 then
WriteLn('Could not execute COMMAND.COM');
WriteLn;
end;
until Command = '';
end.

View File

@ -0,0 +1,44 @@
{ Copyright (c) 1985,90 by Borland International, Inc. }
{$N+,E+}
program Fib8087;
{
Sample program from the Progammer's Guide that
demonstrates how to avoid 8087 stack overflow in recursive
functions that use the 8087 math co-processor. Local variables
are used to store temporary results on the 8086 stack.
}
var
i : integer;
function Fib(N : integer) : extended;
{ calculate the fibonacci sequence for N }
var
F1, F2 : extended;
begin
if N = 0 then
Fib := 0.0
else
if N = 1 then
Fib := 1.0
else
begin
(* Use this line instead of the 3 lines that follow this
comment to cause an 8087 stack overflow for values of
N >= 8:
Fib := Fib(N - 1) + Fib(N - 2); { will cause overflow for N > 8 }
*)
F1 := Fib(N - 1); { store results in temporaries on 8086 }
F2 := Fib(N - 2); { stack to avoid 8087 stack overflow }
Fib := F1 + F2;
end;
end; { Fib }
begin
for i := 0 to 15 do
Writeln(i, '. ', Fib(i));
end.

View File

@ -0,0 +1,212 @@
{ Turbo List }
{ Copyright (c) 1985,90 by Borland International, Inc. }
program SourceLister;
{
SOURCE LISTER DEMONSTRATION PROGRAM
This is a simple program to list your TURBO PASCAL source programs.
PSEUDO CODE
1. Find Pascal source file to be listed
2. Initialize program variables
3. Open main source file
4. Process the file
a. Read a character into line buffer until linebuffer full or eoln;
b. Search line buffer for include file.
c. If line contains include file command:
Then process include file and extract command from line buffer
Else print out the line buffer.
d. Repeat step 4.a thru 4.c until Eof(main file);
INSTRUCTIONS
1. Compile and run the program:
a. In the Development Environment load LISTER.PAS and
press ALT-R R.
b. From the command line type TPC LISTER.PAS (then type
LISTER to run the program)
2. Specify the file to print.
}
uses
Printer;
const
PageWidth = 80;
PrintLength = 55;
PathLength = 65;
FormFeed = #12;
VerticalTabLength = 3;
type
WorkString = string[126];
FileName = string[PathLength];
var
CurRow : integer;
MainFileName: FileName;
MainFile: text;
search1,
search2,
search3,
search4: string[5];
procedure Initialize;
begin
CurRow := 0;
search1 := '{$'+'I'; { different forms that the include compiler }
search2 := '{$'+'i'; { directive can take. }
search3 := '(*$'+'I';
search4 := '(*$'+'i';
end {initialize};
function Open(var fp:text; name: Filename): boolean;
begin
Assign(fp,Name);
{$I-}
Reset(fp);
{$I+}
Open := IOResult = 0;
end { Open };
procedure OpenMain;
begin
if ParamCount = 0 then
begin
Write('Enter filename: ');
Readln(MainFileName);
end
else
MainFileName := ParamStr(1);
if (MainFileName = '') or not Open(MainFile,MainFileName) then
begin
Writeln('ERROR: file not found (', MainFileName, ')');
Halt(1);
end;
end {Open Main};
procedure VerticalTab;
var i: integer;
begin
for i := 1 to VerticalTabLength do Writeln(LST);
end {vertical tab};
procedure ProcessLine(PrintStr: WorkString);
begin
CurRow := Succ(CurRow);
if Length(PrintStr) > PageWidth then Inc(CurRow);
if CurRow > PrintLength then
begin
Write(LST,FormFeed);
VerticalTab;
CurRow := 1;
end;
Writeln(LST,PrintStr);
end {Process line};
procedure ProcessFile;
{ This procedure displays the contents of the Turbo Pascal program on the }
{ printer. It recursively processes include files if they are nested. }
var
LineBuffer: WorkString;
function IncludeIn(var CurStr: WorkString): boolean;
var
ChkChar: char;
column: integer;
begin
ChkChar := '-';
column := Pos(search1,CurStr);
if column <> 0 then
chkchar := CurStr[column+3]
else
begin
column := Pos(search3,CurStr);
if column <> 0 then
chkchar := CurStr[column+4]
else
begin
column := Pos(search2,CurStr);
if column <> 0 then
chkchar := CurStr[column+3]
else
begin
column := Pos(search4,CurStr);
if column <> 0 then
chkchar := CurStr[column+4]
end;
end;
end;
if ChkChar in ['+','-'] then IncludeIn := False
else IncludeIn := True;
end { IncludeIn };
procedure ProcessIncludeFile(var IncStr: WorkString);
var NameStart, NameEnd: integer;
IncludeFile: text;
IncludeFileName: Filename;
Function Parse(IncStr: WorkString): WorkString;
begin
NameStart := Pos('$I',IncStr)+2;
while IncStr[NameStart] = ' ' do
NameStart := Succ(NameStart);
NameEnd := NameStart;
while (not (IncStr[NameEnd] in [' ','}','*']))
and ((NameEnd - NameStart) <= PathLength) do
Inc(NameEnd);
Dec(NameEnd);
Parse := Copy(IncStr,NameStart,(NameEnd-NameStart+1));
end {Parse};
begin {Process include file}
IncludeFileName := Parse(IncStr);
if not Open(IncludeFile,IncludeFileName) then
begin
LineBuffer := 'ERROR: include file not found (' +
IncludeFileName + ')';
ProcessLine(LineBuffer);
end
else
begin
while not EOF(IncludeFile) do
begin
Readln(IncludeFile,LineBuffer);
{ Turbo Pascal 6.0 allows nested include files so we must
check for them and do a recursive call if necessary }
if IncludeIn(LineBuffer) then
ProcessIncludeFile(LineBuffer)
else
ProcessLine(LineBuffer);
end;
Close(IncludeFile);
end;
end {Process include file};
begin {Process File}
VerticalTab;
Writeln('Printing . . . ');
while not EOF(mainfile) do
begin
Readln(MainFile,LineBuffer);
if IncludeIn(LineBuffer) then
ProcessIncludeFile(LineBuffer)
else
ProcessLine(LineBuffer);
end;
Close(MainFile);
Write(LST,FormFeed); { move the printer to the beginning of the next }
{ page }
end {Process File};
begin
Initialize; { initialize some global variables }
OpenMain; { open the file to print }
ProcessFile; { print the program }
end.


View File

@ -0,0 +1,52 @@
{ Turbo Overlays }
{ Copyright (c) 1985,90 by Borland International, Inc. }
{$F+,O+}
program OvrDemo;
(*
This is a simple example of how to use the new overlay system. For
more complete documentation, refer to the overlay chapter in the
Programmer's Guide. Here's a quick checklist:
1. Turn "far calls" on {$F+} (to be safe, in all overlaid units and
the main program).
2. Turn "Overlays allowed" on {$O+}
3. Use Overlay unit in main program.
4. Issue separate {$O} directives for each overlaid unit.
5. Make sure to call OvrInit and pass the name of the .OVR file.
6. Test OvrResult after OvrInit calls (optional).
7. Compile to disk (cannot run in memory).
Here are the overlay error returns for quick reference:
const
ovrOk = 0; { Success }
ovrError = -1; { Overlay manager error }
ovrNotFound = -2; { Overlay file not found }
ovrNoMemory = -3; { Not enough memory for overlay buffer }
ovrIOError = -4; { Overlay file I/O error }
ovrNoEMSDriver = -5; { EMS driver not installed }
ovrNoEMSMemory = -6; { Not enough EMS memory }
*)
uses
Overlay, Crt, OvrDemo1, OvrDemo2;
{$O OvrDemo1} { overlay 'em }
{$O OvrDemo2}
begin
TextAttr := White;
ClrScr;
OvrInit('OVRDEMO.OVR'); { init overlay system, reserve heap space }
if OvrResult <> 0 then
begin
Writeln('Overlay error: ', OvrResult);
Halt(1);
end;
repeat
Write1;
Write2;
until KeyPressed;
end.

View File

@ -0,0 +1,19 @@
{ Copyright (c) 1985,90 by Borland International, Inc. }
{$O+,F+}
unit OvrDemo1;
{ This unit is used by OVRDEMO.PAS }
interface
procedure Write1;
implementation
procedure Write1;
begin
Writeln('One...');
end;
end.

View File

@ -0,0 +1,19 @@
{ Copyright (c) 1985,90 by Borland International, Inc. }
{$O+,F+}
unit OvrDemo2;
{ This unit is used by OVRDEMO.PAS }
interface
procedure Write2;
implementation
procedure Write2;
begin
Writeln('Two...');
end;
end.

View File

@ -0,0 +1,41 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
{$F+}
program ProcVar;
{ For an extensive discussion of procedural types, variables and
parameters, refer to Chapter 8 in the Programmer's Guide.
}
type
IntFuncType = function (x, y : integer) : integer; { No func. identifier }
var
IntFuncVar : IntFuncType;
procedure DoSomething(Func : IntFuncType; x, y : integer);
begin
Writeln(Func(x, y):5); { call the function parameter }
end;
function AddEm(x, y : integer) : integer;
begin
AddEm := x + y;
end;
function SubEm(x, y : integer) : integer;
begin
SubEm := x - y;
end;
begin
{ Directly: }
DoSomething(AddEm, 1, 2);
DoSomething(SubEm, 1, 2);
{ Indirectly: }
IntFuncVar := AddEm; { an assignment, not a call }
DoSomething(IntFuncVar, 3, 4); { a call }
IntFuncVar := SubEm; { an assignment, not a call }
DoSomething(IntFuncVar, 3, 4); { a call }
end.

View File

@ -0,0 +1,66 @@
{ Turbo Sort }
{ Copyright (c) 1985,90 by Borland International, Inc. }
program qsort;
{$R-,S-}
uses Crt;
{ This program demonstrates the quicksort algorithm, which }
{ provides an extremely efficient method of sorting arrays in }
{ memory. The program generates a list of 1000 random numbers }
{ between 0 and 29999, and then sorts them using the QUICKSORT }
{ procedure. Finally, the sorted list is output on the screen. }
{ Note that stack and range checks are turned off (through the }
{ compiler directive above) to optimize execution speed. }
const
max = 1000;
type
list = array[1..max] of integer;
var
data: list;
i: integer;
{ QUICKSORT sorts elements in the array A with indices between }
{ LO and HI (both inclusive). Note that the QUICKSORT proce- }
{ dure provides only an "interface" to the program. The actual }
{ processing takes place in the SORT procedure, which executes }
{ itself recursively. }
procedure quicksort(var a: list; Lo,Hi: integer);
procedure sort(l,r: integer);
var
i,j,x,y: integer;
begin
i:=l; j:=r; x:=a[(l+r) DIV 2];
repeat
while a[i]<x do i:=i+1;
while x<a[j] do j:=j-1;
if i<=j then
begin
y:=a[i]; a[i]:=a[j]; a[j]:=y;
i:=i+1; j:=j-1;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
begin {quicksort};
sort(Lo,Hi);
end;
begin {qsort}
Write('Now generating 1000 random numbers...');
Randomize;
for i:=1 to max do data[i]:=Random(30000);
Writeln;
Write('Now sorting random numbers...');
quicksort(data,1,max);
Writeln;
for i:=1 to 1000 do Write(data[i]:8);
end.

View File

@ -0,0 +1,199 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit Screen;
{ Turbo Pascal 6.0 object-oriented example.
See BREAKOUT.PAS.
This unit provides several objects for dealing with the screen.
}
interface
uses Crt, Dos;
type
Location = object
X, Y : Integer;
Visible : Boolean;
constructor Init(InitX, InitY : Integer);
procedure Relocate(NewX, NewY : Integer);
procedure MoveTo(NewX, NewY : Integer); virtual;
procedure Show; virtual;
procedure Hide; virtual;
function GetX : Integer;
function GetY : Integer;
function IsVisible : Boolean;
end;
Cursor = object(Location)
OldCursor : Integer;
TempCursor : Integer;
constructor Init;
procedure Show; virtual;
procedure Hide; virtual;
procedure SetCursor(NewCursor : Integer);
function GetCursor : Integer;
procedure MoveTo(NewX, NewY : Integer); virtual;
procedure Save;
procedure Restore;
procedure Speedup;
procedure Slowdown;
end;
SaveScreen = object(Cursor)
OldAttr : Byte;
constructor Init;
procedure Save;
procedure Restore;
end;
implementation
procedure SetCursorSpeed(NewSpeed : Word);
begin
Port[$60] := $F3;
Delay(200);
Port[$60] := NewSpeed;
end;
constructor Location.Init(InitX, InitY : Integer);
begin
X := InitX;
Y := InitY;
Visible := False;
end;
procedure Location.Relocate(NewX, NewY : Integer);
begin
X := NewX;
Y := NewY;
end;
procedure Location.MoveTo(NewX, NewY : Integer);
var
Vis : Boolean;
begin
Vis := Visible;
if Vis then Hide;
X := NewX;
Y := NewY;
if Vis then Show;
end;
procedure Location.Show;
begin
Visible := True;
end;
procedure Location.Hide;
begin
Visible := False;
end;
function Location.GetX : Integer;
begin
GetX := X;
end;
function Location.GetY : Integer;
begin
GetY := Y;
end;
function Location.IsVisible;
begin
IsVisible := Visible;
end;
constructor Cursor.Init;
begin
Location.Init(WhereX, WhereY);
OldCursor := GetCursor;
Location.Show;
end;
procedure Cursor.Show;
begin
SetCursor(TempCursor);
end;
procedure Cursor.Hide;
begin
TempCursor := GetCursor;
SetCursor($2000);
end;
function Cursor.GetCursor : Integer;
var
Reg : Registers;
begin
with Reg do
begin
AH := 3;
BH := 0;
Intr($10, Reg);
GetCursor := CX;
end;
end;
procedure Cursor.SetCursor(NewCursor : Integer);
var
Reg : Registers;
begin
with Reg do
begin
AH := 1;
BH := 0;
CX := NewCursor;
Intr($10, Reg);
end;
end;
procedure Cursor.MoveTo(NewX, NewY : Integer);
begin
Location.Relocate(NewX, NewY);
GoToXY(NewX, NewY);
end;
procedure Cursor.Save;
begin
Location.Relocate(WhereX, WhereY);
OldCursor := GetCursor;
end;
procedure Cursor.Restore;
begin
SetCursor(OldCursor);
GoToXY(X, Y);
end;
procedure Cursor.Speedup;
begin
SetCursorSpeed(0);
end;
procedure Cursor.Slowdown;
begin
SetCursorSpeed($2C);
end;
constructor SaveScreen.Init;
begin
Cursor.Init;
OldAttr := TextAttr;
end;
procedure SaveScreen.Save;
begin
Cursor.Save;
OldAttr := TextAttr;
end;
procedure SaveScreen.Restore;
begin
Cursor.Restore;
TextAttr := OldAttr;
ClrScr;
end;
end.

View File

@ -0,0 +1,156 @@
Turbo Pascal 6.0
Turbo Calc Information
Build Information
-----------------
The following files are provided in TCALC.ZIP and are required
in order to build TCALC.EXE:
TCALC PAS
TCCELL PAS
TCCELLSP PAS
TCHASH PAS
TCINPUT PAS
TCLSTR PAS
TCMENU PAS
TCPARSER PAS
TCRUN PAS
TCSCREEN PAS
TCSHEET PAS
TCUTIL PAS
TCCOMPAR OBJ
TCMVSMEM OBJ
In addition, TCALC uses the OBJECTS module, so make sure OBJECTS.TPU
is available (located in the \TP\TVISION directory) in your unit
path.
Types of Cells
--------------
Value: A number.
Text: A string - start it with a space to make sure that it
doesn't get parsed.
Formula: A string that is an expression (see explanation of
expressions below). This cell will be constantly updated (if
AutoCalc is on) to the current value of the expression.
Repeat: A cell with a character that will repeat indefinitely
across the spreadsheet. Type in the character that you want
to repeat with a leading backslash (example: type \_ to get
an underline across the screen).
General Information
-------------------
Columns range from A to CRXO (65535), and rows range from 1 to
65535.
The little dot in the upper left of a spreadsheet tells you
which of the spreadsheets is the current one. The number of the
spreadsheet is also printed, along with 'F' if formula display
is on and 'A' if AutoCalc is on.
The file that the spreadsheet will be saved to is listed at the
bottom of each spreadsheet, along with an asterisk if the
spreadsheet has been updated.
Expressions
-----------
Cell names in formulas are typed in with the column followed by
the row:
A1+A2
B6^5
To compute the sum of a group of cells, put a colon between the
first cell and the last cell in the group:
A1:A10 - Sum all of cells from A1 to A10 and puts the
result in the current cell.
A1:C10 - Sum of all of cells from A1 to A10, B1 to B10,
and C1 to C10 and puts the result in the current
cell.
Available Functions
-------------------
ABS - absolute value
ACOS - arc cosine
ASIN - arc sine
ATAN - arc tangent
COS - cosine
COSH - hyperbolic cosine
EXP - exponential function
LOG - logarithm
LOG10 - base 10 logarithm
POW10 - raise argument to the 10th power
ROUND - round to the nearest whole number
SIN - sine
SINH - hyperbolic sine
SQR - square
SQRT - square root
TAN - tangent
TANH - hyperbolic tangent
TRUNC - return the whole part of a number
Examples:
TRUNC(A1)
SQRT(SQR(34.5))
ABS(TRUNC(B16))
Shortcut Commands
-----------------
AltX - Quit
Ins - Turn block on and off
Del - Delete current cell
F2 - Save current spreadsheet
AltF2 - Save as
F3 - Replace current spreadsheet
AltF3 - Load new spreadsheet (opens up additional window)
F4 - Delete current spreadsheet
F6 - Next spreadsheet
F7 - Toggle formula display on/off
F8 - Toggle AutoCalc on/off
F9 - Recalc
F10 - Main menu
ASCII keys - Add cell
The Parser
----------
The state and goto information for the parser was created using
the UNIX YACC utility. The input to YACC was as follows:
%token CONST CELL FUNC
%%
e : e '+' t
| e '-' t
| t
;
t : t '*' f
| t '/' f
| f
;
f : x '^' f
| x
;
x : '-' u
| u
;
u : CELL ':' CELL
| o
;
o : CELL
| '(' e ')'
| CONST
| FUNC '(' e ')'
;
%%


View File

@ -0,0 +1,20 @@
{ Turbo Calc }
{ Copyright (c) 1989,90 by Borland International, Inc. }
program TCalc;
{ Turbo Pascal 6.0 object-oriented example main module.
Object-oriented spreadsheet program.
See TCALC.DOC for more information about this example.
Specify TCALC.PAS as your primary file when compiling and editing
TCALC inside the Integrated Development Environment.
}
{$S-}
uses TCRun;
begin
Run;
end.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCCellSp;
{ Turbo Pascal 6.0 object-oriented example cell support routines.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$N+,S-}
interface
uses TCUtil, TCLStr, TCScreen, TCInput, TCCell;
function GetColumn(Prompt : String; MaxCols, ColSpace : Word) : Word;
function GetRow(Prompt : String; MaxRows : Word) : Word;
function GetCellPos(Prompt : String; MaxCols, MaxRows, ColSpace,
RowNumberSpace : Word; var P : CellPos) : Boolean;
function FormulaStart(Inp : LStringPtr; Start, MaxCols, MaxRows : Word;
var P : CellPos; var FormLen : Word) : Boolean;
procedure FixFormulaCol(CP : CellPtr; Diff : Longint;
MaxCols, MaxRows : Word);
procedure FixFormulaRow(CP : CellPtr; Diff : Longint;
MaxCols, MaxRows : Word);
implementation
function GetColumn(Prompt : String; MaxCols, ColSpace : Word) : Word;
{ Lets the user enter a column from the keyboard }
var
I : InputField;
S : String;
C : Word;
begin
with I do
begin
if not Init(Length(Prompt) + 3, 0, -1, ColSpace, AllUpper) then
begin
GetColumn := 0;
Exit;
end;
WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
repeat
Edit(0);
S := InputData^.ToString;
if (not GetQuit) and (S <> '') then
begin
C := StringToCol(S, MaxCols);
if C = 0 then
Scr.PrintError(ErrColumnError1 + ColToString(1) +
ErrColumnError2 + ColToString(MaxCols));
end
else
C := 0;
until (C <> 0) or (S = '');
InputArea.Clear;
Done;
end; { with }
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
GetColumn := C;
end; { GetColumn }
function GetRow(Prompt : String; MaxRows : Word) : Word;
{ Lets the user enter a row from the keyboard }
var
R : Word;
Good : Boolean;
begin
R := GetNumber(Prompt, 1, MaxRows, Good);
if Good then
GetRow := R
else
GetRow := 0;
end; { GetRow }
function GetCellPos(Prompt : String; MaxCols, MaxRows, ColSpace,
RowNumberSpace : Word; var P : CellPos) : Boolean;
{ Lets the user enter a cell position from the keyboard }
var
I : InputField;
S : String;
FormLen : Word;
begin
GetCellPos := False;
with I do
begin
if not Init(Length(Prompt) + 3, 0, -1, Pred(ColSpace + RowNumberSpace),
AllUpper) then
Exit;
WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
repeat
Edit(0);
S := InputData^.ToString;
if (not GetQuit) and (S <> '') then
begin
if FormulaStart(InputData, 1, MaxCols, MaxRows, P, FormLen) then
GetCellPos := True
else
Scr.PrintError(ErrCellError);
end
else
FormLen := 0;
until (FormLen <> 0) or (S = '');
InputArea.Clear;
Done;
end; { with }
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
end; { GetCellPos }
function FormulaStart(Inp : LStringPtr; Start, MaxCols, MaxRows : Word;
var P : CellPos; var FormLen : Word) : Boolean;
{ Checks to see if a place in a long string is the beginning of a formula }
var
Col, Row : Word;
CS : String[10];
RS : String[10];
begin
with Inp^ do
begin
FormulaStart := False;
FormLen := 0;
FillChar(P, SizeOf(P), 0);
CS := '';
while (Start <= Length) and (Data^[Start] in Letters) do
begin
CS := CS + Data^[Start];
Inc(Start);
end;
Col := StringToCol(CS, MaxCols);
if Col = 0 then
Exit;
RS := '';
while (Start <= Length) and (Data^[Start] in Numbers) do
begin
RS := RS + Data^[Start];
Inc(Start);
end;
Row := StringToRow(RS, MaxRows);
if Row = 0 then
Exit;
P.Col := Col;
P.Row := Row;
FormLen := System.Length(CS) + System.Length(RS);
FormulaStart := True;
end; { with }
end; { FormulaStart }
procedure FixFormulaCol(CP : CellPtr; Diff : Longint;
MaxCols, MaxRows : Word);
{ Adjusts a formula for a new column }
var
FormLen, Place, OldLen, NewLen : Word;
P : CellPos;
S : String[10];
Good : Boolean;
begin
with FormulaCellPtr(CP)^, GetFormula^ do
begin
Place := 1;
Good := True;
while Good and (Place <= Length) do
begin
if FormulaStart(GetFormula, Place, MaxCols, MaxRows, P, FormLen) then
begin
OldLen := System.Length(ColToString(P.Col));
S := ColToString(Longint(P.Col) + Diff);
NewLen := System.Length(S);
if NewLen > OldLen then
Good := Insert(FillString(NewLen - OldLen, ' '), Place)
else if NewLen < OldLen then
Delete(Place, OldLen - NewLen);
if Good then
begin
Move(S[1], Data^[Place], System.Length(S));
Inc(Place, FormLen + NewLen - OldLen);
end;
end
else
Inc(Place);
end;
end; { with }
end; { FixFormulaCol }
procedure FixFormulaRow(CP : CellPtr; Diff : Longint;
MaxCols, MaxRows : Word);
{ Adjusts a formula for a new row }
var
ColLen, FormLen, Place, OldLen, NewLen : Word;
P : CellPos;
S : String[10];
Good : Boolean;
begin
with FormulaCellPtr(CP)^, GetFormula^ do
begin
Place := 1;
Good := True;
while Good and (Place <= Length) do
begin
if FormulaStart(GetFormula, Place, MaxCols, MaxRows, P, FormLen) then
begin
OldLen := System.Length(RowToString(P.Row));
S := RowToString(P.Row + Diff);
NewLen := System.Length(S);
ColLen := System.Length(ColToString(P.Col));
if NewLen > OldLen then
Good := Insert(FillString(NewLen - OldLen, ' '), Place + ColLen)
else if NewLen < OldLen then
Delete(Place + ColLen, OldLen - NewLen);
if Good then
begin
Move(S[1], Data^[Place + ColLen], System.Length(S));
Inc(Place, FormLen + NewLen - OldLen);
end;
end
else
Inc(Place);
end;
end; { with }
end; { FixFormulaRow }
end.

View File

@ -0,0 +1,40 @@
; Turbo Pascal 6.0 object-oriented example
; Assembler code for TCALC example
; Copyright (c) 1989,90 by Borland International, Inc.
MODEL TPASCAL
LOCALS
CODESEG
PUBLIC Compare
; function Compare(var Source, Dest; Len : Word) : Boolean;
;
; Compares two areas of memory to see if they are identical.
;
; Variables:
;
; Source : Far pointer to the location of the first area of memory.
; Dest : Far pointer to the location of the second area of memory.
; Len : The amount of memory to be compared in bytes.
Proc Compare Source : DWord, Dest : DWord, Len : Word
push ds ; Save DS
mov cx,[Len] ; Move Len to CX
jcxz @@0 ; Quit if Len = 0, returning True
lds si,[Source] ; Load source pointer into DS:SI
les di,[Dest] ; Load destination pointer into ES:DI
cld ; Set direction to forward
repz cmpsb ; Compare the two areas
jz @@0 ; Return True if the compare was completed
mov cl,1 ;
@@0:
mov al,cl ; If CL = 0, return True, otherwise return False
xor al,1
pop ds ; Restore DS
ret
EndP
End

Binary file not shown.

View File

@ -0,0 +1,261 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCHash;
{ Turbo Pascal 6.0 object-oriented example hash tables.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$S-}
interface
uses TCUtil;
{ This unit allows you to implement hash tables. Each hash table is composed
of a number of "buckets", each of which points to a linked list of data
entries. The bucket that a particular data entry goes into is determined
by the HashValue function. }
const
MaxBuckets = 1000;
MaxHashItemSize = 256;
type
BucketRange = 1..MaxBuckets;
HashItemSizeRange = 1..MaxHashItemSize;
HashItemData = array[0..Pred(MaxHashItemSize)] of Byte;
HashItemDataPtr = ^HashItemData;
HashItemPtr = ^HashItem;
HashItem = record
Next : HashItemPtr;
Data : HashItemData;
end;
HashItemArray = array[BucketRange] of HashItemPtr;
HashTable = object
Buckets : BucketRange;
Items : Longint;
CurrItem : HashItemPtr;
CurrBucket : BucketRange;
HashData : ^HashItemArray;
constructor Init(InitBuckets : BucketRange);
destructor Done;
function Add : Boolean;
procedure Delete(Deleted : Pointer);
function FirstItem : HashItemPtr;
function NextItem : HashItemPtr;
function Change : Boolean;
function Search : HashItemPtr;
function HashValue : Word; virtual;
function Found(Item : HashItemPtr) : Boolean; virtual;
procedure CreateItem(var Item : HashItemPtr); virtual;
function ItemSize : HashItemSizeRange; virtual;
function CurrItemSize(Item : HashItemPtr) : HashItemSizeRange; virtual;
end;
implementation
constructor HashTable.Init(InitBuckets : BucketRange);
{ Initialize a new hash table with a certain number of buckets }
begin
GetMem(HashData, InitBuckets * SizeOf(HashItemPtr));
if HashData = nil then
Fail;
Buckets := InitBuckets;
FillChar(HashData^, Buckets * SizeOf(HashItemPtr), 0);
Items := 0;
end; { HashTable.Init }
destructor HashTable.Done;
{ Removes a hash table from memory }
var
P, D : HashItemPtr;
Counter : Word;
begin
for Counter := 1 to Buckets do
begin
P := HashData^[Counter];
while P <> nil do
begin
D := P;
P := P^.Next;
FreeMem(D, CurrItemSize(D) + SizeOf(HashItemPtr));
end;
end;
FreeMem(HashData, Buckets * SizeOf(HashItemPtr));
end; { HashTable.Done }
function HashTable.Add : Boolean;
{ Adds a new item to a hash table }
var
H, A : HashItemPtr;
V : BucketRange;
begin
Add := False;
V := Succ(HashValue mod Buckets);
H := HashData^[V];
A := H;
while H <> nil do
begin
H := H^.Next;
if H <> nil then
A := H;
end;
if A = nil then { Item will be the first element in the list }
begin
GetMem(HashData^[V], ItemSize + SizeOf(HashItemPtr));
A := HashData^[V];
if A = nil then
Exit;
end
else begin { Add item and end of list }
GetMem(A^.Next, ItemSize + SizeOf(HashItemPtr));
if A^.Next = nil then
Exit;
A := A^.Next;
end;
CreateItem(A);
A^.Next := nil;
Inc(Items);
Add := True;
end; { HashTable.Add }
procedure HashTable.Delete(Deleted : Pointer);
{ Deletes an item from a hash table, and returns the deleted item }
var
H, D : HashItemPtr;
V : BucketRange;
begin
V := Succ(HashValue mod Buckets);
H := HashData^[V];
D := H;
while (H <> nil) and (not Found(H)) do
begin
H := H^.Next;
if not Found(H) then
D := H;
end;
if H = nil then { The item was not found }
begin
if Deleted <> nil then
FillChar(Deleted^, ItemSize, 0);
Exit;
end
else begin
if H = HashData^[V] then
HashData^[V] := HashData^[V]^.Next
else
D^.Next := H^.Next;
if Deleted <> nil then { Fill Deleted with the item's data }
Move(H^.Data, Deleted^, ItemSize);
FreeMem(H, CurrItemSize(H) + SizeOf(HashItemPtr));
end;
Dec(Items);
end; { HashTable.Delete }
function HashTable.FirstItem : HashItemPtr;
{ Returns the first item in a hash table. to find all of the items in a
hash table, call FirstItem to get the first one and then call NextItem to
get the rest }
var
Counter : Word;
begin
for Counter := 1 to Buckets do
begin
CurrBucket := Counter;
CurrItem := HashData^[Counter];
if CurrItem <> nil then
begin
FirstItem := CurrItem;
Exit;
end;
end;
FirstItem := nil;
end; { HashTable.FirstItem }
function HashTable.NextItem : HashItemPtr;
{ Returns the next item in a hash table - called after FirstItem }
begin
CurrItem := CurrItem^.Next;
if CurrItem <> nil then
begin
NextItem := CurrItem;
Exit;
end;
while CurrBucket < Buckets do
begin
Inc(CurrBucket);
CurrItem := HashData^[CurrBucket];
if CurrItem <> nil then
begin
NextItem := CurrItem;
Exit;
end;
end;
NextItem := nil;
end; { HashTable.NextItem }
function HashTable.Change : Boolean;
{ Changes the data of a hash item }
var
H : HashItemPtr;
begin
H := HashData^[Succ(HashValue mod Buckets)];
while (H <> nil) and (not Found(H)) do
H := H^.Next;
if H <> nil then
begin
CreateItem(H);
Change := True;
end
else
Change := Add;
end; { HashTable.Change }
function HashTable.Search : HashItemPtr;
{ Searches for a particular hash item }
var
H : HashItemPtr;
begin
H := HashData^[Succ(HashValue mod Buckets)];
while (H <> nil) and (not Found(H)) do
H := H^.Next;
Search := H;
end; { HashTable.Search }
function HashTable.HashValue : Word;
{ Returns a hash value - must be written by the user }
begin
Abstract('HashTable.HashValue');
end; { HashTable.HashValue }
function HashTable.Found(Item : HashItemPtr) : Boolean;
{ Returns a boolean value indicating whether the current hash item is the
one being searched for - must be written by the user }
begin
Abstract('HashTable.Found');
end; { HashTable.Found }
procedure HashTable.CreateItem(var Item : HashItemPtr);
{ Creates a hash item - must be written by the user }
begin
Abstract('HashTable.CreateItem');
end; { HashTable.CreateItem }
function HashTable.ItemSize : HashItemSizeRange;
{ Returns the size of a hash item. If the hash item size is variable, this
is based on whatever the item being searched for, added, or deleted is -
must be written by the user }
begin
Abstract('HashTable.ItemSize');
end; { HashTable.ItemSize }
function HashTable.CurrItemSize(Item : HashItemPtr) : HashItemSizeRange;
{ Returns the size of a particular item. This needs to be written only if
the size of hash items is variable (strings, etc.) }
begin
CurrItemSize := ItemSize;
end; { HashTable.CurrItemSize }
end.

View File

@ -0,0 +1,333 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCInput;
{ Turbo Pascal 6.0 object-oriented example input routines.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$S-}
interface
uses Crt, TCUtil, TCScreen, TCLStr;
const
LeftInputArrow = #17;
RightInputArrow = #16;
YesNo = 'Y/N';
LegalYesNo = ['Y', 'N'];
AllUpper = True;
NotUpper = False;
ErrNumberError1 = 'You must enter a number from ';
ErrNumberError2 = ' to ';
ErrColumnError1 = 'You must enter a column from ';
ErrColumnError2 = ' to ';
ErrCellError = 'You must enter a legal cell';
type
InputField = object
StartCol : ScreenColRange;
StopCol : Integer;
InputRow : Integer;
MaxInputLen : Word;
Quit : Boolean;
InputData : LStringPtr;
UCase : Boolean;
InputArea : ScreenArea;
constructor Init(C1 : ScreenColRange; C2 : Integer; R : Integer;
InitMaxInputLen : Word; InitUCase : Boolean);
destructor Done;
function GetQuit : Boolean;
procedure Edit(StartCursor : Word);
procedure ClearInput;
end;
function ReadString(Prompt : String; Len : Word;
var ESCPressed : Boolean) : String;
function GetLegalChar(Prompt : String; Legal : CharSet;
var ESCPressed : Boolean) : Char;
function GetYesNo(Prompt : String; var ESCPressed : Boolean) : Boolean;
function GetNumber(Prompt : String; Low, High : Longint;
var Result : Boolean) : Longint;
implementation
constructor InputField.Init(C1 : ScreenColRange; C2 : Integer; R : Integer;
InitMaxInputLen : Word; InitUCase : Boolean);
{ Sets up an input field }
begin
InputData := New(LStringPtr, Init);
if InputData = nil then
Fail;
StartCol := C1;
StopCol := C2;
InputRow := R;
if InitMaxInputLen = 0 then
MaxInputLen := 65521 { Maximum area that a pointer can allocate }
else
MaxInputLen := InitMaxInputLen;
UCase := InitUCase;
Quit := False;
end; { InputField.Init }
destructor InputField.Done;
{ Remove memory used by an input field }
begin
Dispose(InputData, Done);
end; { InputField.Done }
function InputField.GetQuit : Boolean;
{ Check to see if an input field has been exited with ESC }
begin
GetQuit := Quit;
end; { InputField.GetQuit }
procedure InputField.Edit(StartCursor : Word);
{ Edits the input field }
var
CursorPos, Start, Cursor : Word;
Ch : Word;
Good, InsMode, Finished : Boolean;
R : ScreenRowRange;
SCol, ECol, EndCol : ScreenColRange;
begin
with InputData^ do
begin
Quit := False;
SCol := StartCol; { Figure out where the field starts and stops }
if StopCol <= 0 then
EndCol := Scr.CurrCols + StopCol
else
EndCol := StopCol;
if InputRow <= 0 then
R := Scr.CurrRows + InputRow
else
R := InputRow;
if (R = Scr.CurrRows) and (ECol = Scr.CurrCols) then
Dec(EndCol);
ECol := EndCol;
InputArea.Init(SCol, R, ECol, R, Colors.InputColor);
InputArea.Clear;
if StartCursor = 0 then
CursorPos := Succ(Length)
else
CursorPos := StartCursor;
Finished := False;
InsMode := True;
Cursor := Scr.InsCursor;
Start := Max(Longint(CursorPos) - ECol - SCol + 2, 1);
repeat
if CursorPos > Length then
ECol := EndCol;
if (CursorPos < Start) or (CursorPos > Start + ECol - SCol) then
Start := Max(Longint(CursorPos) - ECol + SCol, 1);
if (Start = 2) and (SCol <> StartCol) then
begin
SCol := StartCol;
Start := 1;
end;
if Start > 1 then
begin
if SCol = StartCol then
begin
Inc(Start);
SCol := Succ(StartCol); { Text is off left side of line }
end;
end
else
SCol := StartCol;
if Length > Start + ECol - SCol then
begin
if ECol = EndCol then
begin
if SCol <> StartCol then
Inc(Start);
ECol := Pred(EndCol); { Text is off right side of line }
end;
end
else
ECol := EndCol;
GotoXY(StartCol, R);
if SCol <> StartCol then { Text is off left side of line }
WriteColor(LeftInputArrow, Colors.InputArrowColor);
WriteColor(LeftJustStr(InputData^.Copy(Start, Succ(ECol - SCol)),
Succ(ECol - SCol)), Colors.InputColor);
if ECol <> EndCol then { Text is off right side of line }
WriteColor(RightInputArrow, Colors.InputArrowColor);
GotoXY(CursorPos - Start + SCol, R);
SetCursor(Cursor);
Ch := GetKey;
SetCursor(NoCursor);
case Ch of
Ord(' ')..Ord('~') : begin
if not (InsMode and (Length = MaxInputLen)) then
begin
if UCase then
Ch := Ord(UpCase(Chr(Ch)));
if InsMode or (CursorPos > Length) then
Good := Insert(Chr(Ch), CursorPos)
else begin
Good := True;
Change(Chr(Ch), CursorPos);
end;
if Good then
Inc(CursorPos);
end;
end;
HomeKey : CursorPos := 1;
EndKey : CursorPos := Succ(Length);
BS : begin
if CursorPos > 1 then
begin
Delete(Pred(CursorPos), 1);
Dec(CursorPos);
end;
end;
DelKey : begin
if CursorPos <= Length then
Delete(CursorPos, 1);
end;
LeftKey : begin
if CursorPos > 1 then
Dec(CursorPos);
end;
RightKey : begin
if CursorPos <= Length then
Inc(CursorPos);
end;
InsKey : begin
InsMode := not InsMode;
if InsMode then
Cursor := Scr.InsCursor
else
Cursor := Scr.OldCursor;
end;
CtrlLeftKey : begin { Move back one word }
if (CursorPos > 1) and (Data^[CursorPos] <> ' ') then
Dec(CursorPos);
while (CursorPos > 1) and (Data^[CursorPos] = ' ') do
Dec(CursorPos);
while (CursorPos > 1) and (Data^[Pred(CursorPos)] <> ' ') do
Dec(CursorPos);
end;
CtrlRightKey : begin { Move forward one word }
while (CursorPos <= Length) and (Data^[CursorPos] <> ' ') do
Inc(CursorPos);
while (CursorPos <= Length) and (Data^[CursorPos] = ' ') do
Inc(CursorPos);
end;
ESC : begin
ClearInput;
Quit := True;
Finished := True;
end;
CR : Finished := True;
end; { case }
until Finished;
end; { with }
end; { InputField.Edit }
procedure InputField.ClearInput;
{ Makes the input field data a null long string }
var
Good : Boolean;
begin
Good := InputData^.FromString('');
end; { InputField.ClearInput }
function ReadString(Prompt : String; Len : Word;
var ESCPressed : Boolean) : String;
{ Read a string from the input area }
var
I : InputField;
begin
with I do
begin
if not Init(Length(Prompt) + 3, 0, -1, Len, NotUpper) then
begin
ESCPressed := True;
ReadString := '';
end;
WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
Edit(0);
ReadString := InputData^.ToString;
ESCPressed := GetQuit;
Done;
end; { with }
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
end; { ReadString }
function GetLegalChar(Prompt : String; Legal : CharSet;
var ESCPressed : Boolean) : Char;
{ Read a chanracter from the input area, only reading certain ones }
var
Ch : Char;
begin
WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
Ch := GetKeyChar(Legal);
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
GetLegalChar := Ch;
end; { GetLegalChar }
function GetYesNo(Prompt : String; var ESCPressed : Boolean) : Boolean;
{ Prints a "Yes/No" prompt, allowing the user to type Y or N to answer the
question }
var
Ch : Char;
begin
WriteXY(Prompt + ' (' + YesNo + ')?', 1, Pred(Scr.CurrRows),
Colors.PromptColor);
Ch := GetKeyChar(LegalYesNo);
ESCPressed := Ch = Chr(ESC);
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
GetYesNo := Ch = 'Y';
end; { GetYesNo }
function GetNumber(Prompt : String; Low, High : Longint;
var Result : Boolean) : Longint;
{ Prompts for a numeric value within a certain range }
var
I : InputField;
S : String;
Error : Integer;
L : Longint;
begin
with I do
begin
if not Init(Length(Prompt) + 3, 0, -1,
Max(Length(NumToString(Low)),
Length(NumToString(High))), NotUpper) then
begin
Result := False;
GetNumber := 0;
Exit;
end;
WriteXY(Prompt + ': ', 1, Pred(Scr.CurrRows), Colors.PromptColor);
repeat
Edit(0);
S := InputData^.ToString;
if (not GetQuit) and (S <> '') then
begin
Val(S, L, Error);
Result := (Error = 0) and (L >= Low) and (L <= High);
if not Result then
Scr.PrintError(ErrNumberError1 + NumToString(Low) +
ErrNumberError2 + NumToString(High));
end
else begin
Result := False;
L := 0;
end;
until Result or (S = '');
Done;
end; { with }
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.BlankColor);
GetNumber := L;
end; { GetNumber }
end.

View File

@ -0,0 +1,242 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCLStr;
{ Turbo Pascal 6.0 object-oriented example long string routines.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$S-}
interface
uses Objects, TCUtil;
const
MaxLStringLength = 65521; { The maximum amount that can be allocated
to a pointer }
type
LStringRange = 0..MaxLStringLength;
LStringData = array [1..MaxLStringLength] of Char;
LStringDataPtr = ^LStringData;
LStringPtr = ^LString;
LString = object
Len : LStringRange; { Current length }
MaxLen : LStringRange; { Length that has been allocated. This is
always allocated in blocks of 16 bytes so
that the long string's data doesn't have to
be reallocated every time the long string
grows }
Data : LStringDataPtr;
constructor Init;
destructor Done;
function SetValue(NewLen : LStringRange; NewData : Pointer) : Boolean;
function FromString(S : String) : Boolean;
function ToString : String;
function Length : LStringRange;
function Copy(Start, Amt : LStringRange) : String;
function Insert(S : String; Start : LStringRange) : Boolean;
procedure Delete(Start, Amt : LStringRange);
function Append(S : String) : Boolean;
procedure Change(Ch : Char; Start : LStringRange);
function Assign(LS : LString) : Boolean;
function FromStream(var S : TDosStream) : Boolean;
procedure ToStream(var S : TDosStream);
end;
implementation
constructor LString.Init;
{ Initializes the long string. }
begin
Len := 0;
MaxLen := 0;
Data := nil;
end; { LString.Init }
destructor LString.Done;
{ Frees memory used by the long string. }
begin
if Data <> nil then
FreeMem(Data, MaxLen);
end; { LString.Done }
function LString.SetValue(NewLen : LStringRange;
NewData : Pointer) : Boolean;
{ Copies an area of memory to the long string }
var
Size : Word;
NData : Pointer;
begin
Size := (NewLen + 15) shr 4 shl 4; { Calculate the new size }
if NewLen > MaxLen then { Allocate new data area if the long string }
begin { needs to grow }
GetMem(NData, Size);
if NData = nil then { The allocation failed. Return False }
begin
SetValue := False;
Exit;
end;
if Data <> nil then { If there was any data in the long string, }
begin { copy it to the new data area }
Move(Data^, NData^, Len);
FreeMem(Data, MaxLen); { Free the memory used by the long string }
end; { before it was reallocated }
Data := NData; { Set Data and MaxLen to their new values }
MaxLen := Size;
end;
Move(NewData^, Data^, NewLen); { Copy the new data to the long string }
Len := NewLen; { Set the length }
SetValue := True; { Successful - Return True }
end; { LString.SetValue }
function LString.FromString(S : String) : Boolean;
{ Converts a string into a long string }
begin
if not SetValue(System.Length(S), @S[1]) then
begin { Set the long string to be a null }
FromString := SetValue(0, nil); { string if it could not be expanded }
FromString := False; { Return False }
end
else
FromString := True; { Successful. Return True }
end; { LString.FromString }
function LString.ToString : String;
{ Converts a long string into a string }
var
S : String;
NewLen : Byte;
begin
NewLen := Min(255, Length); { The maximum length of a string is 255 }
S[0] := Chr(NewLen); { Set the length of the new string }
Move(Data^, S[1], NewLen); { Copy the data }
ToString := S; { Return the new string }
end; { LString.ToString }
function LString.Length : LStringRange;
{ Returns the current length of a long string }
begin
Length := Len;
end; { LString.Length }
function LString.Copy(Start, Amt : LStringRange) : String;
{ Copies part of a long string into a string }
var
S : String;
begin
if Start > Len then { Trying to copy past the end of the long }
Amt := 0 { string - return a null string }
else
Amt := Min(Amt, Succ(Len - Start)); { Calculate length of new string }
S[0] := Chr(Amt); { Set length of new string }
Move(Data^[Start], S[1], Amt); { Copy data into new string }
Copy := S; { Return new string }
end; { LString.Copy }
function LString.Insert(S : String; Start : LStringRange) : Boolean;
{ Inserts a string into a long string }
var
OldLen : LStringRange;
Size : Word;
NData : Pointer;
begin
OldLen := Len;
Inc(Len, System.Length(S));
if Len > MaxLen then { Allocate new data area if the long }
begin { string needs to grow }
Size := (Len + 15) shr 4 shl 4; { Calculate the new size }
GetMem(NData, Size); { Allocate new data area }
if NData = nil then { The long string could not be expanded }
begin
Dec(Len, System.Length(S)); { Restore the old Len value }
Insert := False; { Return False }
Exit;
end;
if Data <> nil then { If there was data in the long string, }
begin { copy it to the new data area }
Move(Data^, NData^, OldLen);
FreeMem(Data, MaxLen); { Free the old data area }
end;
Data := NData; { Set new values for Data and MaxLen }
MaxLen := Size;
end;
if Start <= OldLen then { Move the part of the string after the insert to }
{ the right to make space for the new string }
Move(Data^[Start], Data^[Start + System.Length(S)], Succ(OldLen - Start));
Move(S[1], Data^[Start], System.Length(S)); { Insert the new string }
Insert := True; { Successful - return True }
end; { LString.Insert }
procedure LString.Delete(Start, Amt : LStringRange);
{ Deletes part of a long string }
begin
Amt := Min(Amt, Succ(Len - Start)); { No characters can be deleted past
the end of the long string }
if Start + Amt <= Len then { The delete is in the middle of the long
string - move the rest of the data to the
left }
Move(Data^[Start + Amt], Data^[Start], Succ(Len - Amt - Start));
Dec(Len, Amt); { Fix the length value }
end; { LString.Delete }
function LString.Append(S : String) : Boolean;
{ Appends a string to a long string }
begin
Append := Insert(S, Succ(Len)); { Insert the string at the end }
end; { LString.Append }
procedure LString.Change(Ch : Char; Start : LStringRange);
{ Change a particular character of a long string }
begin
Move(Ch, Data^[Start], 1);
end; { LString.Change }
function LString.Assign(LS : LString) : Boolean;
{ Copy one long string to another one }
begin
Assign := SetValue(LS.Length, LS.Data);
end; { LString.Assign }
function LString.FromStream(var S : TDosStream) : Boolean;
{ Read a long string from a stream }
var
Counter, NewLen, Size : Word;
Dummy : Byte;
NData : Pointer;
begin
S.Read(NewLen, SizeOf(NewLen)); { Read the length }
Size := (NewLen + 15) shr 4 shl 4; { Calculate the new size }
if NewLen > MaxLen then { Allocate new data area if the long string }
begin { needs to grow }
GetMem(NData, Size);
if NData = nil then { The allocation failed. Return False }
begin
for Counter := 1 to NewLen do { Read the string in so that the file }
S.Read(Dummy, 1); { position is still correct }
FromStream := False;
Exit;
end;
if Data <> nil then { If there was any data in the long string, }
begin { copy it to the new data area }
Move(Data^, NData^, Len);
FreeMem(Data, MaxLen);
end;
Data := NData; { Set new values for Data and MaxLen }
MaxLen := Size;
end;
S.Read(Data^, NewLen); { Read the long string from the stream }
Len := NewLen;
FromStream := True; { Successful - return True }
end; { LString.FromStream }
procedure LString.ToStream(var S : TDosStream);
{ Write a long string to a stream }
begin
S.Write(Len, SizeOf(Len)); { Write the length }
S.Write(Data^, Len); { Write the long string }
end; { LString.ToStream }
end.

View File

@ -0,0 +1,233 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCMenu;
{ Turbo Pascal 6.0 object-oriented example command line menu system.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$S-}
interface
uses Crt, TCUtil, TCScreen;
{ The menus in this unit are very simple. Each menu points to a parent (so
that ESC will take you back to the previous menu) and a list of items.
Each item is either a pointer to a procedure that will be executed when
you choose the item, or is a pointer to a new menu.
}
type
MenuItemPtr = ^MenuItem;
MenuPtr = ^Menu;
Menu = object
MenuString, CommandString : StringPtr;
MenuItems, LastItem : MenuItemPtr;
Parent : MenuPtr;
constructor Init(InitMenuString : String; InitParent : MenuPtr);
procedure AddItem(NewItem : MenuItemPtr);
function AddItemProc(NewProc : ProcPtr) : Boolean;
function AddItemMenu(NewMenu : MenuPtr) : Boolean;
procedure RunMenu;
destructor Done;
end;
MenuItem = object
Next : MenuItemPtr;
constructor Init;
procedure RunItem(var CurrMenu : MenuPtr); virtual;
end;
MenuItemProcPtr = ^MenuItemProc;
MenuItemProc = object(MenuItem)
Proc : ProcPtr;
constructor Init(InitProc : ProcPtr);
procedure RunItem(var CurrMenu : MenuPtr); virtual;
end;
MenuItemMenuPtr = ^MenuItemMenu;
MenuItemMenu = object(MenuItem)
NewMenu : MenuPtr;
constructor Init(InitMenu : MenuPtr);
procedure RunItem(var CurrMenu : MenuPtr); virtual;
end;
implementation
constructor Menu.Init(InitMenuString : String; InitParent : MenuPtr);
{ Initializes a new menu }
var
S : String;
Counter : Word;
begin
MenuItems := nil;
LastItem := nil;
GetMem(MenuString, Succ(Length(InitMenuString)));
if MenuString = nil then
Fail;
MenuString^ := InitMenuString;
S := '';
for Counter := 1 to Length(InitMenuString) do
begin
if (InitMenuString[Counter] in ['A'..'Z']) then
{ Build command string based on upper case letters in mwenu string }
S := S + InitMenuString[Counter];
end;
GetMem(CommandString, Succ(Length(S)));
if CommandString = nil then
begin
Done;
Fail;
end;
CommandString^ := S;
Parent := InitParent;
end; { Menu.Init }
destructor Menu.Done;
{ Removes a menu from memory }
begin
if MenuString <> nil then
FreeMem(MenuString, Succ(Length(MenuString^)));
if CommandString <> nil then
FreeMem(CommandString, Succ(Length(CommandString^)));
LastItem := MenuItems;
while LastItem <> nil do
begin
MenuItems := LastItem;
LastItem := LastItem^.Next;
Dispose(MenuItems);
end;
end; { Menu.Done }
procedure Menu.AddItem(NewItem : MenuItemPtr);
{ Adds a new item to a menu }
begin
if MenuItems = nil then
begin
MenuItems := NewItem;
LastItem := MenuItems;
end
else begin
LastItem^.Next := NewItem;
LastItem := LastItem^.Next;
end;
end; { Menu.AddItem }
function Menu.AddItemProc(NewProc : ProcPtr) : Boolean;
{ Adds a procedure item to a menu }
var
NewItem : MenuItemProcPtr;
begin
NewItem := New(MenuItemProcPtr, Init(NewProc));
if NewItem <> nil then
begin
AddItem(NewItem);
AddItemProc := True;
end
else
AddItemProc := False;
end; { Menu.AddItemProc }
function Menu.AddItemMenu(NewMenu : MenuPtr) : Boolean;
{ Adds a new menu item to a menu }
var
NewItem : MenuItemMenuPtr;
begin
NewItem := New(MenuItemMenuPtr, Init(NewMenu));
if NewItem <> nil then
begin
AddItem(NewItem);
AddItemMenu := True;
end
else
AddItemMenu := False;
end; { Menu.AddItemMenu }
procedure Menu.RunMenu;
{ Run a menu system }
var
Ch, Counter, P : Word;
CurrMenu : MenuPtr;
I : MenuItemPtr;
begin
CurrMenu := @Self;
repeat
with CurrMenu^ do
begin
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor); { Print the menu }
for Counter := 1 to Length(MenuString^) do
begin
if MenuString^[Counter] in ['A'..'Z'] then
WriteColor(MenuString^[Counter], Colors.MenuHiColor)
else
WriteColor(MenuString^[Counter], Colors.MenuLoColor);
end;
repeat
Ch := GetKeyUpCase;
case Ch of
ESC : CurrMenu := Parent;
Ord(' ')..Ord('~') : begin
P := Pos(Chr(Lo(Ch)), CommandString^);
if P <> 0 then { A menu item has been chosen }
begin
I := MenuItems;
for Counter := 2 to P do
begin
if I <> nil then
I := I^.Next;
end;
if I <> nil then
begin
I^.RunItem(CurrMenu); { Run the procedure or switch menus }
Ch := ESC;
end;
end;
end;
end; { case }
until Ch = ESC;
end; { with }
until CurrMenu = nil;
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor);
end; { Menu.RunMenu }
constructor MenuItem.Init;
{ Initializes a menu item }
begin
Next := nil;
end; { MenuItem.Init }
procedure MenuItem.RunItem(var CurrMenu : MenuPtr);
begin
Abstract('MenuItem.RunItem');
end; { MenuItem.RunItem }
constructor MenuItemProc.Init(InitProc : ProcPtr);
{ Initializes a procedure menu item }
begin
MenuItem.Init;
Proc := InitProc;
end; { MenuItemProc.Init }
procedure MenuItemProc.RunItem(var CurrMenu : MenuPtr);
{ Runs the procedure that a procedure menu item points to }
begin
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor);
if @Proc <> nil then
Proc;
CurrMenu := nil;
end; { MenuItemProc.RunItem }
constructor MenuItemMenu.Init(InitMenu : MenuPtr);
{ Initializes a new menu menu item }
begin
MenuItem.Init;
NewMenu := InitMenu;
end; { MenuItemMenu.Init }
procedure MenuItemMenu.RunItem(var CurrMenu : MenuPtr);
{ Changes CurrMenu so that the menu that the item points to becomes the new
current menu }
begin
CurrMenu := NewMenu;
end; { MenuItemMenu.RunItem }
end.

View File

@ -0,0 +1,151 @@
; Turbo Pascal 6.0 object-oriented example
; Assembler code for TCALC example
; Copyright (c) 1989,90 by Borland International, Inc.
MODEL TPASCAL
LOCALS
DATASEG
EXTRN CheckSnow : BYTE
CODESEG
PUBLIC MoveToScreen, MoveFromScreen
; procedure MoveToScreen(var Source, Dest; Len : Word);
;
; Moves memory from normal RAM to screen memory, making sure that the video
; interference that can occur when you do this on certain CGA's is
; prevented.
;
; Variables:
;
; Source : Far pointer to the location of the memory to be moved.
; Dest : Far pointer to the destination of the memory to be moved.
; Len : The amount in bytes of the memory to be moved.
Proc MoveToScreen Source : DWord, Dest : DWord, Len : Word
push ds ; Save DS
mov bh,[CheckSnow] ; Load CheckSnow value
lds si,[Source] ; Source pointer into DS:SI
les di,[Dest] ; Dest pointer into ES:DI
mov cx,[Len] ; Len value into CX
jcxz @@0 ; Quit if Len = 0
cmp si,di ; Find out if source comes before destination
; in memory
jle @@1 ; If it does, copy from end of memory area
cld ; Set direction to forward
jmp short @@2
@@1:
add si,cx ; Move SI and DI to the ends of the memory
sub si,2 ; areas
add di,cx
sub di,2
std ; Set direction to backward
@@2:
cmp bh,0 ; If CheckSnow is false, use fast screen I/O
je @@7
@@3:
shr cx,1 ; Change bytes to words
mov dx,3DAh ; Point DX to CGA status port
mov bl,9 ; Move horiz. + vertical retrace mask to bl
@@4:
lodsw ; Grab a video word
mov bp,ax ; Save it in BP
@@5:
in al,dx ; Get 6845 status
rcr al,1 ; Check horizontal retrace
jb @@5 ; Loop if in horizontal retrace: this prevents
; starting in mid-retrace, since there is
; exactly enough time for 1 and only 1 STOSW
; during horizontal retrace
cli ; No ints during critical section
@@6:
in al,dx ; Get 6845 status
and al,bl ; Check for both kinds of retrace: IF the
; video board does not report horizontal
; retrace while in vertical retrace, this
; will allow several characters to be
; stuffed in during vertical retrace
jz @@6 ; Loop if equal to zero
mov ax,bp ; Get the video word
stosw ; Store the video word
sti ; Allow interrupts
loop @@4 ; Go do next word
jmp short @@0
@@7:
shr cx,1 ; Change bytes to words
rep movsw
@@0:
pop ds ; Restore DS
ret
ENDP
; procedure MoveFromScreen(var Source, Dest; Len : Word);
;
; Moves memory to normal RAM from screen memory, making sure that the video
; interference that can occur when you do this on certain CGA's is
; prevented.
;
; Variables:
;
; Source : Far pointer to the location of the memory to be moved.
; Dest : Far pointer to the destination of the memory to be moved.
; Len : The amount in bytes of the memory to be moved.
Proc MoveFromScreen Source : DWord, Dest : DWord, Len : Word
push ds ; Save DS
mov bh,[CheckSnow] ; Load CheckSnow value
lds si,[Source] ; Source pointer into DS:SI
les di,[Dest] ; Dest pointer into ES:DI
mov cx,[Len] ; Len value into CX
jcxz @@0 ; Quit if Len = 0
cmp si,di ; Find out if source comes before destination
; in memory
jle @@1
cld ; Set direction to forward
jmp short @@2
@@1:
add si,cx ; Move SI and DI to the ends of the memory
sub si,2 ; areas
add di,cx
sub di,2
std ; Set direction to backward
@@2:
cmp bh,0 ; If CheckSnow is false, use fast screen I/O
je @@6
@@3:
shr cx,1 ; Change bytes to words
mov dx,3DAh ; Point DX to CGA status port
@@4:
in al,dx ; Get 6845 status
rcr al,1 ; Check horizontal retrace
jb @@4 ; Loop if in horizontal retrace: this prevents
; starting in mid-retrace, since there is
; exactly enough time for 1 and only 1 LODSW
; during horizontal retrace
cli ; No ints during critical section
@@5:
in al,dx ; Get 6845 status
rcr al,1 ; Check for horizontal retrace: LODSW is 1
; clock cycle slower than STOSW; because of
; this, the vertical retrace trick can't be
; used because it causes flicker! (RCR AL,1
; is 1 cycle faster than AND AL,AH)
jnb @@5 ; Loop if not in retrace
lodsw ; Load the video word
sti ; Allow interrupts
stosw ; Store the video word
loop @@4 ; Go do next word
jmp short @@0
@@6:
shr cx,1 ; Change bytes to words
rep movsw
@@0:
pop ds ; Restore DS
ret
ENDP
END

Binary file not shown.

View File

@ -0,0 +1,676 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCParser;
{ Turbo Pascal 6.0 object-oriented example parser.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$N+,S-}
interface
uses Crt, Dos, TCUtil, TCScreen, TCCell, TCCellSp, TCLStr;
const
ParserStackSize = 10;
MaxFuncNameLen = 5;
ExpLimit = 11356;
SqrLimit = 1E2466;
MaxExpLen = 4;
TotalErrors = 7;
ErrParserStack = 1;
ErrBadRange = 2;
ErrExpression = 3;
ErrOperator = 4;
ErrOpenParen = 5;
ErrCell = 6;
ErrOpCloseParen = 7;
ErrorMessages : array[1..TotalErrors] of String[33] =
('Parser stack overflow', 'Bad cell range', 'Expected expression',
'Expected operator', 'Expected open paren', 'Expected cell',
'Expected operator or closed paren');
type
ErrorRange = 0..TotalErrors;
TokenTypes = (Plus, Minus, Times, Divide, Expo, Colon, OParen, CParen,
Num, CellT, Func, EOL, Bad);
TokenRec = record
State : Byte;
case Byte of
0 : (Value : Extended);
1 : (CP : CellPos);
2 : (FuncName : String[MaxFuncNameLen]);
end;
ParserObj = object
Inp : LStringPtr;
ParserHash : CellHashTablePtr;
PMaxCols : Word;
PMaxRows : Word;
Position : Word;
CurrToken : TokenRec;
StackTop : 0..ParserStackSize;
TokenError : ErrorRange;
ParseError : Boolean;
CType : CellTypes;
ParseValue : Extended;
Stack : array[1..ParserStackSize] of TokenRec;
TokenType : TokenTypes;
TokenLen : Word;
MathError, IsFormula : Boolean;
constructor Init(InitHash : CellHashTablePtr; InitInp : LStringPtr;
InitPMaxCols, InitPMaxRows : Word);
function IsFunc(S : String) : Boolean;
procedure Push(Token : TokenRec);
procedure Pop(var Token : TokenRec);
function GotoState(Production : Word) : Word;
procedure Shift(State : Word);
procedure Reduce(Reduction : Word);
function NextToken : TokenTypes;
procedure Parse;
function CellValue(P : CellPos) : Extended;
end;
var
Parser : ParserObj;
implementation
constructor ParserObj.Init(InitHash : CellHashTablePtr;
InitInp : LStringPtr;
InitPMaxCols, InitPMaxRows : Word);
{ Initializes the parser }
begin
ParserHash := InitHash;
Inp := InitInp;
PMaxCols := InitPMaxCols;
PMaxRows := InitPMaxRows;
Position := 1;
StackTop := 0;
TokenError := 0;
MathError := False;
IsFormula := False;
ParseError := False;
end; { ParserObj.Init }
function ParserObj.IsFunc(S : String) : Boolean;
{ Checks to see if the parser is about to read a function }
var
Counter, SLen : Word;
begin
with Inp^ do
begin
SLen := System.Length(S);
for Counter := 1 to System.Length(S) do
begin
if UpCase(Data^[Pred(Position + Counter)]) <> S[Counter] then
begin
IsFunc := False;
Exit;
end;
end;
CurrToken.FuncName := UpperCase(Copy(Position, SLen));
Inc(Position, SLen);
IsFunc := True;
end; { with }
end; { IsFunc }
function ParserObj.NextToken : TokenTypes;
{ Gets the next Token from the Input stream }
var
NumString : String[80];
FormLen, Place, TLen, NumLen, Check : Word;
Ch, FirstChar : Char;
Decimal : Boolean;
begin
with Inp^ do
begin
while (Position <= Length) and (Data^[Position] = ' ') do
Inc(Position);
TokenLen := Position;
if Position > Length then
begin
NextToken := EOL;
TokenLen := 0;
Exit;
end;
Ch := UpCase(Data^[Position]);
if Ch in ['0'..'9', '.'] then
begin
NumString := '';
TLen := Position;
Decimal := False;
while (TLen <= Length) and
((Data^[TLen] in ['0'..'9']) or
((Data^[TLen] = '.') and (not Decimal))) do
begin
NumString := NumString + Data^[TLen];
if Ch = '.' then
Decimal := True;
Inc(TLen);
end;
if (TLen = 2) and (Ch = '.') then
begin
NextToken := BAD;
TokenLen := 0;
Exit;
end;
if (TLen <= Length) and ((Data^[TLen] = 'E') or
(Data^[TLen] = 'e')) then
begin
NumString := NumString + 'E';
Inc(TLen);
if Data^[TLen] in ['+', '-'] then
begin
NumString := NumString + Data^[TLen];
Inc(TLen);
end;
NumLen := 1;
while (TLen <= Length) and (Data^[TLen] in ['0'..'9']) and
(NumLen <= MaxExpLen) do
begin
NumString := NumString + Data^[TLen];
Inc(NumLen);
Inc(TLen);
end;
end;
if NumString[1] = '.' then
NumString := '0' + NumString;
Val(NumString, CurrToken.Value, Check);
if Check <> 0 then
MathError := True;
NextToken := NUM;
Inc(Position, System.Length(NumString));
TokenLen := Position - TokenLen;
Exit;
end
else if Ch in Letters then
begin
if IsFunc('ABS') or
IsFunc('ATAN') or
IsFunc('COS') or
IsFunc('EXP') or
IsFunc('LN') or
IsFunc('ROUND') or
IsFunc('SIN') or
IsFunc('SQRT') or
IsFunc('SQR') or
IsFunc('TRUNC') then
begin
NextToken := FUNC;
TokenLen := Position - TokenLen;
Exit;
end;
if FormulaStart(Inp, Position, PMaxCols, PMaxRows, CurrToken.CP,
FormLen) then
begin
Inc(Position, FormLen);
IsFormula := True;
NextToken := CELLT;
TokenLen := Position - TokenLen;
Exit;
end
else begin
NextToken := BAD;
TokenLen := 0;
Exit;
end;
end
else begin
case Ch of
'+' : NextToken := PLUS;
'-' : NextToken := MINUS;
'*' : NextToken := TIMES;
'/' : NextToken := DIVIDE;
'^' : NextToken := EXPO;
':' : NextToken := COLON;
'(' : NextToken := OPAREN;
')' : NextToken := CPAREN;
else begin
NextToken := BAD;
TokenLen := 0;
Exit;
end;
end;
Inc(Position);
TokenLen := Position - TokenLen;
Exit;
end; { case }
end; { with }
end; { ParserObj.NextToken }
procedure ParserObj.Push(Token : TokenRec);
{ Pushes a new Token onto the stack }
begin
if StackTop = ParserStackSize then
TokenError := ErrParserStack
else begin
Inc(StackTop);
Stack[StackTop] := Token;
end;
end; { ParserObj.Push }
procedure ParserObj.Pop(var Token : TokenRec);
{ Pops the top Token off of the stack }
begin
Token := Stack[StackTop];
Dec(StackTop);
end; { ParserObj.Pop }
function ParserObj.GotoState(Production : Word) : Word;
{ Finds the new state based on the just-completed production and the
top state.
}
var
State : Word;
begin
State := Stack[StackTop].State;
if (Production <= 3) then
begin
case State of
0 : GotoState := 1;
9 : GotoState := 19;
20 : GotoState := 28;
end; { case }
end
else if Production <= 6 then
begin
case State of
0, 9, 20 : GotoState := 2;
12 : GotoState := 21;
13 : GotoState := 22;
end; { case }
end
else if Production <= 8 then
begin
case State of
0, 9, 12, 13, 20 : GotoState := 3;
14 : GotoState := 23;
15 : GotoState := 24;
16 : GotoState := 25;
end; { case }
end
else if Production <= 10 then
begin
case State of
0, 9, 12..16, 20 : GotoState := 4;
end; { case }
end
else if Production <= 12 then
begin
case State of
0, 9, 12..16, 20 : GotoState := 6;
5 : GotoState := 17;
end; { case }
end
else begin
case State of
0, 5, 9, 12..16, 20 : GotoState := 8;
end; { case }
end;
end; { ParserObj.GotoState }
function ParserObj.CellValue(P : CellPos) : Extended;
{ Returns the value of a cell }
var
CPtr : CellPtr;
begin
CPtr := ParserHash^.Search(P);
with CPtr^ do
begin
if (not LegalValue) or HasError then
begin
MathError := True;
CellValue := 0;
end
else
CellValue := CurrValue;
end; { with }
end; { ParserObj.CellValue }
procedure ParserObj.Shift(State : Word);
{ Shifts a Token onto the stack }
begin
CurrToken.State := State;
Push(CurrToken);
TokenType := NextToken;
end; { ParserObj.Shift }
procedure ParserObj.Reduce(Reduction : Word);
{ Completes a reduction }
var
Token1, Token2 : TokenRec;
Counter : CellPos;
begin
case Reduction of
1 : begin
Pop(Token1);
Pop(Token2);
Pop(Token2);
CurrToken.Value := Token1.Value + Token2.Value;
end;
2 : begin
Pop(Token1);
Pop(Token2);
Pop(Token2);
CurrToken.Value := Token2.Value - Token1.Value;
end;
4 : begin
Pop(Token1);
Pop(Token2);
Pop(Token2);
CurrToken.Value := Token1.Value * Token2.Value;
end;
5 : begin
Pop(Token1);
Pop(Token2);
Pop(Token2);
if Token1.Value = 0 then
MathError := True
else
CurrToken.Value := Token2.Value / Token1.Value;
end;
7 : begin
Pop(Token1);
Pop(Token2);
Pop(Token2);
if Token2.Value <= 0 then
MathError := True
else if (Token1.Value * Ln(Token2.Value) < -ExpLimit) or
(Token1.Value * Ln(Token2.Value) > ExpLimit) then
MathError := True
else
CurrToken.Value := Exp(Token1.Value * Ln(Token2.Value));
end;
9 : begin
Pop(Token1);
Pop(Token2);
CurrToken.Value := -Token1.Value;
end;
11 : begin
Pop(Token1);
Pop(Token2);
Pop(Token2);
CurrToken.Value := 0;
if Token1.CP.Row = Token2.CP.Row then
begin
if Token1.CP.Col < Token2.CP.Col then
TokenError := ErrBadRange
else begin
Counter.Row := Token1.CP.Row;
for Counter.Col := Token2.CP.Col to Token1.CP.Col do
CurrToken.Value := CurrToken.Value + CellValue(Counter);
end;
end
else if Token1.CP.Col = Token2.CP.Col then
begin
if Token1.CP.Row < Token2.CP.Row then
TokenError := ErrBadRange
else begin
Counter.Col := Token1.CP.Col;
for Counter.Row := Token2.CP.Row to Token1.CP.Row do
CurrToken.Value := CurrToken.Value + CellValue(Counter);
end;
end
else if (Token1.CP.Col >= Token2.CP.Col) and
(Token1.CP.Row >= Token2.CP.Row) then
begin
for Counter.Row := Token2.CP.Row to Token1.CP.Row do
begin
for Counter.Col := Token2.CP.Col to Token1.CP.Col do
CurrToken.Value := CurrToken.Value + CellValue(Counter);
end;
end
else
TokenError := ErrBadRange;
end;
13 : begin
Pop(CurrToken);
CurrToken.Value := CellValue(CurrToken.CP);
end;
14 : begin
Pop(Token1);
Pop(CurrToken);
Pop(Token1);
end;
16 : begin
Pop(Token1);
Pop(CurrToken);
Pop(Token1);
Pop(Token1);
if Token1.FuncName = 'ABS' then
CurrToken.Value := Abs(CurrToken.Value)
else if Token1.FuncName = 'ATAN' then
CurrToken.Value := ArcTan(CurrToken.Value)
else if Token1.FuncName = 'COS' then
CurrToken.Value := Cos(CurrToken.Value)
else if Token1.FuncName = 'EXP' then
begin
if (CurrToken.Value < -ExpLimit) or (CurrToken.Value > ExpLimit) then
MathError := True
else
CurrToken.Value := Exp(CurrToken.Value);
end
else if Token1.FuncName = 'LN' then
begin
if CurrToken.Value <= 0 then
MathError := True
else
CurrToken.Value := Ln(CurrToken.Value);
end
else if Token1.FuncName = 'ROUND' then
begin
if (CurrToken.Value < -1E9) or (CurrToken.Value > 1E9) then
MathError := True
else
CurrToken.Value := Round(CurrToken.Value);
end
else if Token1.FuncName = 'SIN' then
CurrToken.Value := Sin(CurrToken.Value)
else if Token1.FuncName = 'SQRT' then
begin
if CurrToken.Value < 0 then
MathError := True
else
CurrToken.Value := Sqrt(CurrToken.Value);
end
else if Token1.FuncName = 'SQR' then
begin
if (CurrToken.Value < -SQRLIMIT) or (CurrToken.Value > SQRLIMIT) then
MathError := True
else
CurrToken.Value := Sqr(CurrToken.Value);
end
else if Token1.FuncName = 'TRUNC' then
begin
if (CurrToken.Value < -1E9) or (CurrToken.Value > 1E9) then
MathError := True
else
CurrToken.Value := Trunc(CurrToken.Value);
end;
end;
3, 6, 8, 10, 12, 15 : Pop(CurrToken);
end; { case }
CurrToken.State := GotoState(Reduction);
Push(CurrToken);
end; { ParserObj.Reduce }
procedure ParserObj.Parse;
{ Parses an input stream }
var
FirstToken : TokenRec;
Accepted : Boolean;
begin
Position := 1;
StackTop := 0;
TokenError := 0;
MathError := False;
IsFormula := False;
ParseError := False;
with Inp^ do
begin
if (Length = 2) and (Data^[1] = RepeatFirstChar) then
begin
CType := ClRepeat;
Exit;
end;
if Data^[1] = TextFirstChar then
begin
CType := ClText;
Exit;
end;
end; { with }
Accepted := False;
FirstToken.State := 0;
FirstToken.Value := 0;
Push(FirstToken);
TokenType := NextToken;
repeat
case Stack[StackTop].State of
0, 9, 12..16, 20 : begin
if TokenType = NUM then
Shift(10)
else if TokenType = CELLT then
Shift(7)
else if TokenType = FUNC then
Shift(11)
else if TokenType = MINUS then
Shift(5)
else if TokenType = OPAREN then
Shift(9)
else begin
TokenError := ErrExpression;
Dec(Position, TokenLen);
end;
end;
1 : begin
if TokenType = EOL then
Accepted := True
else if TokenType = PLUS then
Shift(12)
else if TokenType = MINUS then
Shift(13)
else begin
TokenError := ErrOperator;
Dec(Position, TokenLen);
end;
end;
2 : begin
if TokenType = TIMES then
Shift(14)
else if TokenType = DIVIDE then
Shift(15)
else
Reduce(3);
end;
3 : Reduce(6);
4 : begin
if TokenType = EXPO then
Shift(16)
else
Reduce(8);
end;
5 : begin
if TokenType = NUM then
Shift(10)
else if TokenType = CELLT then
Shift(7)
else if TokenType = FUNC then
Shift(11)
else if TokenType = OPAREN then
Shift(9)
else
TokenError := ErrExpression;
end;
6 : Reduce(10);
7 : begin
if TokenType = COLON then
Shift(18)
else
Reduce(13);
end;
8 : Reduce(12);
10 : Reduce(15);
11 : begin
if TokenType = OPAREN then
Shift(20)
else
TokenError := ErrOpenParen;
end;
17 : Reduce(9);
18 : begin
if TokenType = CELLT then
Shift(26)
else
TokenError := ErrCell;
end;
19 : begin
if TokenType = PLUS then
Shift(12)
else if TokenType = MINUS then
Shift(13)
else if TokenType = CPAREN then
Shift(27)
else
TokenError := ErrOpCloseParen;
end;
21 : begin
if TokenType = TIMES then
Shift(14)
else if TokenType = DIVIDE then
Shift(15)
else
Reduce(1);
end;
22 : begin
if TokenType = TIMES then
Shift(14)
else if TokenType = DIVIDE then
Shift(15)
else
Reduce(2);
end;
23 : Reduce(4);
24 : Reduce(5);
25 : Reduce(7);
26 : Reduce(11);
27 : Reduce(14);
28 : begin
if TokenType = PLUS then
Shift(12)
else if TokenType = MINUS then
Shift(13)
else if TokenType = CPAREN then
Shift(29)
else
TokenError := ErrOpCloseParen;
end;
29 : Reduce(16);
end; { case }
until Accepted or (TokenError <> 0);
if TokenError <> 0 then
begin
with Scr do
begin
if TokenError = ErrBadRange then
Dec(Position, TokenLen);
PrintError(ErrorMessages[TokenError]);
Exit;
end; { with }
end;
if IsFormula then
CType := ClFormula
else
CType := ClValue;
if MathError then
begin
ParseError := True;
ParseValue := 0;
Exit;
end;
ParseError := False;
ParseValue := Stack[StackTop].Value;
end; { ParserObj.Parse }
end.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,522 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCScreen;
{ Turbo Pascal 6.0 object-oriented example screen routines.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$S-}
interface
uses Crt, Dos, TCUtil;
const
ScreenCols = 80;
ScreenRows = 50;
MinScreenRows = 25;
ESCPress = 'Press ESC.'; { Printed in error messages }
type
Direction = (Up, Down, Left, Right);
ScreenColRange = 1..ScreenCols;
ScreenRowRange = 1..ScreenRows;
VideoTypes = (MDA, CGA, MCGA, EGA, VGA);
ScreenChar = record
Data : Char;
Attrib : Byte;
end;
ScreenArray = array[ScreenRowRange, ScreenColRange] of ScreenChar;
ScreenRow = array[ScreenColRange] of ScreenChar;
ScreenPointer = ^ScreenArray;
ScreenPos = record
Col : ScreenColRange;
Row : ScreenRowRange;
end;
Screen = object
CurrRows : ScreenRowRange;
CurrCols : ScreenColRange;
VideoType : VideoTypes;
OldCursor : Word;
InsCursor : Word;
OldMode : Word;
constructor Init;
destructor Done;
procedure ToggleMaxLinesMode;
procedure PrintError(Error : String);
procedure PrintMessage(Message : String);
procedure ClearMessage;
procedure PrintHelpLine(CommandString : String);
end;
ScreenArea = object
UpperLeft, LowerRight : ScreenPos;
Attrib : Byte;
constructor Init(InitX1 : ScreenColRange; InitY1 : ScreenRowRange;
InitX2 : ScreenColRange; InitY2 : ScreenRowRange;
InitAttrib : Byte);
procedure Scroll(Dir : Direction; Amt : Word);
procedure Clear;
procedure Erase;
end;
ColorTableType = (ColorMono, ColorBW, ColorColor);
ColorTablePtr = ^ColorTable;
ColorTable = object
TableType : ColorTableType;
BlankColor : Byte;
ValueCellColor : Byte;
TextCellColor : Byte;
FormulaCellColor : Byte;
RepeatCellColor : Byte;
ColColor : Byte;
RowColor : Byte;
InfoColor : Byte;
HighlightColor : Byte;
BlockColor : Byte;
InputColor : Byte;
InputArrowColor : Byte;
ErrorColor : Byte;
CellErrorColor : Byte;
MemoryColor : Byte;
CellDataColor : Byte;
PromptColor : Byte;
FileNameColor : Byte;
ChangedColor : Byte;
TitleColor : Byte;
ContentsColor : Byte;
KeyNameColor : Byte;
KeyDescColor : Byte;
MenuHiColor : Byte;
MenuLoColor : Byte;
MessageColor : Byte;
constructor Init;
procedure FillColorTable;
end;
const
NoCursor = $2000;
var
Colors : ColorTable;
Scr : Screen;
ScreenPtr : ScreenPointer;
procedure MoveToScreen(var Source, Dest; Len : Word);
procedure MoveFromScreen(var Source, Dest; Len : Word);
procedure ClrEOLXY(Col : ScreenColRange; Row : ScreenRowRange;
Color : Byte);
procedure WriteColor(S : String; Color : Byte);
procedure WriteXY(S : String; Col : ScreenColRange; Row : ScreenRowRange;
Color : Byte);
procedure WriteXYClr(S : String; Col : ScreenColRange; Row : ScreenRowRange;
Color : Byte);
procedure SetCursor(NewCursor : Word);
function GetCursor : Word;
implementation
const
TotalColors = 26;
WhiteOnRed = White + (Red shl 4);
WhiteOnBlue = White + (Blue shl 4);
WhiteOnCyan = White + (Cyan shl 4);
BlackOnGray = LightGray shl 4;
WhiteOnGray = White + (LightGray shl 4);
BlinkingLightRed = LightRed + Blink;
BlinkingWhite = White + Blink;
LightCyanOnBlue = LightCyan + (Blue shl 4);
YellowOnBlue = Yellow + (Blue shl 4);
type
ColorArray = array[1..TotalColors] of Byte;
const
ColorColors : ColorArray = (White, LightCyan, White, LightMagenta, White,
WhiteOnRed, WhiteOnRed, WhiteOnCyan,
WhiteOnBlue, WhiteOnCyan, White, LightCyan,
WhiteOnRed, BlinkingLightRed, LightRed,
LightGreen, Yellow, LightCyan, Yellow,
LightMagenta, Yellow, LightCyanOnBlue,
YellowOnBlue, LightCyan, White,
BlinkingLightRed);
BWColors : ColorArray = (White, White, White, White, White, BlackOnGray,
BlackOnGray, WhiteOnGray, WhiteOnGray, BlackOnGray,
White, White, White, BlinkingWhite, White, White,
White, White, White, White, White, BlackOnGray,
White, White, LightGray, BlinkingWhite);
MonoColors : ColorArray = (White, White, White, White, White, BlackOnGray,
BlackOnGray, BlackOnGray, BlackOnGray,
BlackOnGray, White, White, White, BlinkingWhite,
White, White, White, White, White, White, White,
BlackOnGray, White, White, LightGray,
BlinkingWhite);
const
InsCursorSmall = $0007;
InsCursorLarge = $000D;
var
SavedExitProc : Pointer;
procedure ClearScreen(X1, Y1, X2, Y2, Attrib : Word);
{ Clears an area of the screen }
var
Reg : Registers;
begin
if (X1 > X2) or (Y1 > Y2) then { Illegal values }
Exit;
with Reg do
begin
AX := $0600; { Clear screen through the BIOS }
BH := Attrib;
CH := Pred(Y1);
CL := Pred(X1);
DH := Pred(Y2);
DL := Pred(X2);
Intr($10, Reg);
end; { with }
end; { ClearScreen }
{$L TCMVSMEM}
procedure MoveToScreen(var Source, Dest; Len : Word); external;
{ Moves screen memory from normal RAM to screen memory - see TCMVSMEM.ASM
for source }
procedure MoveFromScreen(var Source, Dest; Len : Word); external;
{ Moves screen memory to normal RAM from screen memory - see TCMVSMEM.ASM
for source }
procedure MoveText(OldX1, OldY1, OldX2, OldY2, NewX1, NewY1 : Word);
{ Moves an area of text to a new position on the screen }
var
Counter, Len : Word;
begin
if (OldX2 < OldX1) or (OldY2 < OldY1) then
Exit;
Len := Succ(OldX2 - OldX1) shl 1;
if NewY1 < OldY1 then
begin { Move it row by row, going forwards }
for Counter := 0 to OldY2 - OldY1 do
MoveFromScreen(ScreenPtr^[OldY1 + Counter, OldX1],
ScreenPtr^[NewY1 + Counter, NewX1], Len)
end
else begin { Move it row by row, going backwards }
for Counter := OldY2 - OldY1 downto 0 do
MoveFromScreen(ScreenPtr^[OldY1 + Counter, OldX1],
ScreenPtr^[NewY1 + Counter, NewX1], Len)
end;
end; { MoveText }
procedure ScrollText(Dir : Direction; X1, Y1, X2, Y2, Amt, Attrib : Word);
{ Scrolls the screen by an amount in a direction - it does this by moving
the text to be scrolled and then clearing the area that wasn't scrolled }
begin
case Dir of
Up : begin
MoveText(X1, Y1 + Amt, X2, Y2, X1, Y1);
ClearScreen(X1, Succ(Y2 - Amt), X2, Y2, Attrib);
end;
Down : begin
MoveText(X1, Y1, X2, Y2 - Amt, X1, Succ(Y1));
ClearScreen(X1, Y1, X2, Pred(Y1 + Amt), Attrib);
end;
Left : begin
MoveText(X1 + Amt, Y1, X2, Y2, X1, Y1);
ClearScreen(Succ(X2 - Amt), Y1, X2, Y2, Attrib);
end;
Right : begin
MoveText(X1, Y1, X2 - Amt, Y2, X1 + Amt, Y1);
ClearScreen(X1, Y1, Pred(X1 + Amt), Y2, Attrib);
end;
end; { case }
end; { ScrollText }
function EGAInstalled : Boolean;
{ Tests for the presence of an EGA }
var
Reg : Registers;
begin
Reg.AX := $1200;
Reg.BX := $0010;
Reg.CX := $FFFF;
Intr($10, Reg);
EGAInstalled := Reg.CX <> $FFFF;
end; { EGAInstalled }
function PS2 : Boolean;
{ This function returns True if we are running on a PS/2 type video adapter }
var
Regs : Registers;
begin
Regs.AX := $1A00;
Intr($10, Regs);
PS2 := ((Regs.AL and $FF) = $1A) and
((Regs.BL and $FF) in [$07, $08, $0B, $0C]);
end; { PS2 }
procedure ClrEOLXY(Col : ScreenColRange; Row : ScreenRowRange; Color : Byte);
{ Clears to the end-of-line in a color at a specified position }
begin
GotoXY(Col, Row);
TextAttr := Color;
ClrEOL;
end; { ClrEOLXY }
procedure WriteColor(S : String; Color : Byte);
{ Writes a string in a color }
begin
TextAttr := Color;
Write(S);
end; { WriteColor }
procedure WriteXY(S : String; Col : ScreenColRange; Row : ScreenRowRange;
Color : Byte);
{ Writes a string in a color at a specified position }
begin
GotoXY(Col, Row);
WriteColor(S, Color);
end; { WriteXY }
procedure WriteXYClr(S : String; Col : ScreenColRange; Row : ScreenRowRange;
Color : Byte);
{ Clears to the end-of-line in a color at a specified position and then
writes a string }
begin
ClrEOLXY(Col, Row, Color);
Write(S);
end; { WriteXYClr }
procedure SetCursor(NewCursor : Word);
{ Sets the value of the scan lines of the cursor }
var
Reg : Registers;
begin
with Reg do
begin
AH := 1;
BH := 0;
CX := NewCursor;
Intr($10, Reg);
end; { with }
end; { SetCursor }
function GetCursor : Word;
{ Returns the value of the scan lines of the cursor }
var
Reg : Registers;
begin
with Reg do
begin
AH := 3;
BH := 0;
Intr($10, Reg);
GetCursor := CX;
end; { Reg }
end; { GetCursor }
constructor Screen.Init;
{ Finds what type of video adapter is being run on, and initializes various
variables based on this information }
var
Reg : Registers;
begin
OldMode := LastMode;
Reg.AH := $0F;
Intr($10, Reg); { Check for the current video mode }
if Reg.AL <> 7 then
begin
if EGAInstalled then
begin
if PS2 then
VideoType := VGA
else
VideoType := EGA;
end
else begin
if PS2 then
VideoType := MCGA
else
VideoType := CGA;
end;
ScreenPtr := Ptr($B800, 0);
if Reg.AL < 2 then
CurrCols := 40
else
CurrCols := 80;
end
else begin
VideoType := MDA;
ScreenPtr := Ptr($B000, 0);
CurrCols := 80;
end;
CurrRows := Succ(Hi(WindMax));
OldCursor := GetCursor;
if (CurrRows = MinScreenRows) and (VideoType <> CGA) then
InsCursor := InsCursorLarge
else
InsCursor := InsCursorSmall;
end; { Screen.Init }
destructor Screen.Done;
{ Restores the screen mode and cursor that existed at the start of the
program }
begin
TextMode(OldMode);
SetCursor(OldCursor);
ExitProc := SavedExitProc;
end; { Screen.Done }
procedure Screen.ToggleMaxLinesMode;
{ Toggles the display in and out of 43/50-line mode }
begin
if CurrRows = MinScreenRows then
begin
TextMode(Lo(LastMode) + Font8x8);
InsCursor := InsCursorSmall;
end
else begin
TextMode(Lo(LastMode));
InsCursor := InsCursorLarge;
end;
CurrRows := Succ(Hi(WindMax));
end; { Screen.ToggleMaxLinesMode }
procedure Screen.PrintError(Error : String);
{ Prints an error message at the bottom of the screen }
var
Ch : Word;
Buffer : ScreenRow;
begin
MoveFromScreen(ScreenPtr^[CurrRows, 1], Buffer,
SizeOf(ScreenChar) * CurrCols); { Save bottom line }
WriteXYClr(CenterStr(Error + '. ' + ESCPress, Pred(CurrCols)), 1, CurrRows,
Colors.ErrorColor);
Beep;
repeat
Ch := GetKey;
until Ch = ESC;
MoveToScreen(Buffer, ScreenPtr^[CurrRows, 1], { Restore bottom line }
SizeOf(ScreenChar) * CurrCols);
end; { Screen.PrintError }
procedure Screen.PrintMessage(Message : String);
{ Prints a message }
begin
WriteXYClr(Message + '...', 1, Pred(CurrRows), Colors.MessageColor);
end; { Screen.PrintMessage }
procedure Screen.ClearMessage;
{ Clears the last printed message }
begin
ClrEOLXY(1, Pred(CurrRows), Colors.MessageColor);
end; { Screen.ClearMessage }
procedure Screen.PrintHelpLine(CommandString : String);
{ Prints a help line at the bottom of the screen. The command string is
made up of a series of keys and descriptions separated by backslashes.
Example: 'F1\Help\F2\Save\F3\Load\Alt-X\Exit'}
var
P : Integer;
S : String[ScreenCols];
begin
CommandString := CommandString + '\';
ClrEOLXY(1, CurrRows, Colors.KeyDescColor);
while CommandString <> '' do
begin
Write(' ');
P := Pos('\', CommandString);
WriteColor(Copy(CommandString, 1, Pred(P)), Colors.KeyNameColor);
Delete(CommandString, 1, P);
P := Pos('\', CommandString);
if CommandString[1] = '\' then
S := '-'
else
S := '-' + Copy(CommandString, 1, Pred(P));
WriteColor(S, Colors.KeyDescColor);
Delete(CommandString, 1, P);
end;
end; { Screen.PrintHelpLine }
constructor ScreenArea.Init(InitX1 : ScreenColRange; InitY1 : ScreenRowRange;
InitX2 : ScreenColRange; InitY2 : ScreenRowRange;
InitAttrib : Byte);
{ Sets up a screen area }
begin
UpperLeft.Col := InitX1;
UpperLeft.Row := InitY1;
LowerRight.Col := InitX2;
LowerRight.Row := InitY2;
Attrib := InitAttrib;
end; { ScreenArea.Init }
procedure ScreenArea.Scroll(Dir : Direction; Amt : Word);
{ Scrolls a screen area an certain amount in a direction }
begin
ScrollText(Dir, UpperLeft.Col, UpperLeft.Row, LowerRight.Col,
LowerRight.Row, Amt, Attrib);
end; { ScreenArea.Scroll }
procedure ScreenArea.Clear;
{ Clears a screen area }
begin
ClearScreen(UpperLeft.Col, UpperLeft.Row, LowerRight.Col, LowerRight.Row,
Attrib);
end; { ScreenArea.Clear }
procedure ScreenArea.Erase;
{ Erases a screen area by writing over it in black }
begin
ClearScreen(UpperLeft.Col, UpperLeft.Row, LowerRight.Col, LowerRight.Row,
Black);
end; { ScreenArea.Erase }
constructor ColorTable.Init;
{ Initializes the color table by finding the video mode that is being used }
begin
case Lo(LastMode) of
BW40, BW80 : TableType := ColorBW;
CO40, CO80 : TableType := ColorColor;
Mono : TableType := ColorMono;
end; { case }
FillColorTable;
end; { ColorTable.Init }
procedure ColorTable.FillColorTable;
{ Moves the correct built-in color table to the program's color table }
var
P : Pointer;
begin
case TableType of
ColorColor : P := @ColorColors;
ColorBW : P := @BWColors;
ColorMono : P := @MonoColors;
end; { case }
Move(P^, BlankColor, TotalColors);
end; { ColorTable.FillColorTable }
{$F+}
procedure ScreenExit;
{ Clears the screen at exit }
begin
Scr.Done;
end; { ScreenExit }
{$F-}
begin
SavedExitProc := ExitProc;
ExitProc := @ScreenExit;
TextMode(LastMode);
Scr.Init;
Colors.Init;
end.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,378 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCUtil;
{ Turbo Pascal 6.0 object-oriented example miscellaneous utility routines.
This unit is used by TCALC.PAS.
See TCALC.DOC for an more information about this example.
}
{$S-}
interface
uses Crt, Dos;
const
FreeListItems = 100; { Sets the size of the free list }
Letters : set of Char = ['A'..'Z', 'a'..'z'];
Numbers : set of Char = ['0'..'9'];
ErrAbstractCall = 'Call to abstract method ';
ErrNoMemory = 'Out of memory';
NULL = 0;
BS = 8;
FF = 12;
CR = 13;
ESC = 27;
F1 = 15104;
F2 = 15360;
F3 = 15616;
F4 = 15872;
F5 = 16128;
F6 = 16384;
F7 = 16640;
F8 = 16896;
F9 = 17152;
F10 = 17408;
AltF1 = 26624;
AltF2 = 26880;
AltF3 = 27136;
AltF4 = 27392;
AltF5 = 27648;
AltF6 = 27904;
AltF7 = 28160;
AltF8 = 28416;
AltF9 = 28672;
AltF10 = 28928;
HomeKey = 18176;
UpKey = 18432;
PgUpKey = 18688;
LeftKey = 19200;
RightKey = 19712;
EndKey = 20224;
DownKey = 20480;
PgDnKey = 20736;
InsKey = 20992;
DelKey = 21248;
CtrlLeftKey = 29440;
CtrlRightKey = 29696;
AltX = 11520;
type
ProcPtr = procedure;
StringPtr = ^String;
WordPtr = ^Word;
CharSet = set of Char;
procedure Abstract(Name : String);
function Compare(var P1, P2; Length : Word) : Boolean;
function GetKey : Word;
function GetKeyUpCase : Word;
function GetKeyChar(Legal : CharSet) : Char;
procedure Abort(Message : String);
procedure Beep;
function FileExists(F : String) : Boolean;
function Min(N1, N2 : Longint) : Longint;
function Max(N1, N2 : Longint) : Longint;
function NumToString(N : Longint) : String;
function UpperCase(S : String) : String;
function FillString(Len : Byte; Ch : Char) : String;
function TruncStr(TString : String; Len : Byte) : String;
function PadChar(PString : String; Ch : Char; Len : Byte) : String;
function CenterStr(S : String; Width : Byte) : String;
function LeftJustStr(S : String; Width : Byte) : String;
function RightJustStr(S : String; Width : Byte) : String;
function ColToString(Col : Word) : String;
function RowToString(Row : Word) : String;
function StringToCol(S : String; MaxCols : Word) : Word;
function StringToRow(S : String; MaxRows : Word) : Word;
procedure ClearInputBuffer;
implementation
const
AbortMessage : String[80] = '';
var
SavedExitProc : Pointer;
procedure Abstract(Name : String);
{ Called by abstract methods which should never be executed. Aborts the
program with an error message.
}
begin
Abort(ErrAbstractCall + Name);
end; { Abstract }
{$L TCCOMPAR}
function Compare(var P1, P2; Length : Word) : Boolean; external;
{ Compares two areas of memory - see TCCOMPAR.ASM for the source }
function GetKey : Word;
{ Returns the value of a key that was pressed - handles extended characters
(function keys, etc.) by treating all characters as words.
}
var
Ch : Char;
begin
Ch := ReadKey;
if Ord(Ch) = NULL then { Extended character }
GetKey := Word(Ord(ReadKey)) shl 8
else
GetKey := Ord(Ch); { Normal character }
end; { GetKey }
function GetKeyUpCase : Word;
{ Returns the upper case equivalent of a character from the keyboard }
var
Ch : Word;
begin
Ch := GetKey;
if (Ch >= Ord(' ')) and (Ch <= Ord('~')) then
GetKeyUpCase := Ord(UpCase(Chr(Ch))) { Change the character's case }
else
GetKeyUpCase := Ch; { Leave the character alone }
end; { GetKeyUpCase }
function GetKeyChar(Legal : CharSet) : Char;
{ Reads an ASCII key from the keyboard, only accepting keys in Legal }
var
Ch : Word;
begin
repeat
Ch := GetKeyUpCase;
until (Ch = ESC) or (Chr(Lo(Ch)) in Legal);
GetKeyChar := Chr(Lo(Ch));
end; { GetKeyChar }
procedure Abort(Message : String);
{ Aborts the program with an error message }
begin
AbortMessage := Message;
Halt(1);
end; { Abort }
procedure Beep;
{ Produces a low beep on the speaker }
begin
Sound(220);
Delay(300);
NoSound;
end; { Beep }
function FileExists(F : String) : Boolean;
{ Checks to see if a selected file exists }
var
SR : SearchRec;
begin
FindFirst(F, AnyFile, SR);
FileExists := DosError = 0;
end; { FileExists }
function Min(N1, N2 : Longint) : Longint;
{ Returns the smaller of two numbers }
begin
if N1 <= N2 then
Min := N1
else
Min := N2;
end; { Min }
function Max(N1, N2 : Longint) : Longint;
{ Returns the larger of two numbers }
begin
if N1 >= N2 then
Max := N1
else
Max := N2;
end; { Max }
function NumToString(N : Longint) : String;
{ Converts a number to a string }
var
S : String[80];
begin
Str(N, S);
NumToString := S;
end; { NumToString }
function UpperCase(S : String) : String;
{ Returns an all-upper case version of a string }
var
Counter : Word;
begin
for Counter := 1 to Length(S) do
S[Counter] := UpCase(S[Counter]);
UpperCase := S;
end; { UpperCase }
function FillString(Len : Byte; Ch : Char) : String;
var
S : String;
begin
S[0] := Chr(Len);
FillChar(S[1], Len, Ch);
FillString := S;
end; { FillString }
function TruncStr(TString : String; Len : Byte) : String;
{ Truncates a string to a specified length }
begin
if Length(TString) > Len then
Delete(TString, Succ(Len), Length(TString) - Len);
TruncStr := TString;
end; { TruncStr }
function PadChar(PString : String; Ch : Char; Len : Byte) : String;
{ Pads a string to a specified length with a specified character }
var
CurrLen : Byte;
begin
CurrLen := Min(Length(PString), Len);
PString[0] := Chr(Len);
FillChar(PString[Succ(CurrLen)], Len - CurrLen, Ch);
PadChar := PString;
end; { PadChar }
function CenterStr(S : String; Width : Byte) : String;
{ Center a string within a certain width }
begin
S := LeftJustStr(LeftJustStr('', (Width - Length(S)) shr 1) + S, Width);
CenterStr := S;
end; { CenterStr }
function LeftJustStr(S : String; Width : Byte) : String;
{ Left-justify a string within a certain width }
begin
LeftJustStr := PadChar(S, ' ', Width);
end; { LeftJustStr }
function RightJustStr(S : String; Width : Byte) : String;
{ Right-justify a string within a certain width }
begin
S := TruncStr(S, Width);
RightJustStr := LeftJustStr('', Width - Length(S)) + S;
end; { RightJustStr }
function ColToString(Col : Word) : String;
{ Converts a column to a string }
var
S : String[4];
W : Word;
begin
if Col > 18278 then { Column is 4 letters }
S := Chr(Ord('A') + ((Col - 18279) div 17576))
else
S := '';
if Col > 702 then { Column is at least 3 letters }
S := S + Chr(Ord('A') + (((Col - 703) mod 17576) div 676));
if Col > 26 then { Column is at least 2 letters }
S := S + Chr(Ord('A') + (((Col - 27) mod 676) div 26));
S := S + Chr(Ord('A') + (Pred(Col) mod 26));
ColToString := S;
end; { ColToString }
function RowToString(Row : Word) : String;
{ Converts a row to a string }
begin
RowToString := NumToString(Row);
end; { RowToString }
function StringToCol(S : String; MaxCols : Word) : Word;
{ Converts a string to a column }
var
L : Byte;
C : Longint;
begin
StringToCol := 0; { Return 0 by default to indicate a bad column }
L := Length(S);
if L = 0 then
Exit;
S := UpperCase(S);
for C := 1 to L do
begin
if not (S[C] in Letters) then { Bad letter - return }
Exit;
end;
C := Ord(S[L]) - Ord(Pred('A'));
if L > 1 then
Inc(C, (Ord(S[Pred(L)]) - Ord(Pred('A'))) * 26);
if L > 2 then
Inc(C, (Ord(S[L - 2]) - Ord(Pred('A'))) * 676);
if L > 3 then
Inc(C, Longint(Ord(S[L - 3]) - Ord(Pred('A'))) * 17576);
if C > MaxCols then
Exit;
StringToCol := C; { Successful - return column string }
end; { StringToCol }
function StringToRow(S : String; MaxRows : Word) : Word;
{ Converts a string to a Rown }
var
R : Longint;
Error : Integer;
begin
StringToRow := 0; { Return 0 by default to indicate a bad row }
if S = '' then
Exit;
Val(S, R, Error);
if (Error = 0) and (R <= MaxRows) then
StringToRow := R;
end; { StringToRow }
procedure ClearInputBuffer;
{ Clears the keyboard buffer }
var
Ch : Char;
begin
while KeyPressed do
Ch := ReadKey;
end; { ClearInputBuffer }
{$F+}
function UtilHeapError(Size : Word) : Integer;
{ Simple heap error handler - returns a nil pointer if allocation was not
successful }
begin
UtilHeapError := 1;
end; { UtilHeapError }
procedure UtilExit;
{ Called on exit to print abort message and restore exit procedure }
begin
if AbortMessage <> '' then
Writeln(AbortMessage + '.');
ExitProc := SavedExitProc;
end; { UtilExit }
{$F-}
begin
SavedExitProc := ExitProc;
HeapError := @UtilHeapError;
ExitProc := @UtilExit;
end.

View File

@ -0,0 +1,42 @@
{ Copyright (c) 1990 by Borland International, Inc. }
(*
Programs compiled with {$G} compiler directive enabled do not
check the processor at runtime to determine whether it is
286-compatible. Trying to execute 80286 instructions on an 8086
or an 8088 will lock up the computer. This program shows how to
check for the presence of a 286-compatible chip at runtime.
If you want to put code like this in a program with {$G+}
enabled, put the test and halt code in the initialization
section of the first unit in the main program's USES clause.
*)
program Test286;
function Is286Able: Boolean; assembler;
asm
PUSHF
POP BX
AND BX,0FFFH
PUSH BX
POPF
PUSHF
POP BX
AND BX,0F000H
CMP BX,0F000H
MOV AX,0
JZ @@1
MOV AX,1
@@1:
end;
begin
if not Is286Able then
begin
Writeln('Need an 80286-compatible system to run this program');
Halt(1);
end;
end.


View File

@ -0,0 +1,13 @@
-c
-p
-r-
-u-
-zCCODE
-zP
-zA
-zRCONST
-zS
-zT
-zDDATA
-zG
-zB

View File

@ -0,0 +1,204 @@
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit Walls;
{ Turbo Pascal 6.0 object-oriented example.
See BREAKOUT.PAS.
This unit defines the Wall object type.
It's a fairly complex object, because it plays such a
pivotal role in the game.
}
interface
uses Screen, Bricks, Bounds, Crt;
type
BrickPtr = ^Brick;
BW = array[1..1000] of Brick;
WallPtr = ^BW;
Wall = object(Obstacle)
BrickWall : WallPtr;
Height : Integer;
NumLeft : Integer;
Value : Integer;
NCells : Integer;
constructor Init(InitX, InitY, InitWidth, InitHeight : Integer);
destructor Done; virtual;
procedure Show; virtual;
procedure Hide; virtual;
function Collide(var B : Ball) : Boolean; virtual;
function GetValue : Integer; virtual;
procedure Reset;
end;
implementation
function RandomColor(MaxColors : Integer) : Integer;
var
C : Integer;
begin
C := Random(MaxColors);
while C = (TextAttr SHR 4) do
C := Random(MaxColors);
RandomColor := C;
end;
procedure Beep;
begin
Sound(100);
Delay(20);
NoSound;
end;
{ A wall is an array of bricks. Its constructor actually builds a
conformant array, so we don't have to hardcode the size of the
wall. }
constructor Wall.Init(InitX, InitY, InitWidth, InitHeight : Integer);
begin
Obstacle.Init(InitX, InitY, InitWidth, False);
Height := InitHeight;
NCells := Width*5;
GetMem(BrickWall, Width*Height*SizeOf(Brick));
Reset;
end;
destructor Wall.Done;
begin
FreeMem(BrickWall, Width*Height*SizeOf(Block));
end;
{ This procedure could be made simpler, but you wouldn't get the slick
effect you see when the wall is built. }
procedure Wall.Show;
var
CurCol : Integer;
Count : Integer;
CurBlock : Integer;
begin
Visible := True;
NumLeft := Width*Height;
for CurCol := 1 to Width + Height - 1 do
for Count := 0 to Height - 1 do
begin
CurBlock := CurCol + Count*(Width-1);
if (CurCol - Count >= 1) and (CurCol - Count <= Width) then
begin
BrickWall^[CurBlock].Show;
Delay(5);
end;
end;
GoToXY(X + (5*Width DIV 2) - 7, Y);
TextColor(WHITE);
Write('Turbo Breakout');
end;
procedure Wall.Hide;
var
CurCol : Integer;
Count : Integer;
CurBlock : Integer;
begin
Visible := False;
for CurCol := 1 to Width + Height - 1 do
for Count := 0 to Height - 1 do
begin
CurBlock := CurCol + Count*(Width-1);
if (CurCol - Count >= 1) and (CurCol - Count <= Width) then
begin
if BrickWall^[CurBlock].IsVisible then
begin
BrickWall^[CurBlock].Hide;
Delay(5);
end;
end;
end;
end;
function Wall.Collide(var B : Ball) : Boolean;
var
CollideV, CollideH : Boolean;
{ To check for a collision with a brick, first we check if the ball is in
the area where the wall is located, then we see if there's a brick that's
still visible at the ball's position. If so, we destroy the brick, grab
its value, and beep. }
function CheckCollide(XPos, YPos : Integer) : Boolean;
var
ThisBrick : BrickPtr;
begin
CheckCollide := False;
if (YPos < Y) or (YPos > Y + Height - 1) or
(XPos < X) or (XPos > X + NCells - 1) then
Exit;
ThisBrick := @BrickWall^[1 + ((XPos-1) DIV 5) + Width*(YPos - 1)];
if ThisBrick^.IsVisible then
begin
CheckCollide := True;
Inc(Value, ThisBrick^.GetValue);
ThisBrick^.Hide;
Dec(NumLeft);
Beep;
if NumLeft = 0 then
Show;
end
end;
{ When checking for a collision with the wall, we have to watch out
for special cases involving corners. }
begin
Collide := False;
Value := 0;
CollideV := CheckCollide(B.X, B.NextY);
CollideH := CheckCollide(B.NextX, B.Y);
if CollideV then
begin
Collide := True;
B.ReverseY;
end;
if CollideH then
begin
Collide := True;
B.ReverseX;
end;
if not CollideV and not CollideH then
if CheckCollide(B.NextX, B.NextY) then
begin
Collide := True;
B.ReverseX;
B.ReverseY;
end;
end;
function Wall.GetValue : Integer;
begin
GetValue := Value;
end;
procedure Wall.Reset;
var
CurRow : Integer;
CurCol : Integer;
MaxColors : Integer;
begin
if LastMode = Mono then
MaxColors := 4
else
MaxColors := 16;
NumLeft := Width*Height;
for CurRow := 0 to Height - 1 do
for CurCol := 0 to Width - 1 do
BrickWall^[CurRow*Width+CurCol+1].Init(X + CurCol*5,
Y + CurRow,
RandomColor(MaxColors),
Height - Y - CurRow + 1);
if Visible then
Show;
end;
end.

View File

@ -0,0 +1,284 @@
; Turbo Pascal 6.0 example
; Assembler include file for WIN.PAS unit
; Copyright (c) 1989,90 by Borland International, Inc.
TITLE WIN
LOCALS @@
; Coordinate record
X EQU (BYTE PTR 0)
Y EQU (BYTE PTR 1)
; BIOS workspace equates
CrtMode EQU (BYTE PTR 49H)
CrtWidth EQU (BYTE PTR 4AH)
DATA SEGMENT WORD PUBLIC
; Externals from CRT unit
EXTRN CheckSnow:BYTE,WindMin:WORD,WindMax:WORD
DATA ENDS
CODE SEGMENT BYTE PUBLIC
ASSUME CS:CODE,DS:DATA
; procedure WriteStr(X, Y: Byte; S: String; Attr: Byte);
PUBLIC WriteStr
WriteStr:
PUSH BP
MOV BP,SP
LES BX,[BP+8]
MOV CL,ES:[BX]
MOV SI,OFFSET CS:CrtWriteStr
CALL CrtWrite
POP BP
RETF 10
; procedure WriteChar(X, Y, Count: Byte; Ch: Char; Attr: Byte);
PUBLIC WriteChar
WriteChar:
PUSH BP
MOV BP,SP
MOV CL,[BP+10]
MOV SI,OFFSET CS:CrtWriteChar
CALL CrtWrite
POP BP
RETF 10
; procedure FillWin(Ch: Char; Attr: Byte);
PUBLIC FillWin
FillWin:
MOV SI,OFFSET CS:CrtWriteChar
JMP SHORT CommonWin
; procedure ReadWin(var Buf);
PUBLIC ReadWin
ReadWin:
MOV SI,OFFSET CS:CrtReadWin
JMP SHORT CommonWin
; procedure WriteWin(var Buf);
PUBLIC WriteWin
WriteWin:
MOV SI,OFFSET CS:CrtWriteWin
; Common FillWin/ReadWin/WriteWin routine
CommonWin:
PUSH BP
MOV BP,SP
XOR CX,CX
MOV DX,WindMin
MOV CL,WindMax.X
SUB CL,DL
INC CX
@@1: PUSH CX
PUSH DX
PUSH SI
CALL CrtBlock
POP SI
POP DX
POP CX
INC DH
CMP DH,WindMax.Y
JBE @@1
POP BP
RETF 4
; Write string to screen
CrtWriteStr:
PUSH DS
MOV AH,[BP+6]
LDS SI,[BP+8]
INC SI
JC @@4
@@1: LODSB
MOV BX,AX
@@2: IN AL,DX
TEST AL,1
JNE @@2
CLI
@@3: IN AL,DX
TEST AL,1
JE @@3
MOV AX,BX
STOSW
STI
LOOP @@1
POP DS
RET
@@4: LODSB
STOSW
LOOP @@4
POP DS
RET
; Write characters to screen
CrtWriteChar:
MOV AL,[BP+8]
MOV AH,[BP+6]
JC @@4
MOV BX,AX
@@1: IN AL,DX
TEST AL,1
JNE @@1
CLI
@@2: IN AL,DX
TEST AL,1
JE @@2
MOV AX,BX
STOSW
STI
LOOP @@1
RET
@@4: REP STOSW
RET
; Read window buffer from screen
CrtReadWin:
PUSH DS
PUSH ES
POP DS
MOV SI,DI
LES DI,[BP+6]
CALL CrtCopyWin
MOV [BP+6],DI
POP DS
RET
; Write window buffer to screen
CrtWriteWin:
PUSH DS
LDS SI,[BP+6]
CALL CrtCopyWin
MOV [BP+6],SI
POP DS
RET
; Window buffer copy routine
CrtCopyWin:
JC @@4
@@1: LODSW
MOV BX,AX
@@2: IN AL,DX
TEST AL,1
JNE @@2
CLI
@@3: IN AL,DX
TEST AL,1
JE @@3
MOV AX,BX
STOSW
STI
LOOP @@1
RET
@@4: REP MOVSW
RET
; Do screen operation
; In CL = Buffer length
; SI = Write procedure pointer
; BP = Stack frame pointer
CrtWrite:
MOV DL,[BP+14]
DEC DL
ADD DL,WindMin.X
JC CrtExit
CMP DL,WindMax.X
JA CrtExit
MOV DH,[BP+12]
DEC DH
ADD DH,WindMin.Y
JC CrtExit
CMP DH,WindMax.Y
JA CrtExit
XOR CH,CH
JCXZ CrtExit
MOV AL,WindMax.X
SUB AL,DL
INC AL
CMP CL,AL
JB CrtBlock
MOV CL,AL
; Do screen operation
; In CL = Buffer length
; DX = CRT coordinates
; SI = Procedure pointer
CrtBlock:
MOV AX,40H
MOV ES,AX
MOV AL,DH
MUL ES:CrtWidth
XOR DH,DH
ADD AX,DX
SHL AX,1
MOV DI,AX
MOV AX,0B800H
CMP ES:CrtMode,7
JNE @@1
MOV AH,0B0H
@@1: MOV ES,AX
MOV DX,03DAH
CLD
CMP CheckSnow,1
JMP SI
; Exit from screen operation
CrtExit:
RET
; function WinSize: Word;
PUBLIC WinSize
WinSize:
MOV AX,WindMax
SUB AX,WindMin
ADD AX,101H
MUL AH
SHL AX,1
RETF
CODE ENDS
END

Binary file not shown.

View File

@ -0,0 +1,130 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Window Interface Unit }
{ }
{ Copyright (C) 1989,90 Borland International }
{ }
{*******************************************************}
unit Win;
{$D-,S-}
interface
uses Crt;
type
{ Window title string }
TitleStr = string[63];
{ Window frame characters }
FrameChars = array[1..8] of Char;
{ Window state record }
WinState = record
WindMin, WindMax: Word;
WhereX, WhereY: Byte;
TextAttr: Byte;
end;
const
{ Standard frame character sets }
SingleFrame: FrameChars = 'ÚÄ¿³³ÀÄÙ';
DoubleFrame: FrameChars = 'ÉÍ»ººÈͼ';
{ Direct write routines }
procedure WriteStr(X, Y: Byte; S: String; Attr: Byte);
procedure WriteChar(X, Y, Count: Byte; Ch: Char; Attr: Byte);
{ Window handling routines }
procedure FillWin(Ch: Char; Attr: Byte);
procedure ReadWin(var Buf);
procedure WriteWin(var Buf);
function WinSize: Word;
procedure SaveWin(var W: WinState);
procedure RestoreWin(var W: WinState);
procedure FrameWin(Title: TitleStr; var Frame: FrameChars;
TitleAttr, FrameAttr: Byte);
procedure UnFrameWin;
implementation
{$L WIN}
procedure WriteStr(X, Y: Byte; S: String; Attr: Byte);
external {WIN};
procedure WriteChar(X, Y, Count: Byte; Ch: Char; Attr: Byte);
external {WIN};
procedure FillWin(Ch: Char; Attr: Byte);
external {WIN};
procedure WriteWin(var Buf);
external {WIN};
procedure ReadWin(var Buf);
external {WIN};
function WinSize: Word;
external {WIN};
procedure SaveWin(var W: WinState);
begin
W.WindMin := WindMin;
W.WindMax := WindMax;
W.WhereX := WhereX;
W.WhereY := WhereY;
W.TextAttr := TextAttr;
end;
procedure RestoreWin(var W: WinState);
begin
WindMin := W.WindMin;
WindMax := W.WindMax;
GotoXY(W.WhereX, W.WhereY);
TextAttr := W.TextAttr;
end;
procedure FrameWin(Title: TitleStr; var Frame: FrameChars;
TitleAttr, FrameAttr: Byte);
var
W, H, Y: Word;
begin
W := Lo(WindMax) - Lo(WindMin) + 1;
H := Hi(WindMax) - Hi(WindMin) + 1;
WriteChar(1, 1, 1, Frame[1], FrameAttr);
WriteChar(2, 1, W - 2, Frame[2], FrameAttr);
WriteChar(W, 1, 1, Frame[3], FrameAttr);
if Length(Title) > W - 2 then Title[0] := Chr(W - 2);
WriteStr((W - Length(Title)) shr 1 + 1, 1, Title, TitleAttr);
for Y := 2 to H - 1 do
begin
WriteChar(1, Y, 1, Frame[4], FrameAttr);
WriteChar(W, Y, 1, Frame[5], FrameAttr);
end;
WriteChar(1, H, 1, Frame[6], FrameAttr);
WriteChar(2, H, W - 2, Frame[7], FrameAttr);
WriteChar(W, H, 1, Frame[8], FrameAttr);
Inc(WindMin, $0101);
Dec(WindMax, $0101);
end;
procedure UnFrameWin;
begin
Dec(WindMin, $0101);
Inc(WindMax, $0101);
end;
end.

View File

@ -0,0 +1,206 @@
{ Turbo Windows }
{ Copyright (c) 1989,90 by Borland International, Inc. }
program WinDemo;
{ Turbo Pascal 6.0 example.
This program demonstrates use of the WIN unit.
}
{$S-}
uses Crt, Win;
const
CClose = ^C;
CRight = ^D;
CUp = ^E;
CEnter = ^M;
CInsLin = ^N;
COpen = ^O;
CRandom = ^R;
CLeft = ^S;
CDown = ^X;
CDelLin = ^Y;
CExit = ^[;
type
TitleStrPtr = ^TitleStr;
WinRecPtr = ^WinRec;
WinRec = record
Next: WinRecPtr;
State: WinState;
Title: TitleStrPtr;
TitleAttr, FrameAttr: Byte;
Buffer: Pointer;
end;
var
TopWindow: WinRecPtr;
WindowCount: Integer;
Done: Boolean;
Ch: Char;
procedure ActiveWindow(Active: Boolean);
begin
if TopWindow <> nil then
begin
UnFrameWin;
with TopWindow^ do
if Active then
FrameWin(Title^, DoubleFrame, TitleAttr, FrameAttr)
else
FrameWin(Title^, SingleFrame, FrameAttr, FrameAttr);
end;
end;
procedure OpenWindow(X1, Y1, X2, Y2: Byte; T: TitleStr;
TAttr, FAttr: Byte);
var
W: WinRecPtr;
begin
ActiveWindow(False);
New(W);
with W^ do
begin
Next := TopWindow;
SaveWin(State);
GetMem(Title, Length(T) + 1);
Title^ := T;
TitleAttr := TAttr;
FrameAttr := FAttr;
Window(X1, Y1, X2, Y2);
GetMem(Buffer, WinSize);
ReadWin(Buffer^);
FrameWin(T, DoubleFrame, TAttr, FAttr);
end;
TopWindow := W;
Inc(WindowCount);
end;
procedure CloseWindow;
var
W: WinRecPtr;
begin
if TopWindow <> nil then
begin
W := TopWindow;
with W^ do
begin
UnFrameWin;
WriteWin(Buffer^);
FreeMem(Buffer, WinSize);
FreeMem(Title, Length(Title^) + 1);
RestoreWin(State);
TopWindow := Next;
end;
Dispose(W);
ActiveWindow(True);
Dec(WindowCount);
end;
end;
procedure Initialize;
begin
CheckBreak := False;
if (LastMode <> CO80) and (LastMode <> BW80) and
(LastMode <> Mono) then TextMode(CO80);
TextAttr := Black + LightGray * 16;
Window(1, 2, 80, 24);
FillWin(#178, LightGray + Black * 16);
Window(1, 1, 80, 25);
GotoXY(1, 1);
Write(' Turbo Pascal 6.0 Window Demo');
ClrEol;
GotoXY(1, 25);
Write(' Ins-InsLine Del-DelLine Alt-O-Open ' +
' Alt-C-Close Alt-R-Random Esc-Exit ');
ClrEol;
Randomize;
TopWindow := nil;
WindowCount := 0;
end;
procedure CreateWindow;
var
X, Y, W, H: Integer;
S: string[15];
Color: Byte;
begin
W := Random(50) + 10;
H := Random(15) + 5;
X := Random(80 - W) + 1;
Y := Random(23 - H) + 2;
Str(WindowCount + 1, S);
if LastMode <> CO80 then
Color := Black else Color := WindowCount mod 6 + 1;
OpenWindow(X, Y, X + W - 1, Y + H - 1, ' Window ' + S + ' ',
Color + LightGray * 16, LightGray + Color * 16);
TextAttr := LightGray;
ClrScr;
end;
procedure RandomText;
begin
repeat
Write(Chr(Random(95) + 32));
until KeyPressed;
end;
function ReadChar: Char;
var
Ch: Char;
begin
Ch := ReadKey;
if Ch = #0 then
case ReadKey of
#19: Ch := CRandom; { Alt-R }
#24: Ch := COpen; { Alt-O }
#45: Ch := CExit; { Alt-X }
#46: Ch := CClose; { Alt-C }
#72: Ch := CUp; { Up }
#75: Ch := CLeft; { Left }
#77: Ch := CRight; { Right }
#80: Ch := CDown; { Down }
#82: Ch := CInsLin; { Ins }
#83: Ch := CDelLin; { Del }
end;
ReadChar := Ch;
end;
procedure Beep;
begin
Sound(500); Delay(25); NoSound;
end;
begin
Initialize;
Done := False;
repeat
Ch := ReadChar;
if WindowCount = 0 then
if (Ch <> COpen) and (Ch <> CExit) then Ch := #0;
case Ch of
#32..#255: Write(Ch);
COpen: CreateWindow;
CClose: CloseWindow;
CUp: GotoXY(WhereX, WhereY - 1);
CLeft: GotoXY(WhereX - 1, WhereY);
CRight: GotoXY(WhereX + 1, WhereY);
CDown: GotoXY(WhereX, WhereY + 1);
CRandom: RandomText;
CInsLin: InsLine;
CDelLin: DelLine;
CEnter: WriteLn;
CExit: Done := True;
else
Beep;
end;
until Done;
Window(1, 1, 80, 25);
NormVideo;
ClrScr;
end.

View File

@ -0,0 +1,113 @@
BUFFERS
-------
This unit implements a simple movable memory manager, primarily
for use with the EDITORS unit. This unit sets aside a fixed
amount of memory to manage at the end of the normal heap, the
size of which is determined by BufHeapSize (in paragraphs).
Memory is allocated through calls to NewBuffer and SetBufferSize.
The advantage to movable memory managers is no memory is wasted
due to fragmentation since the memory can move. Unfortunately,
unless great care is taken, only one pointer to this memory can
exist.
As with most movable memory managers, BUFFERS allocates the
memory to what is referred to as a master pointer. The master
pointer is kept up-to-date as to the current location of the
buffer and is modified whenever the memory is moved. It is
assumed that this pointer, the pointer passed to the NewBuffer
procedure, is the only pointer that is pointing to the memory. If
a copy is made, either through an assignment or if the pointer is
passed as a parameter, the copy will not be updated. Typically
when a copy is necessary a pointer to the master pointer is used
instead. For example
CopyPtr = @MstrPtr;
When the copy is used, it is dereferenced twice, as in
CopyPtr^^ := {Some value};
so that all references to the memory allocated go through the
master pointer. Note, since very few allocations can meet these
requirements, this unit is not intended to replace Turbo Pascal's
heap manager for general heap allocation needs.
Care should be taken when using pointers allocated with BUFFERS.
It is bad practice to assume that a copy of the master pointer is
valid. Such assumptions can lead to sporadic and very difficult-
to-reproduce bugs. Typically, only the master pointer itself is
ever used, as is done in EDITORS.
BUFFERS is a simple movable memory manager in that it does not
try to minimize the movement of buffers when a buffer is
deallocated or resized. Buffers are positioned in the buffer area
in the order they are allocated. When a buffer is resized, the
buffers above it are moved up or down to accommodate the change.
Since this movement takes time, it is assumed that the user of
this unit will take great pains to minimize the resizing of
buffers.
Variables
---------
BufHeapSize: Word = 0;
The amount of memory, in paragraphs, to be managed by this
unit. This variable must be set before calling InitBuffers.
BufHeapPtr: Word = 0;
The segment marking the beginning of buffer memory.
BufHeapEnd: Word = 0;
The segment marking the end of buffer memory.
Procedures and Functions
------------------------
procedure InitBuffers;
Allocates a block of memory from the end of the heap to be used
for buffers. The size of this block is determined by the value
of BufHeapSize (in paragraphs) when this routine is called.
procedure DoneBuffers;
Returns to the heap the memory allocated by InitBuffers.
procedure NewBuffer(var P: Pointer);
Allocates a buffer to the given pointer. The given pointer
becomes the master pointer to the allocated buffer and a
reference to the pointer's location is stored. The pointer will
be updated whenever the position of the buffer changes. The
buffer size is initially zero an can be adjusted by a call to
SetBufferSize. If a buffer is deallocated, or the size of a
buffer changes, the position of all the buffers allocated after
this one change. Each buffer has an overhead of 16 bytes (one
paragraph) which is used to store the size of the buffer and
the location of its master pointer.
procedure DisposeBuffer(P: Pointer);
Deallocates the buffer allocated to the given pointer. The memory
allocated can now be used by other buffers. This pointer must
point to a buffer allocated with a call to NewBuffer. Disposing
of a buffer will cause the master pointer of all buffers allocated
after this buffer to change.
function GetBufferSize(P: Pointer): Word;
Returns the size of the buffer allocated to this pointer. This
pointer must be a pointer allocated with NewBuffer.
function SetBufferSize(P: Pointer; Size: Word): Boolean;
Increases or decreases the size of the given buffer. This
pointer must have been allocated with NewBuffer. Changing the
size of a buffer will cause the master pointer of buffers
allocated after this one to change.

View File

@ -0,0 +1,95 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ CRT Interface Unit }
{ }
{ Copyright (C) 1987, 1990 Borland International }
{ }
{*******************************************************}
unit Crt;
{$D-,I-,S-}
interface
const
{ CRT modes }
BW40 = 0; { 40x25 B/W on Color Adapter }
CO40 = 1; { 40x25 Color on Color Adapter }
BW80 = 2; { 80x25 B/W on Color Adapter }
CO80 = 3; { 80x25 Color on Color Adapter }
Mono = 7; { 80x25 on Monochrome Adapter }
Font8x8 = 256; { Add-in for ROM font }
{ Mode constants for 3.0 compatibility }
C40 = CO40;
C80 = CO80;
{ Foreground and background color constants }
Black = 0;
Blue = 1;
Green = 2;
Cyan = 3;
Red = 4;
Magenta = 5;
Brown = 6;
LightGray = 7;
{ Foreground color constants }
DarkGray = 8;
LightBlue = 9;
LightGreen = 10;
LightCyan = 11;
LightRed = 12;
LightMagenta = 13;
Yellow = 14;
White = 15;
{ Add-in for blinking }
Blink = 128;
var
{ Interface variables }
CheckBreak: Boolean; { Enable Ctrl-Break }
CheckEOF: Boolean; { Enable Ctrl-Z }
DirectVideo: Boolean; { Enable direct video addressing }
CheckSnow: Boolean; { Enable snow filtering }
LastMode: Word; { Current text mode }
TextAttr: Byte; { Current text attribute }
WindMin: Word; { Window upper left coordinates }
WindMax: Word; { Window lower right coordinates }
{ Interface procedures }
procedure AssignCrt(var F: Text);
function KeyPressed: Boolean;
function ReadKey: Char;
procedure TextMode(Mode: Integer);
procedure Window(X1,Y1,X2,Y2: Byte);
procedure GotoXY(X,Y: Byte);
function WhereX: Byte;
function WhereY: Byte;
procedure ClrScr;
procedure ClrEol;
procedure InsLine;
procedure DelLine;
procedure TextColor(Color: Byte);
procedure TextBackground(Color: Byte);
procedure LowVideo;
procedure HighVideo;
procedure NormVideo;
procedure Delay(MS: Word);
procedure Sound(Hz: Word);
procedure NoSound;


View File

@ -0,0 +1,438 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Vision Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit Dialogs;
{$O+,F+,S-,X+}
interface
uses Objects, Drivers, Views;
const
{ Color palettes }
CDialog = #32#33#34#35#36#37#38#39#40#41#42#43#44#45#46#47 +
#48#49#50#51#52#53#54#55#56#57#58#59#60#61#62#63;
CStaticText = #6;
CLabel = #7#8#9#9;
CButton = #10#11#12#13#14#14#14#15;
CCluster = #16#17#18#18;
CInputLine = #19#19#20#21;
CHistory = #22#23;
CHistoryWindow = #19#19#21#24#25#19#20;
CHistoryViewer = #6#6#7#6#6;
{ TButton flags }
bfNormal = $00;
bfDefault = $01;
bfLeftJust = $02;
bfBroadcast = $04;
type
{ TDialog object }
{ Palette layout }
{ 1 = Frame passive }
{ 2 = Frame active }
{ 3 = Frame icon }
{ 4 = ScrollBar page area }
{ 5 = ScrollBar controls }
{ 6 = StaticText }
{ 7 = Label normal }
{ 8 = Label selected }
{ 9 = Label shortcut }
{ 10 = Button normal }
{ 11 = Button default }
{ 12 = Button selected }
{ 13 = Button disabled }
{ 14 = Button shortcut }
{ 15 = Button shadow }
{ 16 = Cluster normal }
{ 17 = Cluster selected }
{ 18 = Cluster shortcut }
{ 19 = InputLine normal text }
{ 20 = InputLine selected text }
{ 21 = InputLine arrows }
{ 22 = History arrow }
{ 23 = History sides }
{ 24 = HistoryWindow scrollbar page area }
{ 25 = HistoryWindow scrollbar controls }
{ 26 = ListViewer normal }
{ 27 = ListViewer focused }
{ 28 = ListViewer selected }
{ 29 = ListViewer divider }
{ 30 = InfoPane }
{ 31 = Reserved }
{ 32 = Reserved }
PDialog = ^TDialog;
TDialog = object(TWindow)
constructor Init(var Bounds: TRect; ATitle: TTitleStr);
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
function Valid(Command: Word): Boolean; virtual;
end;
{ TSItem }
PSItem = ^TSItem;
TSItem = record
Value: PString;
Next: PSItem;
end;
{ TInputLine object }
{ Palette layout }
{ 1 = Passive }
{ 2 = Active }
{ 3 = Selected }
{ 4 = Arrows }
PInputLine = ^TInputLine;
TInputLine = object(TView)
Data: PString;
MaxLen: Integer;
CurPos: Integer;
FirstPos: Integer;
SelStart: Integer;
SelEnd: Integer;
constructor Init(var Bounds: TRect; AMaxLen: Integer);
constructor Load(var S: TStream);
destructor Done; virtual;
function DataSize: Word; virtual;
procedure Draw; virtual;
procedure GetData(var Rec); virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure SelectAll(Enable: Boolean);
procedure SetData(var Rec); virtual;
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure Store(var S: TStream);
end;
{ TButton object }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Default text }
{ 3 = Selected text }
{ 4 = Disabled text }
{ 5 = Normal shortcut }
{ 6 = Default shortcut }
{ 7 = Selected shortcut }
{ 8 = Shadow }
PButton = ^TButton;
TButton = object(TView)
Title: PString;
Command: Word;
Flags: Byte;
AmDefault: Boolean;
constructor Init(var Bounds: TRect; ATitle: TTitleStr; ACommand: Word;
AFlags: Word);
constructor Load(var S: TStream);
destructor Done; virtual;
procedure Draw; virtual;
procedure DrawState(Down: Boolean);
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure MakeDefault(Enable: Boolean);
procedure Press; virtual;
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure Store(var S: TStream);
end;
{ TCluster }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Selected text }
{ 3 = Normal shortcut }
{ 4 = Selected shortcut }
PCluster = ^TCluster;
TCluster = object(TView)
Value: Word;
Sel: Integer;
Strings: TStringCollection;
constructor Init(var Bounds: TRect; AStrings: PSItem);
constructor Load(var S: TStream);
destructor Done; virtual;
function DataSize: Word; virtual;
procedure DrawBox(Icon: String; Marker: Char);
procedure GetData(var Rec); virtual;
function GetHelpCtx: Word; virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
function Mark(Item: Integer): Boolean; virtual;
procedure Press(Item: Integer); virtual;
procedure MovedTo(Item: Integer); virtual;
procedure SetData(var Rec); virtual;
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure Store(var S: TStream);
end;
{ TRadioButtons }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Selected text }
{ 3 = Normal shortcut }
{ 4 = Selected shortcut }
PRadioButtons = ^TRadioButtons;
TRadioButtons = object(TCluster)
procedure Draw; virtual;
function Mark(Item: Integer): Boolean; virtual;
procedure MovedTo(Item: Integer); virtual;
procedure Press(Item: Integer); virtual;
procedure SetData(var Rec); virtual;
end;
{ TCheckBoxes }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Selected text }
{ 3 = Normal shortcut }
{ 4 = Selected shortcut }
PCheckBoxes = ^TCheckBoxes;
TCheckBoxes = object(TCluster)
procedure Draw; virtual;
function Mark(Item: Integer): Boolean; virtual;
procedure Press(Item: Integer); virtual;
end;
{ TListBox }
{ Palette layout }
{ 1 = Active }
{ 2 = Inactive }
{ 3 = Focused }
{ 4 = Selected }
{ 5 = Divider }
PListBox = ^TListBox;
TListBox = object(TListViewer)
List: PCollection;
constructor Init(var Bounds: TRect; ANumCols: Word;
AScrollBar: PScrollBar);
constructor Load(var S: TStream);
function DataSize: Word; virtual;
procedure GetData(var Rec); virtual;
function GetText(Item: Integer; MaxLen: Integer): String; virtual;
procedure NewList(AList: PCollection); virtual;
procedure SetData(var Rec); virtual;
procedure Store(var S: TStream);
end;
{ TStaticText }
{ Palette layout }
{ 1 = Text }
PStaticText = ^TStaticText;
TStaticText = object(TView)
Text: PString;
constructor Init(var Bounds: TRect; AText: String);
constructor Load(var S: TStream);
destructor Done; virtual;
procedure Draw; virtual;
function GetPalette: PPalette; virtual;
procedure GetText(var S: String); virtual;
procedure Store(var S: TStream);
end;
{ TParamText }
{ Palette layout }
{ 1 = Text }
PParamText = ^TParamText;
TParamText = object(TStaticText)
ParamCount: Integer;
ParamList: Pointer;
constructor Init(var Bounds: TRect; AText: String;
AParamCount: Integer);
constructor Load(var S: TStream);
function DataSize: Word; virtual;
procedure GetText(var S: String); virtual;
procedure SetData(var Rec); virtual;
procedure Store(var S: TStream);
end;
{ TLabel }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Selected text }
{ 3 = Normal shortcut }
{ 4 = Selected shortcut }
PLabel = ^TLabel;
TLabel = object(TStaticText)
Link: PView;
Light: Boolean;
constructor Init(var Bounds: TRect; AText: String; ALink: PView);
constructor Load(var S: TStream);
procedure Draw; virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure Store(var S: TStream);
end;
{ THistoryViewer }
{ Palette layout }
{ 1 = Active }
{ 2 = Inactive }
{ 3 = Focused }
{ 4 = Selected }
{ 5 = Divider }
PHistoryViewer = ^THistoryViewer;
THistoryViewer = object(TListViewer)
HistoryId: Word;
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
AHistoryId: Word);
function GetPalette: PPalette; virtual;
function GetText(Item: Integer; MaxLen: Integer): String; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
function HistoryWidth: Integer;
end;
{ THistoryWindow }
{ Palette layout }
{ 1 = Frame passive }
{ 2 = Frame active }
{ 3 = Frame icon }
{ 4 = ScrollBar page area }
{ 5 = ScrollBar controls }
{ 6 = HistoryViewer normal text }
{ 7 = HistoryViewer selected text }
PHistoryWindow = ^THistoryWindow;
THistoryWindow = object(TWindow)
Viewer: PListViewer;
constructor Init(var Bounds: TRect; HistoryId: Word);
function GetPalette: PPalette; virtual;
function GetSelection: String; virtual;
procedure InitViewer(HistoryId: Word); virtual;
end;
{ THistory }
{ Palette layout }
{ 1 = Arrow }
{ 2 = Sides }
PHistory = ^THistory;
THistory = object(TView)
Link: PInputLine;
HistoryId: Word;
constructor Init(var Bounds: TRect; ALink: PInputLine; AHistoryId: Word);
constructor Load(var S: TStream);
procedure Draw; virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
function InitHistoryWindow(var Bounds: TRect): PHistoryWindow; virtual;
procedure Store(var S: TStream);
end;
{ SItem routines }
function NewSItem(Str: String; ANext: PSItem): PSItem;
{ Dialogs registration procedure }
procedure RegisterDialogs;
{ Stream Registration Records }
const
RDialog: TStreamRec = (
ObjType: 10;
VmtLink: Ofs(TypeOf(TDialog)^);
Load: @TDialog.Load;
Store: @TDialog.Store
);
RInputLine: TStreamRec = (
ObjType: 11;
VmtLink: Ofs(TypeOf(TInputLine)^);
Load: @TInputLine.Load;
Store: @TInputLine.Store
);
RButton: TStreamRec = (
ObjType: 12;
VmtLink: Ofs(TypeOf(TButton)^);
Load: @TButton.Load;
Store: @TButton.Store
);
RCluster: TStreamRec = (
ObjType: 13;
VmtLink: Ofs(TypeOf(TCluster)^);
Load: @TCluster.Load;
Store: @TCluster.Store
);
RRadioButtons: TStreamRec = (
ObjType: 14;
VmtLink: Ofs(TypeOf(TRadioButtons)^);
Load: @TRadioButtons.Load;
Store: @TRadioButtons.Store
);
RCheckBoxes: TStreamRec = (
ObjType: 15;
VmtLink: Ofs(TypeOf(TCheckBoxes)^);
Load: @TCheckBoxes.Load;
Store: @TCheckBoxes.Store
);
RListBox: TStreamRec = (
ObjType: 16;
VmtLink: Ofs(TypeOf(TListBox)^);
Load: @TListBox.Load;
Store: @TListBox.Store
);
RStaticText: TStreamRec = (
ObjType: 17;
VmtLink: Ofs(TypeOf(TStaticText)^);
Load: @TStaticText.Load;
Store: @TStaticText.Store
);
RLabel: TStreamRec = (
ObjType: 18;
VmtLink: Ofs(TypeOf(TLabel)^);
Load: @TLabel.Load;
Store: @TLabel.Store
);
RHistory: TStreamRec = (
ObjType: 19;
VmtLink: Ofs(TypeOf(THistory)^);
Load: @THistory.Load;
Store: @THistory.Store
);
RParamText: TStreamRec = (
ObjType: 20;
VmtLink: Ofs(TypeOf(TParamText)^);
Load: @TParamText.Load;
Store: @TParamText.Store
);
const
{ Dialog broadcast commands }
cmRecordHistory = 60;

View File

@ -0,0 +1,152 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ DOS Interface Unit }
{ }
{ Copyright (C) 1987, 1990 Borland International }
{ }
{*******************************************************}
unit Dos;
{$D-,I-,S-}
interface
const
{ Flags bit masks }
FCarry = $0001;
FParity = $0004;
FAuxiliary = $0010;
FZero = $0040;
FSign = $0080;
FOverflow = $0800;
{ File mode magic numbers }
fmClosed = $D7B0;
fmInput = $D7B1;
fmOutput = $D7B2;
fmInOut = $D7B3;
{ File attribute constants }
ReadOnly = $01;
Hidden = $02;
SysFile = $04;
VolumeID = $08;
Directory = $10;
Archive = $20;
AnyFile = $3F;
type
{ String types }
ComStr = string[127]; { Command line string }
PathStr = string[79]; { Full file path string }
DirStr = string[67]; { Drive and directory string }
NameStr = string[8]; { File name string }
ExtStr = string[4]; { File extension string }
{ Registers record used by Intr and MsDos }
Registers = record
case Integer of
0: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Word);
1: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
end;
{ Typed-file and untyped-file record }
FileRec = record
Handle: Word;
Mode: Word;
RecSize: Word;
Private: array[1..26] of Byte;
UserData: array[1..16] of Byte;
Name: array[0..79] of Char;
end;
{ Textfile record }
TextBuf = array[0..127] of Char;
TextRec = record
Handle: Word;
Mode: Word;
BufSize: Word;
Private: Word;
BufPos: Word;
BufEnd: Word;
BufPtr: ^TextBuf;
OpenFunc: Pointer;
InOutFunc: Pointer;
FlushFunc: Pointer;
CloseFunc: Pointer;
UserData: array[1..16] of Byte;
Name: array[0..79] of Char;
Buffer: TextBuf;
end;
{ Search record used by FindFirst and FindNext }
SearchRec = record
Fill: array[1..21] of Byte;
Attr: Byte;
Time: Longint;
Size: Longint;
Name: string[12];
end;
{ Date and time record used by PackTime and UnpackTime }
DateTime = record
Year,Month,Day,Hour,Min,Sec: Word;
end;
var
{ Error status variable }
DosError: Integer;
function DosVersion: Word;
procedure Intr(IntNo: Byte; var Regs: Registers);
procedure MsDos(var Regs: Registers);
procedure GetDate(var Year,Month,Day,DayOfWeek: Word);
procedure SetDate(Year,Month,Day: Word);
procedure GetTime(var Hour,Minute,Second,Sec100: Word);
procedure SetTime(Hour,Minute,Second,Sec100: Word);
procedure GetCBreak(var Break: Boolean);
procedure SetCBreak(Break: Boolean);
procedure GetVerify(var Verify: Boolean);
procedure SetVerify(Verify: Boolean);
function DiskFree(Drive: Byte): Longint;
function DiskSize(Drive: Byte): Longint;
procedure GetFAttr(var F; var Attr: Word);
procedure SetFAttr(var F; Attr: Word);
procedure GetFTime(var F; var Time: Longint);
procedure SetFTime(var F; Time: Longint);
procedure FindFirst(Path: PathStr; Attr: Word; var F: SearchRec);
procedure FindNext(var F: SearchRec);
procedure UnpackTime(P: Longint; var T: DateTime);
procedure PackTime(var T: DateTime; var P: Longint);
procedure GetIntVec(IntNo: Byte; var Vector: Pointer);
procedure SetIntVec(IntNo: Byte; Vector: Pointer);
procedure SwapVectors;
procedure Keep(ExitCode: Word);
procedure Exec(Path: PathStr; ComLine: ComStr);
function DosExitCode: Word;
function FSearch(Path: PathStr; DirList: String): PathStr;
function FExpand(Path: PathStr): PathStr;
procedure FSplit(Path: PathStr; var Dir: DirStr;
var Name: NameStr; var Ext: ExtStr);
function EnvCount: Integer;
function EnvStr(Index: Integer): String;
function GetEnv(EnvVar: String): String;


View File

@ -0,0 +1,235 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Vision Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit Drivers;
{$F+,S-}
interface
uses Objects;
{ ******** EVENT MANAGER ******** }
const
{ Event codes }
evMouseDown = $0001;
evMouseUp = $0002;
evMouseMove = $0004;
evMouseAuto = $0008;
evKeyDown = $0010;
evCommand = $0100;
evBroadcast = $0200;
{ Event masks }
evNothing = $0000;
evMouse = $000F;
evKeyboard = $0010;
evMessage = $FF00;
{ Extended key codes }
kbEsc = $011B; kbAltSpace = $0200; kbCtrlIns = $0400;
kbShiftIns = $0500; kbCtrlDel = $0600; kbShiftDel = $0700;
kbBack = $0E08; kbCtrlBack = $0E7F; kbShiftTab = $0F00;
kbTab = $0F09; kbAltQ = $1000; kbAltW = $1100;
kbAltE = $1200; kbAltR = $1300; kbAltT = $1400;
kbAltY = $1500; kbAltU = $1600; kbAltI = $1700;
kbAltO = $1800; kbAltP = $1900; kbCtrlEnter = $1C0A;
kbEnter = $1C0D; kbAltA = $1E00; kbAltS = $1F00;
kbAltD = $2000; kbAltF = $2100; kbAltG = $2200;
kbAltH = $2300; kbAltJ = $2400; kbAltK = $2500;
kbAltL = $2600; kbAltZ = $2C00; kbAltX = $2D00;
kbAltC = $2E00; kbAltV = $2F00; kbAltB = $3000;
kbAltN = $3100; kbAltM = $3200; kbF1 = $3B00;
kbF2 = $3C00; kbF3 = $3D00; kbF4 = $3E00;
kbF5 = $3F00; kbF6 = $4000; kbF7 = $4100;
kbF8 = $4200; kbF9 = $4300; kbF10 = $4400;
kbHome = $4700; kbUp = $4800; kbPgUp = $4900;
kbGrayMinus = $4A2D; kbLeft = $4B00; kbRight = $4D00;
kbGrayPlus = $4E2B; kbEnd = $4F00; kbDown = $5000;
kbPgDn = $5100; kbIns = $5200; kbDel = $5300;
kbShiftF1 = $5400; kbShiftF2 = $5500; kbShiftF3 = $5600;
kbShiftF4 = $5700; kbShiftF5 = $5800; kbShiftF6 = $5900;
kbShiftF7 = $5A00; kbShiftF8 = $5B00; kbShiftF9 = $5C00;
kbShiftF10 = $5D00; kbCtrlF1 = $5E00; kbCtrlF2 = $5F00;
kbCtrlF3 = $6000; kbCtrlF4 = $6100; kbCtrlF5 = $6200;
kbCtrlF6 = $6300; kbCtrlF7 = $6400; kbCtrlF8 = $6500;
kbCtrlF9 = $6600; kbCtrlF10 = $6700; kbAltF1 = $6800;
kbAltF2 = $6900; kbAltF3 = $6A00; kbAltF4 = $6B00;
kbAltF5 = $6C00; kbAltF6 = $6D00; kbAltF7 = $6E00;
kbAltF8 = $6F00; kbAltF9 = $7000; kbAltF10 = $7100;
kbCtrlPrtSc = $7200; kbCtrlLeft = $7300; kbCtrlRight = $7400;
kbCtrlEnd = $7500; kbCtrlPgDn = $7600; kbCtrlHome = $7700;
kbAlt1 = $7800; kbAlt2 = $7900; kbAlt3 = $7A00;
kbAlt4 = $7B00; kbAlt5 = $7C00; kbAlt6 = $7D00;
kbAlt7 = $7E00; kbAlt8 = $7F00; kbAlt9 = $8000;
kbAlt0 = $8100; kbAltMinus = $8200; kbAltEqual = $8300;
kbCtrlPgUp = $8400; kbNoKey = $0000;
{ Keyboard state and shift masks }
kbRightShift = $0001;
kbLeftShift = $0002;
kbCtrlShift = $0004;
kbAltShift = $0008;
kbScrollState = $0010;
kbNumState = $0020;
kbCapsState = $0040;
kbInsState = $0080;
{ Mouse button state masks }
mbLeftButton = $01;
mbRightButton = $02;
type
{ Event record }
PEvent = ^TEvent;
TEvent = record
What: Word;
case Word of
evNothing: ();
evMouse: (
Buttons: Byte;
Double: Boolean;
Where: TPoint);
evKeyDown: (
case Integer of
0: (KeyCode: Word);
1: (CharCode: Char;
ScanCode: Byte));
evMessage: (
Command: Word;
case Word of
0: (InfoPtr: Pointer);
1: (InfoLong: Longint);
2: (InfoWord: Word);
3: (InfoInt: Integer);
4: (InfoByte: Byte);
5: (InfoChar: Char));
end;
const
{ Initialized variables }
ButtonCount: Byte = 0;
MouseEvents: Boolean = False;
MouseReverse: Boolean = False;
DoubleDelay: Word = 8;
RepeatDelay: Word = 8;
var
{ Uninitialized variables }
MouseIntFlag: Byte;
MouseButtons: Byte;
MouseWhere: TPoint;
{ Event manager routines }
procedure InitEvents;
procedure DoneEvents;
procedure ShowMouse;
procedure HideMouse;
procedure GetMouseEvent(var Event: TEvent);
procedure GetKeyEvent(var Event: TEvent);
{ ******** SCREEN MANAGER ******** }
const
{ Screen modes }
smBW80 = $0002;
smCO80 = $0003;
smMono = $0007;
smFont8x8 = $0100;
const
{ Initialized variables }
StartupMode: Word = $FFFF;
var
{ Uninitialized variables }
ScreenMode: Word;
ScreenWidth: Byte;
ScreenHeight: Byte;
HiResScreen: Boolean;
CheckSnow: Boolean;
ScreenBuffer: Pointer;
CursorLines: Word;
{ Screen manager routines }
procedure InitVideo;
procedure DoneVideo;
procedure SetVideoMode(Mode: Word);
procedure ClearScreen;
{ ******** SYSTEM ERROR HANDLER ******** }
type
{ System error handler function type }
TSysErrorFunc = function(ErrorCode: Integer; Drive: Byte): Integer;
{ Default system error handler routine }
function SystemError(ErrorCode: Integer; Drive: Byte): Integer;
const
{ Initialized variables }
SysErrorFunc: TSysErrorFunc = SystemError;
SysColorAttr: Word = $4E4F;
SysMonoAttr: Word = $7070;
CtrlBreakHit: Boolean = False;
SaveCtrlBreak: Boolean = False;
SysErrActive: Boolean = False;
{ System error handler routines }
procedure InitSysError;
procedure DoneSysError;
{ ******** UTILITY ROUTINES ******** }
{ Keyboard support routines }
function GetAltChar(KeyCode: Word): Char;
function GetAltCode(Ch: Char): Word;
function CtrlToArrow(KeyCode: Word): Word;
{ String routines }
procedure FormatStr(var Result: String; Format: String; var Params);
procedure PrintStr(S: String);
{ Buffer move routines }
procedure MoveBuf(var Dest; var Source; Attr: Byte; Count: Word);
procedure MoveChar(var Dest; C: Char; Attr: Byte; Count: Word);
procedure MoveCStr(var Dest; Str: String; Attrs: Word);
procedure MoveStr(var Dest; Str: String; Attr: Byte);
function CStrLen(S: String): Integer;

View File

@ -0,0 +1,774 @@
EDITORS
-------
TEditor implements a small, fast 64K editor for use in Turbo
Vision applications. It features mouse support, undo, clipboard
cut, copy and paste, autoindent and overwrite modes, WordStar
key bindings, and search and replace. This editor can be used not
only for editing files, but as a multi-line memo field in dialogs
or forms.
The use of TEditor is demonstrated in TVEDIT.PAS for editing
files and TVFORM.PAS as a memo field. Both of these file can be
found in the \T6\TVDEMOS directory.
Object summary
--------------
TEditor
-------
TEditor is the base object for all editors. It implements most of
the editor's functionality. If a TEditor object is created, it
will allocate its buffer out of the heap with the given size. The
buffer will initially be empty.
TMemo
-----
TMemo is a descendant of TEditor that is intended to go into a
dialog or form. It supports GetData and SetData and allows the Tab
key to be processed by TDialog. It also has a different palette
than TEditor. GetData/SetData expect a record like the following,
TMemoRec = record
TextLen: Word;
TextData: array[1..MaxMemoLen] of Char;
end;
where MaxMemoLen is the BufSize value passed to TMemo. TMemo
allocates its buffer from the heap.
TFileEditor
-----------
TFileEditor edits the contents of a file, which it stores in memory
allocated from the Buffers unit. This allows several editors to share
the same memory pool. Instead of allocating 64k for each editor, you
can allocate, say, 128k for all your editors. If the first editor only
takes up 16k, it will leave 112k for other editors. The editor takes
only the memory it needs at the time out of the pool. An editor will
grow by 4k at a time whenever the "gap" shrinks to 0, and will shrink
by 4k at a time if the gap grows larger than 4K. See below for a
description of the "gap." See BUFFERS.DOC for further information on
dynamic buffers.
TEditWindow
-----------
TEditWindow is a window designed to hold a TFileEditor or the
clipboard. It will change its title to display the file name
being edited and will initialize scroll bars and an indicator for
the editor. If the name passed to TEditWindow is blank, it
assumes that you are initializing the clipboard.
TIndicator
----------
TIndicator is the line and column counter in the lower left
corner of the edit window. It is initialized by TEditWindow and
passed as the fourth parameter to a TEditor.
Key Bindings
------------
Keys are bound to many of the the familiar WordStar key bindings
used in the IDE. The only exceptions are the block commands. Since
TEditor does not use persistent blocks, the block commands are
simulated by copying the information to and from the clipboard.
For example, ^K^B will begin selecting text. ^K^K will copy the
text to the clipboard. ^K^C will paste the contents from the
clipboard to the editor. This simulates, quite closely, the
keystrokes to do the same thing using WordStar bindings.
The selection can be started by holding down the shift key with
any of the cursor movement commands instead of using the ^K
bindings.
These key bindings can be changed by overriding the ConvertEvent
method which translates the given key event to a command event.
Internals
---------
Buffer structure
----------------
TEditor implements a "buffer gap" editor. It stores the text in
two pieces. Any text before the cursor is stored at the beginning
of the buffer, and text after the cursor is stored at the end
of the buffer. The space between the text is called the "gap."
When a character is inserted into the editor it is inserted into
the gap. The editor supports undo by recording deleted text in the
gap and maintaining the the number of characters inserted and
deleted. When asked to perform an undo, the characters that were
inserted are deleted, the deleted characters are copied to the
beginning of the gap, and the cursor is positioned after the
formerly-deleted text.
To illustrate how the buffer operates, consider the following
diagram of an editor buffer after the characters
"abcdefghijkxxxopqrstuvwxyz" are inserted,
CurPtr
|
v<-- GapLen -->
===========================................
|abcdefghijkxxxopqrstuvwxyz |
===========================................
<-------- BufLen -------->
<---------------- BufSize -------------->
Buffer after text inserted
CurPtr records the position of the cursor, GapLen is the length
of the gap, and BufLen is the total number of characters in the
buffer. BufSize is the size of the buffer which is always the sum
of GapLen and BufLen. If the cursor is then moved to just after
the "xxx" characters, the buffer would look like,
CurPtr
|
v<-- GapLen -->
===============...............=============
|abcdefghijkxxx opqrstuvwxyz|
===============...............=============
BufLen = <------------> + <----------->
<--------------- BufSize --------------->
Buffer after cursor movement
Note that the gap is kept in front of the cursor. This allow for
quick insertion of characters without moving any text. If "xxx"
is deleted using the backspace key the characters are copied to
the bottom of the gap and the cursor is moved backwards. The
DelCount field records the number of characters deleted.
CurPtr
|
v<--- GapLen ---->
============..................=============
|abcdefghijk xxxopqrstuvwxyz|
============..................=============
<-> DelCount
BufLen = <------------> + <----------->
<--------------- BufSize --------------->
Buffer after "xxx" is deleted
When characters are inserted, the insertion count, InsCount, is
incremented to record how to many characters to delete with an
undo. If "lmn" are now typed, the buffer would look like this:
CurPtr
|
v<-- GapLen -->
===============...............=============
|abcdefghijklmn xxxopqrstuvwxyz|
===============...............=============
<-> InsCount <-> DelCount
BufLen = <------------> + <----------->
<--------------- BufSize --------------->
Buffer after "lmn" is inserted
InsCount records the number of characters inserted. If an undo is
now requested "lmn" are deleted and "xxx" are copied on top of them,
restoring the buffer to what it was before the edits.
CurPtr
|
v<-- GapLen -->
===============...............=============
|abcdefghijkxxx opqrstuvwxyz|
===============...............=============
BufLen = <------------> + <----------->
<--------------- BufSize --------------->
Buffer after undo
If the cursor is moved before the undo is performed, all undo
information is lost because the gap moves. Undo will only undo
operations done between cursor movements. As soon as the cursor
moves, the edits performed are considered "accepted." Note also
that undo takes space inside the buffer which could prevent the
user from inserting text. The space can be recovered by moving
the cursor.
Selection or block
------------------
The Selection or block mark is always either before or after the
cursor. If text is inserted into the editor, either through a key
press, or through InsertText, the contents of the selection are
replaced by the inserted text. If there is no selection, the text
is just inserted. The selection is marked by the fields SelStart
and SelEnd. The selection can be set by the call SetSelection,
which will also move the cursor.
Options
-------
TEditor provides several options, the state of which are stored in
Boolean fields. CanUndo indicates whether the editor records undo
information. Since undo takes space temporarily from inserts, you
might find it advantageous to disable undo. This is done
automatically for the clipboard. Overwrite indicates whether the
editor is in overwrite or insert mode. AutoIndent records whether
the editor will, when the Enter key is pressed, indent the cursor
to the column of the first non-space character of the previous
line. This is convenient if the editor is used to edit source
code.
Objects
-------
TEditor
-----------------------------------------------------------------
Fields
------
HScrollBar: PScrollBar;
Pointer to the horizontal scroll bar, nil if the scroll bar
does not exist.
VScrollBar: PScrollBar;
Pointer to the vertical scroll bar, nil if the scroll bar does
not exist.
Indicator: PIndicator;
Pointer to the indicator, nil if the indicator does not exist.
Buffer: PEditBuffer;
Pointer to the buffer used to hold the text.
BufSize: Word;
Size of Buffer.
BufLen: Word;
The amount of text currently in buffer.
GapLen: Word;
The size of the "gap" between the text before the cursor and
the text after the cursor. See above description of the "gap."
SelStart: Word;
Starting offset of the selection.
SelEnd: Word;
Ending offset of the selection.
CurPtr: Word;
Offset of the cursor.
CurPos: TPoint;
Line/Column location of the cursor in the file.
Delta: TPoint;
The top line and left most column shown in the view.
Limit: TPoint;
The maximum number of columns to display, and the number of lines
in the file. Records the limits of the scroll bars.
DelCount: Word;
Number of characters in the end of the gap that were deleted
from the text. Used to implement undo.
InsCount: Word;
Number of characters inserted into the text since the last
cursor movement. Used to implement undo.
IsValid: Boolean;
True if the view is valid. Used by the Valid method.
CanUndo: Boolean;
True if the editor is to support undo.
Modified: Boolean;
True if the buffer has been modified.
Selecting: Boolean;
True if the editor is in selecting mode (i.e., ^K^B has been
pressed).
Overwrite: Boolean;
True if in overwrite mode, otherwise the editor is in insert
mode.
AutoIndent: Boolean;
True if the editor is in autoindent mode.
Methods
-------
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
AIndicator: PIndicator; ABufSize: Word);
Creates a TEditor object with the given scroll bars and indicator,
and with a buffer of size ABufSize. Options are set to
sfSelectable and the EventMask additionally allows handling of
broadcast events. Any of AHScrollBar, AVScrollBar or
AIndicator can be nil if you do not want to use them.
constructor Load(var S: TStream);
Creates and initializes a TEditor object off the given stream.
It does not load the previous contents of the buffer, but
instead initializes the buffer to empty.
function BufChar(P: Word): Char;
Returns the P'th character in the file, factoring in the gap.
function BufPtr(P: Word): Word;
Returns the offset into Buffer of the P'th character in the
file, factoring in the gap.
procedure ChangeBounds(var Bounds: TRect); virtual;
Overridden to ensure the file stays within view if the parent
size changes.
procedure ConvertEvent(var Event: TEvent); virtual;
Converts key events into command events. Used to implement the
WordStar key-bindings. Override if you wish to change or
extend the default key-bindings.
function CursorVisible: Boolean;
Returns true if the cursor (or insertion point) is visible
within the view.
procedure DeleteSelect;
Deletes selection if one exists.
procedure DoneBuffer; virtual;
Called whenever the buffer should be disposed. By default it
calls FreeMem with Buffer and BufSize. It should be overridden
if you wish not to use the heap to store the buffer. This is
done in TFileEditor.
procedure Draw; virtual;
Overridden to draw the editor. This should not be overridden
by descendants of TEditor.
function GetPalette: PPalette; virtual;
Returns the Editor palette, CEditor. Override if you wish to
change the palette of the editor.
procedure HandleEvent(var Event: TEvent); virtual;
Provides the event handling for the editor. Override if you
wish to extend the commands the editor handles.
procedure InitBuffer; virtual;
Called whenever the buffer should be allocated. By default, an
editor will call GetMem with Buffer and BufSize. You should
override this method if you do not want the editor to allocate
the buffer from the heap.
function InsertBuffer(var P: PEditBuffer; Offset, Length: Word;
AllowUndo, SelectText: Boolean): Boolean;
This is the lowest-level text insertion method. It will
insert Length bytes of text from the given pointer to text into
the buffer from the given offset into the buffer, P. It will
optionally record undo information and select the text
inserted. This method need never be called directly, since it
is called from InsertFrom and InsertText. This method should
be used if the buffer to be copied from could move (e.g., P was
allocated using the Buffers unit).
function InsertFrom(Editor: PEditor): Boolean; virtual;
Insert the selection from the given editor into this editor.
This method is used to implement Cut, Copy, and Paste. It need
never be overridden by the user.
function InsertText(Text: Pointer; Length: Word;
SelectText: Boolean): Boolean;
Insert the given text of length Length into the buffer,
optionally selecting the text. This is an easier-to-use
version of InsertBuffer.
procedure ScrollTo(X, Y: Integer);
Move column X and line Y to the upper-left corner of the editor.
function Search(FindStr: String; Opts: Word): Boolean;
Search for the given string in the editor with the given
options. The options words are,
efCaseSensitive Case sensitive search
efWholeWordsOnly Find whole words only
function SetBufSize(NewSize: Word): Boolean; virtual;
Called whenever the buffer can be grown or shrunk to the given
value. It should return true if the the buffer can be of the
given size. By default, it returns true if NewSize is less than
or equal to the new size.
procedure SetCmdState(Command: Word; Enable: Boolean);
Disables or enables the given command. The command is always
disabled if the editor is not the selected view. Used as a
convenient way to enable and disable command instead of using
EnableCommands and DisableCommands.
procedure SetSelect(NewStart, NewEnd: Word; CurStart: Boolean);
Set the selection to the given offsets into the file. This
method will either place the cursor in front of behind the
selection pending on the value of CurStart.
procedure SetState(AState: Word; Enable: Boolean); virtual;
SetState is overridden to hide and show scroll bars and the
indicator and to enable and disable commands. If you wish to
enable and disable additional commands, override UpdateCommands
instead. This is called whenever the command states should be
updated.
procedure Store(var S: TStream);
Stores the editor on the given stream.
procedure TrackCursor(Center: Boolean);
Forces the cursor to be visible. If Center is True, the
cursor is forced to be in the center of the screen in the Y
access. The X, or column, is not changed.
procedure Undo;
Undo the changes since the last cursor movement.
procedure UpdateCommands; virtual;
Called whenever the commands should be updated. This is used
to enable and disable commands such as cmUndo, cmClip, cmCopy,
etc.
function Valid(Command: Word): Boolean; virtual;
Returns whether the view is valid given Command. By default it
returns the value of IsValid which is True if Buffer is non-nil.
TMemo
-----------------------------------------------------------------
Methods
-------
constructor Load(var S: TStream);
Creates and initializes a TMemo object off the given stream.
function DataSize: Word; virtual;
Returns the size of the data written by GetData and read by
SetData. By default it return SizeOf(Word) + BufSize.
procedure GetData(var Rec); virtual;
Writes the contents of the buffer into the given Rec.
function GetPalette: PPalette; virtual;
Returns a palette, CMemo, suitable for TMemo's use in a
TDialog.
procedure HandleEvent(var Event: TEvent); virtual;
Prevents TMemo from handling kbTab, otherwise handles events the
same as a TEditor.
procedure SetData(var Rec); virtual;
Read the contents of the buffer from the given Rec.
procedure Store(var S: TStream);
Store the TMemo to the given stream.
TFileEditor
-----------------------------------------------------------------
Fields
------
FileName: FNameStr;
Name of the file being edited.
Methods
-------
constructor Init(var Bounds: TRect;
AHScrollBar, AVScrollBar: PScrollBar;
AIndicator: PIndicator; AFileName: FNameStr);
Creates a TFileEditor object with the given scroll bars and
indicator and loads the contents of the given file. If the
file is not found or invalid an error message will be displayed
and the object's Valid method will return false. Options are
set to sfSelectable and the EventMask additionally allows
handling of broadcast events. Any of AHScrollBar, AVScrollBar
or AIndicator can be nil if you do not want them.
constructor Load(var S: TStream);
Creates and initializes a TFileEditor object off the given
stream. The file is reloaded into the editor and the cursor is
positioned back to the location it was when the Store was
performed. It is ideal for use with a "Desktop save" option.
procedure DoneBuffer; virtual;
Disposes of the buffer allocated from the Buffers unit.
procedure HandleEvent(var Event: TEvent); virtual;
Overridden to implement the cmSave and cmSaveAs commands.
procedure InitBuffer; virtual;
Allocates memory from the Buffers unit to use for the editor
buffer.
function LoadFile: Boolean;
Read the file from disk and check for errors. Sets IsValid to
False if the file was not loaded into the buffer.
function Save: Boolean;
Saves the file to disk. Returns false if the save failed or
was canceled. If EditorFlags has the efBackupFiles bit set, a
.BAK file is created. Will call SaveAs if the editor is
"Untitled."
function SaveAs: Boolean;
Saves the editor with a different name. The name is derived
from a dialog brought up using the EditorDialogs function
pointer. Returns True if the editor was saved, False otherwise
(i.e., the operation was canceled).
function SaveFile: Boolean;
Saves the file to disk. Returns False if the save failed. If
EditorFlags has the efBackupFiles bit set, a .BAK file is
created.
function SetBufSize(NewSize: Word): Boolean; virtual;
Overridden to grow and shrink the buffer with calls to the
Buffers unit. Will grow and shrink the buffer in 4k
increments.
procedure Store(var S: TStream);
Store the TFileEditor object on the given stream. The file
name, not the file contents, are stored on the stream.
procedure UpdateCommands; virtual;
Overridden to enable and disable the cmSave and cmSaveAs
commands. They are only valid if the selected view is an
editor, otherwise they should be disabled.
function Valid(Command: Word): Boolean; virtual;
Overridden to make sure the file is saved before the program
exits. Returns False if the user cancels the save.
TEditWindow
-----------------------------------------------------------------
Fields
------
Editor: PFileEditor;
Pointer to the editor object in the edit window.
constructor Init(var Bounds: TRect; FileName: FNameStr;
ANumber: Integer);
Creates a TEditWindow object that will edit the given file
name with window number ANumber. This method initializes a
TFileEditor with scroll bars and an indicator. If the file
name is a null string, it is assumed to be an untitled file. If
Editor is equal to the Clipboard variable, the editor is assumed
to be the clipboard.
constructor Load(var S: TStream);
Creates and initializes a TEditWindow off the given stream.
procedure Close; virtual;
Overridden to hide, instead of close, the window if the editor
is a clipboard.
function GetTitle(MaxSize: Integer): TTitleStr; virtual;
Returns the name of the file being edited by the editor or
'Clipboard' if the editor is the clipboard.
procedure HandleEvent(var Event: TEvent); virtual;
Handles cmUpdateTitle to redraw the frame of the window. Used
in SaveAs to change the title of the window if the file being
edited changes names.
procedure Store(var S: TStream);
Saves the TEditWindow object to the given stream.
TIndicator
-----------------------------------------------------------------
Fields
------
Location: TPoint;
Stores the location to display. Updated by a TEditor.
Modified: Boolean;
True if the associated TEditor has been modified. Displays a
special character if true.
Methods
-------
constructor Init(var Bounds: TRect);
Creates a TIndicator object.
procedure Draw; virtual;
Draws the indicator.
function GetPalette: PPalette; virtual;
Return the a pointer to CIndicator, the TIndicator default
palette.
procedure SetState(AState: Word; Enable: Boolean); virtual;
Draws the indicator in the frame dragging color if dragging.
procedure SetValue(ALocation: TPoint; AModified: Boolean);
Method called by TEditor to update the values to the fields of
a TIndicator.
Globals
-------
Variables
---------
WordChars: set of Char;
Set of characters that define a word. Used when handling the
cmWordLeft and cmWordRight commands. The default value is
['0'..'9', 'A'..'Z', '_', 'a'..'z'].
EditorDialog: TEditorDialog;
EditorDialog is a procedure variable that is used by TEditor
objects to display various dialogs. Since dialogs are very
application-dependent, EDITORS cannot display its own dialogs.
Instead it calls this function variable instead. For an
example of an EditorDialog function, see TVEDIT.PAS. The various
dialog values are
edOutOfMemory
edReadError
edWriteError
edCreateError
edSaveModify
edSaveUntitled
edSaveAs
edFind
edSearchFailed
edReplace
edReplacePrompt
EditorFlags: Word;
EditorFlags contains various flags for use in the editor. The
value of which are
efCaseSensitive Default to case sensitive search
efWholeWordsOnly Default to whole words only search
efPromptOnReplace Prompt on replace
efReplaceAll Replace all occurrences.
efDoReplace Do replace.
efBackupFiles Create .BAK files on saves.
The default value is efBackupFiles + efPromptOnReplace.
FindStr: String[80];
Stores the last value used for a find.
ReplaceStr: String[80];
Stores the last value of a replace.
Clipboard: PEditor = nil;
Pointer to the clipboard. Any TEditor can be the clipboard, it
just needs be assigned to this variable. The clipboard should
not support undo (i.e., its CanUndo should be false).
Procedures
----------
procedure RegisterEditors;
Register all object types in EDITORS.


View File

@ -0,0 +1,134 @@
======================================================================
Corrections & Additions
======================================================================
This documentation file chronicles corrections or additions to
the printed documentation. Make sure you look at other .DOC files
in the \TP\DOC directory, especially TVISION.DOC. Note that the
\TP\DOCDEMOS directory contains complete, correct versions of all
the examples in the Turbo Vision Guide and in Chapter 4 of the
User's Guide.
----------------------------------------------------------------------
Table of Contents
----------------------------------------------------------------------
1. User's Guide
2. Programmer's Guide
3. Library Reference
4. Turbo Vision Guide
----------------------------------------------------------------------
1. User's Guide
----------------
P-1 Far and near directives
----------------------------
Far and near directives can be placed after a procedure or
function declaration:
procedure MyProc; far;
function MyFunc: Boolean; near;
If MyProc and MyFunc are declared in the implementaton section of
a unit or in the body of the main program, they will be far and
near (respectively) regardless of the enabled or disabled state of
the {$F} compiler directive.
P-197 Stepping into conditional breakpoints
--------------------------------------------
An anomaly exists when the execution bar is above a conditional
breakpoint you've set and the condition is false. If you press F8
in this situation, the debugger will execute the statement with
the false conditional breakpoint without stopping. To have the
debugger stop before executing that statement, it is not necessary
to delete the conditional breakpoint. Instead, just position the
cursor on the line with the false conditional berakpoint and press
F4 (Run|Go to cursor).
2. Programmer's Guide
----------------------
P-153 Incorrect demo program name
----------------------------------
The correct name for the BGI demo program that shows how to link
font and driver files into an EXE is called BGILINK.PAS.
P-215 Free list
----------------
The second paragraph incorrectly implies that the free list starts
at the top of memory and grows downwards. The remaining text in
that chapter correctly explains that the free list is maintained
by using the first 8 bytes of each freed block.
P-328 Allows PUBLIC without external
-------------------------------------
Error message #51 will no longer occur if you link with an .OBJ
file that defines a PUBLIC for which there is no corresponding
external Pascal procedure. When the linker encounters an unmatched
PUBLIC in an .OBJ file, it simply creates a corresponding entry in
the symbol table that can be referenced by EXTERNs in other .OBJ
files.
3. Library Reference
---------------------
P-115 Incorrect demo program name
----------------------------------
The correct name for the BGI demo program that shows how to
link font and driver files into an EXE is called BGILINK.PAS.
2. Turbo Vision Guide
----------------------
P-29 Missing parameters
-------------------------
The first line of the bottom two examples should be just like
the topmost example on the page:
MenuBar := New(PMenuBar, Init(R, NewMenu(
...
P-54 Missing parameters
-------------------------
The example in the middle of the page is missing parameters in
the call to Assign. The correct syntax is:
R.Assign(22, 3, 34, 6);
P-157 Stream registration made easy
------------------------------------
Turbo Vision defines stream registration records for all its
objects. In addition, each Turbo Vision unit defines a
RegisterXXXX procedure that automatically registers all of the
unit's objects. Finally, to register all Turbo Vision objects,
just call TApplication.RegisterTypes. Note that this will link
in ALL Turbo Vision objects, regardless of whether you're using
them or not (that's why it's not done automatically). See
TVISION.DOC for more information about additional registration
procedures.
P-166 Incorrect method call
----------------------------
The Append call in the IF statement should be a call to Insert
as follows:
...
Insert(Desktop);
...
P-224 Wrong order
------------------
The TCollection.Free method descriptions has the calls in
reverse order. The correct order is:
Delete(Item);
FreeItem(Item);


View File

@ -0,0 +1,338 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Graph Interface Unit }
{ }
{ Copyright (C) 1987,90 Borland International }
{ }
{*******************************************************}
unit Graph;
interface
const
{ GraphResult error return codes: }
grOk = 0;
grNoInitGraph = -1;
grNotDetected = -2;
grFileNotFound = -3;
grInvalidDriver = -4;
grNoLoadMem = -5;
grNoScanMem = -6;
grNoFloodMem = -7;
grFontNotFound = -8;
grNoFontMem = -9;
grInvalidMode = -10;
grError = -11; { generic error }
grIOerror = -12;
grInvalidFont = -13;
grInvalidFontNum = -14;
{ define graphics drivers }
CurrentDriver = -128; { passed to GetModeRange }
Detect = 0; { requests autodetection }
CGA = 1;
MCGA = 2;
EGA = 3;
EGA64 = 4;
EGAMono = 5;
IBM8514 = 6;
HercMono = 7;
ATT400 = 8;
VGA = 9;
PC3270 = 10;
{ graphics modes for each driver }
CGAC0 = 0; { 320x200 palette 0: LightGreen, LightRed, Yellow; 1 page }
CGAC1 = 1; { 320x200 palette 1: LightCyan, LightMagenta, White; 1 page }
CGAC2 = 2; { 320x200 palette 2: Green, Red, Brown; 1 page }
CGAC3 = 3; { 320x200 palette 3: Cyan, Magenta, LightGray; 1 page }
CGAHi = 4; { 640x200 1 page }
MCGAC0 = 0; { 320x200 palette 0: LightGreen, LightRed, Yellow; 1 page }
MCGAC1 = 1; { 320x200 palette 1: LightCyan, LightMagenta, White; 1 page }
MCGAC2 = 2; { 320x200 palette 2: Green, Red, Brown; 1 page }
MCGAC3 = 3; { 320x200 palette 3: Cyan, Magenta, LightGray; 1 page }
MCGAMed = 4; { 640x200 1 page }
MCGAHi = 5; { 640x480 1 page }
EGALo = 0; { 640x200 16 color 4 page }
EGAHi = 1; { 640x350 16 color 2 page }
EGA64Lo = 0; { 640x200 16 color 1 page }
EGA64Hi = 1; { 640x350 4 color 1 page }
EGAMonoHi = 3; { 640x350 64K on card, 1 page; 256K on card, 2 page }
HercMonoHi = 0; { 720x348 2 page }
ATT400C0 = 0; { 320x200 palette 0: LightGreen, LightRed, Yellow; 1 page }
ATT400C1 = 1; { 320x200 palette 1: LightCyan, LightMagenta, White; 1 page }
ATT400C2 = 2; { 320x200 palette 2: Green, Red, Brown; 1 page }
ATT400C3 = 3; { 320x200 palette 3: Cyan, Magenta, LightGray; 1 page }
ATT400Med = 4; { 640x200 1 page }
ATT400Hi = 5; { 640x400 1 page }
VGALo = 0; { 640x200 16 color 4 page }
VGAMed = 1; { 640x350 16 color 2 page }
VGAHi = 2; { 640x480 16 color 1 page }
PC3270Hi = 0; { 720x350 1 page }
IBM8514LO = 0; { 640x480 256 colors }
IBM8514HI = 1; { 1024x768 256 colors }
{ Colors for SetPalette and SetAllPalette: }
Black = 0;
Blue = 1;
Green = 2;
Cyan = 3;
Red = 4;
Magenta = 5;
Brown = 6;
LightGray = 7;
DarkGray = 8;
LightBlue = 9;
LightGreen = 10;
LightCyan = 11;
LightRed = 12;
LightMagenta = 13;
Yellow = 14;
White = 15;
{ colors for 8514 to set standard EGA colors w/o knowing their values }
EGABlack = 0; { dark colors }
EGABlue = 1;
EGAGreen = 2;
EGACyan = 3;
EGARed = 4;
EGAMagenta = 5;
EGABrown = 20;
EGALightgray = 7;
EGADarkgray = 56; { light colors }
EGALightblue = 57;
EGALightgreen = 58;
EGALightcyan = 59;
EGALightred = 60;
EGALightmagenta = 61;
EGAYellow = 62;
EGAWhite = 63;
{ Line styles and widths for Get/SetLineStyle: }
SolidLn = 0;
DottedLn = 1;
CenterLn = 2;
DashedLn = 3;
UserBitLn = 4; { User-defined line style }
NormWidth = 1;
ThickWidth = 3;
{ Set/GetTextStyle constants: }
DefaultFont = 0; { 8x8 bit mapped font }
TriplexFont = 1; { "Stroked" fonts }
SmallFont = 2;
SansSerifFont = 3;
GothicFont = 4;
HorizDir = 0; { left to right }
VertDir = 1; { bottom to top }
UserCharSize = 0; { user-defined char size }
{ Clipping constants: }
ClipOn = true;
ClipOff = false;
{ Bar3D constants: }
TopOn = true;
TopOff = false;
{ Fill patterns for Get/SetFillStyle: }
EmptyFill = 0; { fills area in background color }
SolidFill = 1; { fills area in solid fill color }
LineFill = 2; { --- fill }
LtSlashFill = 3; { /// fill }
SlashFill = 4; { /// fill with thick lines }
BkSlashFill = 5; { \\\ fill with thick lines }
LtBkSlashFill = 6; { \\\ fill }
HatchFill = 7; { light hatch fill }
XHatchFill = 8; { heavy cross hatch fill }
InterleaveFill = 9; { interleaving line fill }
WideDotFill = 10; { Widely spaced dot fill }
CloseDotFill = 11; { Closely spaced dot fill }
UserFill = 12; { user defined fill }
{ BitBlt operators for PutImage: }
NormalPut = 0; { MOV } { left for 1.0 compatibility }
CopyPut = 0; { MOV }
XORPut = 1; { XOR }
OrPut = 2; { OR }
AndPut = 3; { AND }
NotPut = 4; { NOT }
{ Horizontal and vertical justification for SetTextJustify: }
LeftText = 0;
CenterText = 1;
RightText = 2;
BottomText = 0;
{ CenterText = 1; already defined above }
TopText = 2;
const
MaxColors = 15;
type
PaletteType = record
Size : byte;
Colors : array[0..MaxColors] of shortint;
end;
LineSettingsType = record
LineStyle : word;
Pattern : word;
Thickness : word;
end;
TextSettingsType = record
Font : word;
Direction : word;
CharSize : word;
Horiz : word;
Vert : word;
end;
FillSettingsType = record { Pre-defined fill style }
Pattern : word;
Color : word;
end;
FillPatternType = array[1..8] of byte; { User defined fill style }
PointType = record
X, Y : integer;
end;
ViewPortType = record
x1, y1, x2, y2 : integer;
Clip : boolean;
end;
ArcCoordsType = record
X, Y : integer;
Xstart, Ystart : integer;
Xend, Yend : integer;
end;
var
GraphGetMemPtr : Pointer; { allows user to steal heap allocation }
GraphFreeMemPtr : Pointer; { allows user to steal heap de-allocation }
{ *** high-level error handling *** }
function GraphErrorMsg(ErrorCode : integer) : String;
function GraphResult : integer;
{ *** detection, initialization and crt mode routines *** }
procedure DetectGraph(var GraphDriver, GraphMode : integer);
function GetDriverName : string;
procedure InitGraph(var GraphDriver : integer;
var GraphMode : integer;
PathToDriver : String);
function RegisterBGIfont(Font : pointer) : integer;
function RegisterBGIdriver(Driver : pointer) : integer;
function InstallUserDriver(DriverFileName : string;
AutoDetectPtr : pointer) : integer;
function InstallUserFont(FontFileName : string) : integer;
procedure SetGraphBufSize(BufSize : word);
function GetMaxMode : integer;
procedure GetModeRange(GraphDriver : integer; var LoMode, HiMode : integer);
function GetModeName(GraphMode : integer) : string;
procedure SetGraphMode(Mode : integer);
function GetGraphMode : integer;
procedure GraphDefaults;
procedure RestoreCrtMode;
procedure CloseGraph;
function GetX : integer;
function GetY : integer;
function GetMaxX : integer;
function GetMaxY : integer;
{ *** Screen, viewport, page routines *** }
procedure ClearDevice;
procedure SetViewPort(x1, y1, x2, y2 : integer; Clip : boolean);
procedure GetViewSettings(var ViewPort : ViewPortType);
procedure ClearViewPort;
procedure SetVisualPage(Page : word);
procedure SetActivePage(Page : word);
{ *** point-oriented routines *** }
procedure PutPixel(X, Y : integer; Pixel : word);
function GetPixel(X, Y : integer) : word;
{ *** line-oriented routines *** }
procedure SetWriteMode(WriteMode : integer);
procedure LineTo(X, Y : integer);
procedure LineRel(Dx, Dy : integer);
procedure MoveTo(X, Y : integer);
procedure MoveRel(Dx, Dy : integer);
procedure Line(x1, y1, x2, y2 : integer);
procedure GetLineSettings(var LineInfo : LineSettingsType);
procedure SetLineStyle(LineStyle : word;
Pattern : word;
Thickness : word);
{ *** polygon, fills and figures *** }
procedure Rectangle(x1, y1, x2, y2 : integer);
procedure Bar(x1, y1, x2, y2 : integer);
procedure Bar3D(x1, y1, x2, y2 : integer; Depth : word; Top : boolean);
procedure DrawPoly(NumPoints : word; var PolyPoints);
procedure FillPoly(NumPoints : word; var PolyPoints);
procedure GetFillSettings(var FillInfo : FillSettingsType);
procedure GetFillPattern(var FillPattern : FillPatternType);
procedure SetFillStyle(Pattern : word; Color : word);
procedure SetFillPattern(Pattern : FillPatternType; Color : word);
procedure FloodFill(X, Y : integer; Border : word);
{ *** arc, circle, and other curves *** }
procedure Arc(X, Y : integer; StAngle, EndAngle, Radius : word);
procedure GetArcCoords(var ArcCoords : ArcCoordsType);
procedure Circle(X, Y : integer; Radius : word);
procedure Ellipse(X, Y : integer;
StAngle, EndAngle : word;
XRadius, YRadius : word);
procedure FillEllipse(X, Y : integer;
XRadius, YRadius : word);
procedure GetAspectRatio(var Xasp, Yasp : word);
procedure SetAspectRatio(Xasp, Yasp : word);
procedure PieSlice(X, Y : integer; StAngle, EndAngle, Radius : word);
procedure Sector(X, Y : Integer;
StAngle, EndAngle,
XRadius, YRadius : word);
{ *** color and palette routines *** }
procedure SetBkColor(ColorNum : word);
procedure SetColor(Color : word);
function GetBkColor : word;
function GetColor : word;
procedure SetAllPalette(var Palette);
procedure SetPalette(ColorNum : word; Color : shortint);
procedure GetPalette(var Palette : PaletteType);
function GetPaletteSize : integer;
procedure GetDefaultPalette(var Palette : PaletteType);
function GetMaxColor : word;
procedure SetRGBPalette(ColorNum, RedValue, GreenValue, BlueValue : integer);
{ *** bit-image routines *** }
function ImageSize(x1, y1, x2, y2 : integer) : word;
procedure GetImage(x1, y1, x2, y2 : integer; var BitMap);
procedure PutImage(X, Y : integer; var BitMap; BitBlt : word);
{ *** text routines *** }
procedure GetTextSettings(var TextInfo : TextSettingsType);
procedure OutText(TextString : string);
procedure OutTextXY(X, Y : integer; TextString : string);
procedure SetTextJustify(Horiz, Vert : word);
procedure SetTextStyle(Font, Direction : word; CharSize : word);
procedure SetUserCharSize(MultX, DivX, MultY, DivY : word);
function TextHeight(TextString : string) : word;
function TextWidth(TextString : string) : word;


View File

@ -0,0 +1,341 @@
Turbo Pascal 6.0
----------------
This file contains answers to commonly asked questions. See the README
file for suggestions on where to get more help. If you're programming
with Turbo Vision, make sure you look at TVISION.DOC for additional
information.
Floppy use
----------
Turbo Pascal 6.0 requires a dual-floppy system (a hard disk is
recommended). If you're using 720 kbyte floppies (or more), you can
put TURBO.EXE and TURBO.TPL on the same disk. If you're using 360
kbyte floppies, you'll need to put TURBO.EXE on Drive B: and TURBO.TPL
on your boot disk. Boot and then type B:TURBO. You can store your
source files on the same disk with TURBO.TPL. You can use TPUMOVER to
make TURBO.TPL smaller by removing units you don't use.
If you use the INSTALL program, make sure your floppies are completely
empty (no system files or COMMAND.COM) before installing. After
running INSTALL, you can copy TURBO.TPL onto a boot disk.
Turbo Pascal's online help system (TURBO.HLP) requires about 700
kbytes of disk storage and cannot be used on a system equipped
only with 360 kbyte floppy drives.
Once you have used INSTALL to build your working diskettes, you
can manually UNZIP other Turbo Pascal components (e.g. BGI, Turbo
Vision or the demo programs) onto other floppy diskettes.
FreePtr and FreeMin
-------------------
These Turbo Pascal 5.x identifiers are no longer needed by the new
heap manager. Simply delete references to FreeMin from your code. If
you're using routines that use FreePtr to compress the heap or perform
other implementation-dependent operations on the heap, you'll need to
update these routines for use with the new heap manager. (If you just
need to lower the top of memory in order to do an Exec, you can call
the SetMemTop procedure from the Turbo Vision Memory unit.) See
Chapter 16 in the Programmer's Guide for more information about how
the new heap manager works.
HeapError
---------
If you are using a HeapError function, make sure it returns
as quickly as possible when passed a Size value of 0:
function HeapError(Size: Word): Integer; far;
begin
if Size > 0 then
begin
{ ... perform HeapError processing here ... }
end;
end;
In version 6.0, HeapError is called with a value of 0 whenever an
allocation moves the HeapPtr upwards.
Mouse Support
-------------
Turbo Pascal's IDE and Turbo Vision require a mouse driver compatible
with Microsoft driver 6.x or later.
286 Code Generation Notes
-------------------------
Programs compiled with {$G+} do not check the processor at runtime to
determine whether it is 286-compatible. Trying to execute 80286
instructions on an 8086 or an 8088 will lock up the computer.
Refer to TEST286.PAS in \TP\DEMOS for an example of how to check
for the presence of a 286-compatible chip at runtime.
$X+ Is Global
-------------
The {$X+} compiler directive is global, so it must appear in the
source code before any declarations or program statements. A $X
directive elsewhere will cause an "Invalid Compiler Directive" error.
Non-static Constuctor Calls
---------------------------
When making inherited constructor calls from inside a method, always
use the TypeName.ConstructorName syntax. This allows the compiler to
statically call the inherited constructor and will not change the
"identity" of the calling object:
Correct:
...
TObject.Init; { always specify type name }
...
WRONG:
...
Init; { may change calling object's "identity" }
...
DOS Critical Error Handling
---------------------------
The IDE and Turbo Vision both provide critical error handling. Due to
problems with some versions of DOS, however, you may need to press ESC
several types to successfully cancel an operation after a critical
error has occurred (e.g. DRIVE NOT READY).
Iterator Methods
----------------
The ForEach, FirstThat and LastThat all take a local (nested), far
procedure or function as a parameter. Refer to Chapter 7 in the Turbo
Vision Guide for details.
Note: never use ForEach to delete items from a collection. The act of
deleting an item moves subsequent items forward and will result in
items being skipped.
Editor Swap File
----------------
The IDE creates a swap file for its virtual editor with the naming
convention of TPxxxx.$$$. Never delete this file while the IDE is
running (e.g. while in a DOS shell). However, if you reboot your
system while the IDE is running, it is safe to delete the swap file
before re-loading the IDE.
Note that the swap file grows but never shrinks while the IDE is
running. If you're editing a large file on a drive without much disk
space available, place the swap file on another drive (ideally a RAM
disk; use the /S command-line option at startup). If there is no other
drive available, and you've done an unusual amount of editing of large
files, you can exit and re-load the IDE and thus reduce the swap file
down to a normal size.
Inline Assembler Notes
----------------------
The built-in assembler works differently than Turbo Assembler in the
following case. In TASM, there is no distinction between an array of
some types and a single variable of this type:
MyVar DW ?
MyArray DW 10 DUP(?)
.
.
MOV AX,MyVar
MOV AX,MyArray[BX]
Using TASM on the above example, the type of both "MyVar" and
"MyArray" is WORD, and either can be loaded into a word-sized
register without a type cast.
This is not the case with Turbo Pascal's built-in assembler. In
Pascal, an array is not the same as a single variable, and a type
cast is required when accessing an element of an array, as
illustrated below:
var
MyVar: Word;
MyArray: array[0..9] of Word;
.
.
asm
MOV AX,MyVar
MOV AX,MyArray[BX].Word
MOV AX,WORD PTR MyArray[BX]
end;
Turbo Pascal 6.0 and the Toolboxes
----------------------------------
With the exception of the Turbo Editor Toolbox, the 4.0 toolboxes
will compile with Turbo Pascal 6.0. The Turbo Editor Toolbox
needs the minor source code changes described below in order to
work with the new heap manager:
MicroStar
---------
In MSVARS.PAS:
1) On line 219 after "var"
Add "FreePtr: Pointer;"
2) On line 295 after "begin"
Add "FreePtr := Ptr(Seg(HeapEnd^) - $1000, 0);"
In INVOKE.PAS:
1) On line 18 after "Dos"
Add ", MsVars"
FirstEd
-------
In EDVARS.PAS:
1) On line 139
Add "FreePtr: Pointer;"
On line 207
Add "FreePtr := Ptr(Seg(HeapEnd^) - $1000, 0);"
In addition, an updated version of BINED.OBJ is required for use
with version 6.0 and is available on CompuServe.
************************************************
Tech Support's Ten Most Commonly Asked Questions
************************************************
1. How do you read and write a file inside a Turbo Pascal
program?
Here's a program that creates a text file and then reads it
back:
program FileDemo;
var
FileVar: Text;
InString, OutString: String;
begin
OutString := 'Write this to a text file';
Assign(FileVar, 'TEST.TXT');
Rewrite(FileVar); { Creates new text file }
Writeln(FileVar, OutString);
Close(FileVar);
Assign(FileVar, 'TEST.TXT');
Reset(FileVar); { Opens existing text file }
Readln(FileVar, InString);
Close(FileVar);
end.
2. What is the GRAPH.TPU file?
GRAPH.TPU is the BGI unit found in BGI.ZIP on your distribution
diskettes. The INSTALL program puts it in \TP\BGI by default.
3. How do you send a program's output to the printer?
program Print;
uses Printer;
begin
Writeln(Lst, 'Hello Printer');
end.
4. Why am I getting a "Unit file format error" when I compile my
program with the new Turbo Pascal compiler?
You are using a unit that has been compiled with an earlier
version of Turbo Pascal. Re-build all your programs with Turbo
Pascal 6.0 using the command-line compiler's /B switch or using
the IDE's Compile|Build command.
Contact third-party vendors for updated TPU's if you don't
have the source code.
5. How do you calculate X to the power of Y?
function Power(X, Y: Real): Real;
begin
Power := Exp(Y * Ln(X));
end.
6. How come my program runs fine in the IDE and locks when run
from the DOS prompt?
This usually happens when you have uninitialized variables (for
another possible reason, refer to the next question).
7. I think my program is trashing memory. Which statements are the
likely culprits?
Here are some of the most common causes for out-of-bounds memory
writes:
Problem Suggestion
------- ----------
Array index out of range Turn on range checking {$R+}.
Uninitialized variable Initialize it, of course.
Pointers out of bounds Make sure you're not using
unallocated pointers or pointers
to blocks that have been
disposed.
Move, FillChar, BlockRead These routines all write to
memory without regard for
Pascal's normal size- and
type-checking. Make sure you're
specifying the correct amount of
data to be moved, filled or
read.
Indexing beyond the size If you're using relaxed var string
of a string checking {$V-}, make sure you're
not writing past the end of a
string (and onto neighboring
data).
8. Why doesn't the Exec procedure run the program I specify?
Make sure you define a maximum heap size using a $M compiler
directive at the beginning of your program. Refer to EXECDEMO.PAS
in \TP\DEMOS.
In addition to omitting a $M compiler directive, two other common
are common errors can be diagnosed easily by looking at the
value of DosError after a call to Exec:
DosError Explanation
-------- -----------
2 File not found. Specify the full path and program
name. If you're trying to execute an internal DOS
command (like DIR), you need to Exec COMMAND.COM
(see the Exec example in online help and the Library
Reference).
8 Not enough memory available to Exec the specified
program. Lower the amount of heap your program is
using (see \TP\DEMOS\EXECDEMO.PAS).
9. What do I do if Turbo Pascal gives an "out of memory" error?
If you're running out of memory using the IDE, you have many
configuration options available. Refer to P-146 in the User's
Guide for a comprehensive checklist.
If you're using the command-line compiler and running out of
memory during a compilation, first try the appropriate
suggestions on P-146 in the User's Guide. If you're still running
out of memory during compilation, you should probably TPCX.EXE,
the extended memory compiler available with Turbo Pascal 6.0
Professional.
10. How come I don't get the results that I expect when I
compare and print real numbers?
Floating point, or real numbers, are an approximation and small
rounding errors will occur during calculations and
transformations between numeric types. For a complete discussion
of this topic, refer to the section on comparing reals in Chapter
14 in the Programmer's Guide.


View File

@ -0,0 +1,38 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Vision Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit HistList;
{$F+,O+,S-}
{****************************************************************************
History buffer structure:
Byte Byte String Byte Byte String
+-------------------------+-------------------------+--...--+
| 0 | Id | History string | 0 | Id | History string | |
+-------------------------+-------------------------+--...--+
***************************************************************************}
interface
const
HistoryBlock: Pointer = nil;
HistorySize: Word = 1024;
HistoryUsed: Word = 0;
procedure HistoryAdd(Id: Byte; var Str: String);
function HistoryCount(Id: Byte): Word;
function HistoryStr(Id: Byte; Index: Integer): String;
procedure ClearHistory;
procedure InitHistory;
procedure DoneHistory;

View File

@ -0,0 +1,28 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Vision Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit Memory;
{$F+,O+,S-}
interface
const
LowMemSize: Word = 4096 div 16;
MaxBufMem: Word = 65536 div 16;
procedure InitMemory;
procedure DoneMemory;
function LowMemory: Boolean;
function MemAlloc(Size: Word): Pointer;
function MemAllocSeg(Size: Word): Pointer;
procedure GetBufMem(var P: Pointer; Size: Word);
procedure FreeBufMem(P: Pointer);
procedure SetMemTop(MemTop: Pointer);

View File

@ -0,0 +1,206 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Vision Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit Menus;
{$F+,O+,S-}
interface
uses Objects, Drivers, Views;
const
{ Color palettes }
CMenuView = #2#3#4#5#6#7;
CStatusLine = #2#3#4#5#6#7;
type
{ TMenu types }
TMenuStr = string[31];
PMenu = ^TMenu;
PMenuItem = ^TMenuItem;
TMenuItem = record
Next: PMenuItem;
Name: PString;
Command: Word;
Disabled: Boolean;
KeyCode: Word;
HelpCtx: Word;
case Integer of
0: (Param: PString);
1: (SubMenu: PMenu);
end;
TMenu = record
Items: PMenuItem;
Default: PMenuItem;
end;
{ TMenuView object }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Disabled text }
{ 3 = Shortcut text }
{ 4 = Normal selection }
{ 5 = Disabled selection }
{ 6 = Shortcut selection }
PMenuView = ^TMenuView;
TMenuView = object(TView)
ParentMenu: PMenuView;
Menu: PMenu;
Current: PMenuItem;
constructor Init(var Bounds: TRect);
constructor Load(var S: TStream);
function Execute: Word; virtual;
function FindItem(Ch: Char): PMenuItem;
procedure GetItemRect(Item: PMenuItem; var R: TRect); virtual;
function GetHelpCtx: Word; virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
function HotKey(KeyCode: Word): PMenuItem;
function NewSubView(var Bounds: TRect; AMenu: PMenu;
AParentMenu: PMenuView): PMenuView; virtual;
procedure Store(var S: TStream);
end;
{ TMenuBar object }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Disabled text }
{ 3 = Shortcut text }
{ 4 = Normal selection }
{ 5 = Disabled selection }
{ 6 = Shortcut selection }
PMenuBar = ^TMenuBar;
TMenuBar = object(TMenuView)
constructor Init(var Bounds: TRect; AMenu: PMenu);
destructor Done; virtual;
procedure Draw; virtual;
procedure GetItemRect(Item: PMenuItem; var R: TRect); virtual;
end;
{ TMenuBox object }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Disabled text }
{ 3 = Shortcut text }
{ 4 = Normal selection }
{ 5 = Disabled selection }
{ 6 = Shortcut selection }
PMenuBox = ^TMenuBox;
TMenuBox = object(TMenuView)
constructor Init(var Bounds: TRect; AMenu: PMenu;
AParentMenu: PMenuView);
procedure Draw; virtual;
procedure GetItemRect(Item: PMenuItem; var R: TRect); virtual;
end;
{ TStatusItem }
PStatusItem = ^TStatusItem;
TStatusItem = record
Next: PStatusItem;
Text: PString;
KeyCode: Word;
Command: Word;
end;
{ TStatusDef }
PStatusDef = ^TStatusDef;
TStatusDef = record
Next: PStatusDef;
Min, Max: Word;
Items: PStatusItem;
end;
{ TStatusLine }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Disabled text }
{ 3 = Shortcut text }
{ 4 = Normal selection }
{ 5 = Disabled selection }
{ 6 = Shortcut selection }
PStatusLine = ^TStatusLine;
TStatusLine = object(TView)
Items: PStatusItem;
Defs: PStatusDef;
constructor Init(var Bounds: TRect; ADefs: PStatusDef);
constructor Load(var S: TStream);
destructor Done; virtual;
procedure Draw; virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
function Hint(AHelpCtx: Word): String; virtual;
procedure Store(var S: TStream);
procedure Update; virtual;
end;
{ TMenuItem routines }
function NewItem(Name, Param: TMenuStr; KeyCode: Word; Command: Word;
AHelpCtx: Word; Next: PMenuItem): PMenuItem;
function NewLine(Next: PMenuItem): PMenuItem;
function NewSubMenu(Name: TMenuStr; AHelpCtx: Word; SubMenu: PMenu;
Next: PMenuItem): PMenuItem;
{ TMenu routines }
function NewMenu(Items: PMenuItem): PMenu;
procedure DisposeMenu(Menu: PMenu);
{ TStatusLine routines }
function NewStatusDef(AMin, AMax: Word; AItems: PStatusItem;
ANext: PStatusDef): PStatusDef;
function NewStatusKey(AText: String; AKeyCode: Word; ACommand: Word;
ANext: PStatusItem): PStatusItem;
{ Menus registration procedure }
procedure RegisterMenus;
const
{ Stream registration records }
RMenuBar: TStreamRec = (
ObjType: 40;
VmtLink: Ofs(TypeOf(TMenuBar)^);
Load: @TMenuBar.Load;
Store: @TMenuBar.Store
);
RMenuBox: TStreamRec = (
ObjType: 41;
VmtLink: Ofs(TypeOf(TMenuBox)^);
Load: @TMenuBox.Load;
Store: @TMenuBox.Store
);
RStatusLine: TStreamRec = (
ObjType: 42;
VmtLink: Ofs(TypeOf(TStatusLine)^);
Load: @TStatusLine.Load;
Store: @TStatusLine.Store
);

View File

@ -0,0 +1,371 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Pascal Standard Objects Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit Objects;
{$F+,O+,S-}
interface
const
{ TStream access modes }
stCreate = $3C00; { Create new file }
stOpenRead = $3D00; { Read access only }
stOpenWrite = $3D01; { Write access only }
stOpen = $3D02; { Read and write access }
{ TStream error codes }
stOk = 0; { No error }
stError = -1; { Access error }
stInitError = -2; { Cannot initialize stream }
stReadError = -3; { Read beyond end of stream }
stWriteError = -4; { Cannot expand stream }
stGetError = -5; { Get of unregistered object type }
stPutError = -6; { Put of unregistered object type }
{ Maximum TCollection size }
MaxCollectionSize = 65520 div SizeOf(Pointer);
{ TCollection error codes }
coIndexError = -1; { Index out of range }
coOverflow = -2; { Overflow }
type
{ Type conversion records }
WordRec = record
Lo, Hi: Byte;
end;
LongRec = record
Lo, Hi: Word;
end;
PtrRec = record
Ofs, Seg: Word;
end;
{ String pointers }
PString = ^String;
PChar = ^Char;
{ General arrays }
PByteArray = ^TByteArray;
TByteArray = array[0..32767] of Byte;
PWordArray = ^TWordArray;
TWordArray = array[0..16383] of Word;
{ TObject base object }
PObject = ^TObject;
TObject = object
constructor Init;
procedure Free;
destructor Done; virtual;
end;
{ TStreamRec }
PStreamRec = ^TStreamRec;
TStreamRec = record
ObjType: Word;
VmtLink: Word;
Load: Pointer;
Store: Pointer;
Next: Word;
end;
{ TStream }
PStream = ^TStream;
TStream = object(TObject)
Status: Integer;
ErrorInfo: Integer;
procedure CopyFrom(var S: TStream; Count: Longint);
procedure Error(Code, Info: Integer); virtual;
procedure Flush; virtual;
function Get: PObject;
function GetPos: Longint; virtual;
function GetSize: Longint; virtual;
procedure Put(P: PObject);
procedure Read(var Buf; Count: Word); virtual;
function ReadStr: PString;
procedure Reset;
procedure Seek(Pos: Longint); virtual;
procedure Truncate; virtual;
procedure Write(var Buf; Count: Word); virtual;
procedure WriteStr(P: PString);
end;
{ DOS file name string }
FNameStr = string[79];
{ TDosStream }
PDosStream = ^TDosStream;
TDosStream = object(TStream)
Handle: Word;
constructor Init(FileName: FNameStr; Mode: Word);
destructor Done; virtual;
function GetPos: Longint; virtual;
function GetSize: Longint; virtual;
procedure Read(var Buf; Count: Word); virtual;
procedure Seek(Pos: Longint); virtual;
procedure Truncate; virtual;
procedure Write(var Buf; Count: Word); virtual;
end;
{ TBufStream }
PBufStream = ^TBufStream;
TBufStream = object(TDosStream)
Buffer: Pointer;
BufSize: Word;
BufPtr: Word;
BufEnd: Word;
constructor Init(FileName: FNameStr; Mode, Size: Word);
destructor Done; virtual;
procedure Flush; virtual;
function GetPos: Longint; virtual;
function GetSize: Longint; virtual;
procedure Read(var Buf; Count: Word); virtual;
procedure Seek(Pos: Longint); virtual;
procedure Truncate; virtual;
procedure Write(var Buf; Count: Word); virtual;
end;
{ TEmsStream }
PEmsStream = ^TEmsStream;
TEmsStream = object(TStream)
Handle: Word;
PageCount: Word;
Size: Longint;
Position: Longint;
constructor Init(MinSize, MaxSize: Longint);
destructor Done; virtual;
function GetPos: Longint; virtual;
function GetSize: Longint; virtual;
procedure Read(var Buf; Count: Word); virtual;
procedure Seek(Pos: Longint); virtual;
procedure Truncate; virtual;
procedure Write(var Buf; Count: Word); virtual;
end;
{ TCollection types }
PItemList = ^TItemList;
TItemList = array[0..MaxCollectionSize - 1] of Pointer;
{ TCollection object }
PCollection = ^TCollection;
TCollection = object(TObject)
Items: PItemList;
Count: Integer;
Limit: Integer;
Delta: Integer;
constructor Init(ALimit, ADelta: Integer);
constructor Load(var S: TStream);
destructor Done; virtual;
function At(Index: Integer): Pointer;
procedure AtDelete(Index: Integer);
procedure AtFree(Index: Integer);
procedure AtInsert(Index: Integer; Item: Pointer);
procedure AtPut(Index: Integer; Item: Pointer);
procedure Delete(Item: Pointer);
procedure DeleteAll;
procedure Error(Code, Info: Integer); virtual;
function FirstThat(Test: Pointer): Pointer;
procedure ForEach(Action: Pointer);
procedure Free(Item: Pointer);
procedure FreeAll;
procedure FreeItem(Item: Pointer); virtual;
function GetItem(var S: TStream): Pointer; virtual;
function IndexOf(Item: Pointer): Integer; virtual;
procedure Insert(Item: Pointer); virtual;
function LastThat(Test: Pointer): Pointer;
procedure Pack;
procedure PutItem(var S: TStream; Item: Pointer); virtual;
procedure SetLimit(ALimit: Integer); virtual;
procedure Store(var S: TStream);
end;
{ TSortedCollection object }
PSortedCollection = ^TSortedCollection;
TSortedCollection = object(TCollection)
Duplicates: Boolean;
constructor Load(var S: TStream);
function Compare(Key1, Key2: Pointer): Integer; virtual;
function IndexOf(Item: Pointer): Integer; virtual;
procedure Insert(Item: Pointer); virtual;
function KeyOf(Item: Pointer): Pointer; virtual;
function Search(Key: Pointer; var Index: Integer): Boolean; virtual;
procedure Store(var S: TStream);
end;
{ TStringCollection object }
PStringCollection = ^TStringCollection;
TStringCollection = object(TSortedCollection)
function Compare(Key1, Key2: Pointer): Integer; virtual;
procedure FreeItem(Item: Pointer); virtual;
function GetItem(var S: TStream): Pointer; virtual;
procedure PutItem(var S: TStream; Item: Pointer); virtual;
end;
{ TResourceCollection object }
PResourceCollection = ^TResourceCollection;
TResourceCollection = object(TStringCollection)
procedure FreeItem(Item: Pointer); virtual;
function GetItem(var S: TStream): Pointer; virtual;
function KeyOf(Item: Pointer): Pointer; virtual;
procedure PutItem(var S: TStream; Item: Pointer); virtual;
end;
{ TResourceFile object }
PResourceFile = ^TResourceFile;
TResourceFile = object(TObject)
Stream: PStream;
Modified: Boolean;
constructor Init(AStream: PStream);
destructor Done; virtual;
function Count: Integer;
procedure Delete(Key: String);
procedure Flush;
function Get(Key: String): PObject;
function KeyAt(I: Integer): String;
procedure Put(Item: PObject; Key: String);
function SwitchTo(AStream: PStream; Pack: Boolean): PStream;
end;
{ TStringList object }
TStrIndexRec = record
Key, Count, Offset: Word;
end;
PStrIndex = ^TStrIndex;
TStrIndex = array[0..9999] of TStrIndexRec;
PStringList = ^TStringList;
TStringList = object(TObject)
constructor Load(var S: TStream);
destructor Done; virtual;
function Get(Key: Word): String;
end;
{ TStrListMaker object }
PStrListMaker = ^TStrListMaker;
TStrListMaker = object(TObject)
constructor Init(AStrSize, AIndexSize: Word);
destructor Done; virtual;
procedure Put(Key: Word; S: String);
procedure Store(var S: TStream);
end;
{ TPoint object }
TPoint = object
X, Y: Integer;
end;
{ Rectangle object }
TRect = object
A, B: TPoint;
procedure Assign(XA, YA, XB, YB: Integer);
procedure Copy(R: TRect);
procedure Move(ADX, ADY: Integer);
procedure Grow(ADX, ADY: Integer);
procedure Intersect(R: TRect);
procedure Union(R: TRect);
function Contains(P: TPoint): Boolean;
function Equals(R: TRect): Boolean;
function Empty: Boolean;
end;
{ Dynamic string handling routines }
function NewStr(S: String): PString;
procedure DisposeStr(P: PString);
{ Longint routines }
function LongMul(X, Y: Integer): Longint;
inline($5A/$58/$F7/$EA);
function LongDiv(X: Longint; Y: Integer): Integer;
inline($59/$58/$5A/$F7/$F9);
{ Stream routines }
procedure RegisterType(var S: TStreamRec);
{ Abstract notification procedure }
procedure Abstract;
{ Objects registration procedure }
procedure RegisterObjects;
const
{ Stream error procedure }
StreamError: Pointer = nil;
{ EMS stream state variables }
EmsCurHandle: Word = $FFFF;
EmsCurPage: Word = $FFFF;
const
{ Stream registration records }
RCollection: TStreamRec = (
ObjType: 50;
VmtLink: Ofs(TypeOf(TCollection)^);
Load: @TCollection.Load;
Store: @TCollection.Store);
RStringCollection: TStreamRec = (
ObjType: 51;
VmtLink: Ofs(TypeOf(TStringCollection)^);
Load: @TStringCollection.Load;
Store: @TStringCollection.Store);
RStringList: TStreamRec = (
ObjType: 52;
VmtLink: Ofs(TypeOf(TStringList)^);
Load: @TStringList.Load;
Store: nil);
RStrListMaker: TStreamRec = (
ObjType: 52;
VmtLink: Ofs(TypeOf(TStrListMaker)^);
Load: nil;
Store: @TStrListMaker.Store);

View File

@ -0,0 +1,47 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Overlay Interface Unit }
{ }
{ Copyright (C) 1987, 1990 Borland International }
{ }
{*******************************************************}
unit Overlay;
{$D-,I-,S-}
interface
const
ovrOk = 0;
ovrError = -1;
ovrNotFound = -2;
ovrNoMemory = -3;
ovrIOError = -4;
ovrNoEMSDriver = -5;
ovrNoEMSMemory = -6;
const
OvrResult: Integer = 0;
OvrTrapCount: Word = 0;
OvrLoadCount: Word = 0;
OvrFileMode: Byte = 0;
type
OvrReadFunc = function(OvrSeg: Word): Integer;
var
OvrReadBuf: OvrReadFunc;
procedure OvrInit(FileName: String);
procedure OvrInitEMS;
procedure OvrSetBuf(Size: LongInt);
function OvrGetBuf: LongInt;
procedure OvrSetRetry(Size: LongInt);
function OvrGetRetry: LongInt;
procedure OvrClearBuf;
implementation


View File

@ -0,0 +1,19 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Printer Interface Unit }
{ }
{ Copyright (C) 1987, 1990 Borland International }
{ }
{*******************************************************}
unit Printer;
{$D-,I-,S-}
interface
var
Lst: Text;


View File

@ -0,0 +1,65 @@
{*******************************************************}
{ }
{ Turbo Pascal Runtime Library Version 6.0 }
{ System Unit }
{ }
{ Copyright (C) 1988,90 Borland International }
{ }
{*******************************************************}
unit System;
interface
const
OvrCodeList: Word = 0; { Overlay code segment list }
OvrHeapSize: Word = 0; { Initial overlay buffer size }
OvrDebugPtr: Pointer = nil; { Overlay debugger hook }
OvrHeapOrg: Word = 0; { Overlay buffer origin }
OvrHeapPtr: Word = 0; { Overlay buffer pointer }
OvrHeapEnd: Word = 0; { Overlay buffer end }
OvrLoadList: Word = 0; { Loaded overlays list }
OvrDosHandle: Word = 0; { Overlay DOS handle }
OvrEmsHandle: Word = 0; { Overlay EMS handle }
HeapOrg: Pointer = nil; { Heap origin }
HeapPtr: Pointer = nil; { Heap pointer }
HeapEnd: Pointer = nil; { Heap end }
FreeList: Pointer = nil; { Free list pointer }
FreeZero: Pointer = nil; { Must be zero }
HeapError: Pointer = nil; { Heap error function }
ExitProc: Pointer = nil; { Exit procedure }
ExitCode: Integer = 0; { Exit code }
ErrorAddr: Pointer = nil; { Runtime error address }
PrefixSeg: Word = 0; { Program segment prefix }
StackLimit: Word = 0; { Stack pointer low limit }
InOutRes: Integer = 0; { I/O result buffer }
RandSeed: Longint = 0; { Random seed }
FileMode: Byte = 2; { File open mode }
Test8087: Byte = 0; { 8087 test result }
var
Input: Text; { Input standard file }
Output: Text; { Output standard file }
SaveInt00: Pointer; { Saved interrupt $00 }
SaveInt02: Pointer; { Saved interrupt $02 }
SaveInt1B: Pointer; { Saved interrupt $1B }
SaveInt21: Pointer; { Saved interrupt $21 }
SaveInt23: Pointer; { Saved interrupt $23 }
SaveInt24: Pointer; { Saved interrupt $24 }
SaveInt34: Pointer; { Saved interrupt $34 }
SaveInt35: Pointer; { Saved interrupt $35 }
SaveInt36: Pointer; { Saved interrupt $36 }
SaveInt37: Pointer; { Saved interrupt $37 }
SaveInt38: Pointer; { Saved interrupt $38 }
SaveInt39: Pointer; { Saved interrupt $39 }
SaveInt3A: Pointer; { Saved interrupt $3A }
SaveInt3B: Pointer; { Saved interrupt $3B }
SaveInt3C: Pointer; { Saved interrupt $3C }
SaveInt3D: Pointer; { Saved interrupt $3D }
SaveInt3E: Pointer; { Saved interrupt $3E }
SaveInt3F: Pointer; { Saved interrupt $3F }
SaveInt75: Pointer; { Saved interrupt $75 }
implementation


View File

@ -0,0 +1,941 @@
======================================================================
Using the Turbo Editor Macro Compiler
======================================================================
----------------------------------------------------------------------
Table of Contents
----------------------------------------------------------------------
1. Operation
2. Editor macro language syntax
3. Example scripts
MakeFuncText
MakeStub
4. Built-in commands
Functional index
Block macros
Deletion/insertion
Search macros
Hot key macros
Screen movement
System macros
Alphabetical reference
5. Error messages
6. Warning message
----------------------------------------------------------------------
The Turbo Editor Macro Language (TEML) is a powerful utility that
you can use to enhance or change the IDE's editor. Using the
140-odd built-in macros, you can define new ones that perform
sophisticated editing tasks and that can bind keystrokes to these
tasks.
NOTE: SetReturnCode macros are designated with an asterisk (*).
These special macros terminate the macro and give a return code.
It is an error to specify a command following a SetReturnCode
macro.
==============
1. Operation
==============
In order to use TEML, you first write a macro script in a text
editor. You then compile the script using the Turbo Editor Macro
Compiler (TEMC). The compiled file is used as a configuration
file in Turbo Pascal's IDE.
The Turbo Editor Macro Compiler expects as input an ASCII file
containing definitions and binding conforming to the TEML
specification. The output is placed in a configuration file
that can be used by the Integrated Development Environment.
The changes from TEMC are incremental; this means that if you
just change the definition of one key, only that key will be
changed in the configuration file. Everything else will stay
as it was.
Here is the syntax for the TEMC utility:
TEMC scriptfile outputconfigfile
You can use any text editor (including Turbo Pascal's) to create
the ASCII scriptfile. You use the outputconfigfile by naming it
TPCONFIG.TP and placing it in the directory you will be in when
starting TURBO.EXE.
=================================
2. Editor macro language syntax
=================================
TEML has a simple syntax based on Pascal and C. Here are the
basic syntax rules of the macro language:
o Statements in a script file are separated with a semicolon.
o Reserved words in TEML are:
ALT BEGIN
CTRL END
MACRO SCRIPT
SHIFT
o Comments are designated in the C style between /* and */ marks.
o In strings, the user can place any legal C backslash (\)
sequence; for example, "\xD".
The rest of this section describes how each possible component of
the syntax fits into the overall scheme. In this list, the symbol
::= means that the object on the left side is composed of the
objects on the right side. If the list of objects on the right
side of the ::= begins with the | symbol, then the object on the
left can be composed of nothing or one of the listed items.
Script: ::= ScriptName ScriptItems
ScriptName ::= |
SCRIPTIdentifier ;
ScriptItems ::= |
ScriptItems ScriptItem
ScriptItem ::= KeyAssignment | MacroDefinition
KeyAssignment ::= KeySequence : Command ;
KeySequence ::= KeySpecifier|KeySequence +
KeySpecifier|KeySequence + ^ KeySpecifier
KeySpecifier ::= Key | KeyModifier Key
Key ::= Number | Identifier | END
KeyModifier ::= | CTRL - | ALT - | SHIFT -
Command ::= BEGIN CommandList OptSemicolon END|
MacroCommand
CommandList ::= Command |
CommandList ; Command
MacroCommand ::= CommandName |
CommandName (ParamList)
CommandName ::= Identifier
ParamList ::= Param |
ParamList , Param
Param ::= Number | String
MacroDefinition ::= MACRO CommandName CommandList
OptSemicolon END ;
OptSemicolon ::= | ;
Number ::= Digit | Number Digit
Digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Identifier ::= Letter | Identifier LetterDigit
Letter ::= A to Z | a to z | _
LetterDigit ::= Letter | Digit
String ::= " AnyCharacterNotQuote "
====================
3. Example scripts
====================
This example sets up a host of WordStar-like keyboard shortcuts.
Script WordStar;
Macro NewLine
RightOfLine;
InsertText("\xD");
End;
/* Key Assignments */
Ctrl-A : WordLeft;
Ctrl-C : PageDown;
Ctrl-D : CursorCharRight;
Ctrl-E : CursorUp;
Ctrl-F : WordRight;
Ctrl-G : DeleteChar;
Ctrl-H : BackSpaceDelete;
Ctrl-J : CursorDown;
Ctrl-K+^B : SetBlockBeg;
Ctrl-K+^C : CopyBlock;
Ctrl-K+^H : ToggleHideBlock;
Ctrl-K+^K : SetBlockEnd;
Ctrl-K+^Q : Exit;
Ctrl-K+^R : ReadBlock;
Ctrl-K+^V : MoveBlock;
Ctrl-K+^W : WriteBlock;
Ctrl-K+^Y : DeleteBlock;
Ctrl-K+1 : SetMark(1);
Ctrl-K+2 : SetMark(2);
Ctrl-K+3 : SetMark(3);
Ctrl-L : RepeatSearch;
Ctrl-N : BreakLine;
Ctrl-O : NewLine; /* This is not a WordStar keystroke */
Ctrl-P : LiteralChar;
Ctrl-Q+^A : Replace;
Ctrl-Q+^B : MoveToBlockBeg;
Ctrl-Q+^C : EndCursor;
Ctrl-Q+^D : RightOfLine;
Ctrl-Q+^E : TopOfScreen;
Ctrl-Q+^F : GetFindString;
Ctrl-Q+^K : MoveToBlockEnd;
Ctrl-Q+^P : MoveToPrevPos;
Ctrl-Q+^R : HomeCursor;
Ctrl-Q+^S : LeftOfLine;
Ctrl-Q+^X : BottomOfScreen;
Ctrl-Q+^Y : DeleteToEol;
Ctrl-Q+1 : begin
MoveToMark(1);
CenterFixScreenPos;
end;
Ctrl-Q+2 : begin
MoveToMark(2);
CenterFixScreenPos;
end;
Ctrl-Q+3 : begin
MoveToMark(3);
CenterFixScreenPos;
end;
Ctrl-R : PageUp;
Ctrl-S : CursorCharLeft;
Ctrl-T : DeleteWord;
Ctrl-V : ToggleInsert;
Ctrl-W : ScrollDown;
Ctrl-X : CursorDown;
Ctrl-Y : DeleteLine;
Ctrl-Z : ScrollUp;
Home : LeftOfLine;
UpAr : CursorUp;
PgUp : PageUp;
LfAr : CursorCharLeft;
RgAr : CursorCharRight;
End : RightOfLine;
DnAr : CursorDown;
PgDn : PageDown;
Ins : ToggleInsert;
Ctrl-End : BottomOfScreen;
Ctrl-PgDn : EndCursor;
Ctrl-Home : TopOfScreen;
Ctrl-PgUp : HomeCursor;
MakeFuncText
==============
MakeFuncText creates a commented area for descriptive text
associated with a function, assumes the cursor is positioned
immediately after the name, and the name is at the left of the
screen.
Script util;
macro MakeFuncText
InsertText("\n\n"); /* add some whitespace */
CursorUp;
CursorUp;
LeftOfLine; /* go before beginning of
intended function name */
SetBlockBeg; /* mark function name */
WordRight;
SetBlockEnd;
LeftOfLine;
CursorDown;
CopyBlockRaw; /* copy for prototyping */
CursorUp;
LeftOfLine;
InsertText("\nFunction "); /* add "Function" to comment |area*/
RightOfLine;
InsertText(":"); /* .. and colon at end */
CursorUp; /* put in comment lines fore and |aft */
LeftOfLine; /* add comment divider lines */
InsertText("{*********");
InsertText("*********");
CursorDown;
RightOfLine;
InsertText("\n");
InsertText("\tDescription:\n");
InsertText("**********");
InsertText("*********}\n");
CursorDown; /* go back to end of name */
RightOfLine;
end; /* MakeFuncText */
Alt-T : MakeFuncText;
======================
3. Built-in commands
======================
The names of the built-in commands describe their actions.
Commands with the word screen in them generally only affect the
screen.
Commands that have the word raw in them perform fewer housekeeping
tasks than their "raw-less" counterparts. For example, in a long
macro, using raw commands saves time in that they don't constantly
update the screen display to reflect each change in cursor
position. However, you would only use the raw macros as
intermediate steps in combination with other macros.
Macro names are not case-sensitive. A few macros require
parameters in parentheses, as discussed in the descriptions.
Remember, you can use these primitive macros to build more
complicated ones.
Functional index
==================
This section lists the built-in macros by function. The following
section is a straight alphabetical list.
Block macros
--------------
These macros affect blocks of text.
You should use SetPrevPos or FixScreenPos, or both, at the end of
the raw macros for housekeeping purposes.
CopyBlock MoveToBlockEnd
DeleteBlock MoveToBlockEndRaw
DeleteBlockRaw *ReadBlock
HighlightBlock SetBlockBeg
MoveBlock SetBlockEnd
MoveToBlockBeg ToggleHideBlock
MoveToBlockBegRaw *WriteBlock
Deletion/insertion
--------------------
These macros delete, undelete, and insert text.
BackspaceDelete DeleteToEOL
ClipClear DeleteChar
ClipCopy DeleteWord
ClipCut EditMenu
ClipPaste InsertText
ClipShow LiteralChar
DeleteBlock RestoreLine
DeleteBlockRaw SetInsertMode
DeleteLine ToggleInsert
Search macro
--------------
These macros deal with searching.
GetFindString RepeatSearch
MatchPairForward Replace
MatchPairBackward SearchMenu
Hot key macros
----------------
These macros duplicate the hot keys in the Integrated
Development Environment.
*AddWatch *ResetProgram
*CloseWindow *RunProgram
*CompileFile *RunToHere
*Help *SaveFile
*LastHelp *SetBreakpoint
*Menu *Step
*Modify *Trace
*NextWindow *ZoomWindow
*OpenFile
Screen movement
-----------------
These macros control cursor movement and screen movement.
BottomOfScreen MoveToPrevPos
BottomOfScreenRaw PageDown
CenterFixScreenPos PageUp
CursorCharLeft PageScreenDown
CursorCharRight PageScreenUp
CursorDown RightOfLine
CursorLeft ScrollDown
CursorRight ScrollUp
CursorUp ScrollScreenDown
EndCursor ScrollScreenUp
EndCursorRaw SetMark
FixCursorPos SetPrevPos
FixScreenPos SwapPrevPos
HomeCursor TopOfScreen
HomeCursorRaw TopOfScreenRaw
LeftOfLine WordLeft
MoveToMark WordRight
System macros
---------------
These macros affect certain system functions.
*Exit *Quit
FullPaintScreen SmartRefreshScreen
PaintScreen
Alphabetical reference
========================
This section is an alphabetical list of all the built-in macros. If
you need to see how the macros are grouped by function, refer to
the preceding section.
AddWatch - This macro is the same as pressing Ctrl-F7 or
Debug|Watches|Add Watch.
BackspaceDelete - Moves the cursor back one character and deletes
it (typically defined to be Backspace).
BottomOfScreen - Moves the cursor position to the lower left
corner of the screen. This macro automatically sets the starting
cursor position so that you can go back there with the
MoveToPrevPos macro.
BottomOfScreenRaw - Moves the cursor to the lower left corner of
the screen. As opposed to the BottomOfScreen macro, this command
does not change the "previous cursor" location, which you access
with the SwapPrevPos and MoveToPrevPos macros.
BreakLine - Insert a line break at the current cursor location
leaving the cursor on the beginning of the next line. This macro
is the same as pressing Enter.
CenterFixScreenPos - Corrects the screen image position relative
to the cursor. This command moves the screen image so that the
cursor is in the middle of it.
ClipClear - Removes the selected text but does not change the
Clipboard. This macro is the same as pressing Ctrl-Del or
choosing Edit|Clear.
ClipCopy - Copies the selected text so you can paste a copy of it
elsewhere. This macro is the same as pressing Ctrl-Ins or
choosing Edit|Copy.
ClipCut - Cuts the selected text. This macro is the same as
pressing Shift-Del or choosing Edit|Cut.
ClipPaste - Pastes the last-cut or last-copied text. This macro is
the same as pressing Shift-Ins or choosing Edit|Paste.
ClipShow - Opens the Clipboard window.
*CloseWindow - Close the current editor. This macro is the same as
pressing Alt-F3.
CompileFile - Compiles the current file. This macro is the same as
pressing Alt-F9 or choosing the Compile|Compile to OBJ command.
CopyBlock - Inserts a copy of the current block at the cursor
position. Unlike the CopyBlockRaw macro, this macro makes
sure that the cursor remains visible.
CopyBlockRaw - Copies the block without ensuring the cursor
remains visible.
CursorCharLeft - Moves the cursor one character to the left. (If
the cursor is at the beginning of a line, this command makes it
wrap to the previous printing character.)
CursorCharRight - Moves the cursor one character to the right. (If
the cursor is at the end of a line, this command makes it wrap
to the next printing character.)
CursorDown - Moves the cursor one line down, keeping it in the
same column.
CursorLeft - Moves the cursor one column to the left.
CursorRight - Moves the cursor one column to the right (even if
there are no characters there). If the cursor is at the edge of
the screen, this command moves the cursor off the visible
screen.
CursorSwitchedLeft - Move the cursor one character left paying
attention to the roaming cursor mode. This macro is the same as
pressing Left Arrow or ^E.
CursorSwitchedRight - Move the cursor one character right paying
attention to the roaming cursor mode. This macro is the same as
pressing Right Arrow or ^D.
CursorUp - Moves the cursor one line up, keeping it in the same
column.
DeleteBlock - Deletes the current block. Unlike the DeleteBlockRaw
macro, DeleteBlock leaves the cursor fixed in one spot on the
screen (it doesn't move when the block is deleted).
DeleteBlockRaw - Deletes the current block. Unlike the DeleteBlock
macro, this "raw" macro doesn't fix the cursor in one spot on
the screen (it can move when the block is deleted).
DeleteChar - Deletes the character at the cursor position.
DeleteLine - Deletes the line the cursor is on.
DeleteToEOL - Deletes from the cursor position to the end of the
line.
DeleteWord - Deletes the word the cursor is on plus the space
characters after it.
EndCursor - Moves the cursor to the end of the file. This macro
automatically sets the previous cursor position so that you can
go back there with the MoveToPrevPos macro.
EndCursorRaw - Moves the cursor to the end of the file. As opposed
to the EndCursor macro, this command does not reset the
"previous cursor" location, which you access with the
SwapPrevPos and MoveToPrevPos macros.
Exit - Exits from the editor.
FixCursorPos - Corrects the cursor position in respect to the
screen. This command moves the cursor to the visible screen by
making the least amount of movement possible, the result being
that the cursor appears at the start or the end of the screen.
FixScreenPos - Corrects the screen position in respect to the
cursor. This command moves the screen image to the cursor by
making the least amount of movement possible, the result being
that the screen appears above or below the cursor position.
FullPaintScreen - Forces a full refresh of the screen. This paints
out to the edge of the screen; it is slower than PaintScreen.
GetFindString - Opens the Find dialog box so you can search for a
text string. The search begins at the current cursor position.
Help - Opens the Help window, just like the Help|Table of Contents
command. This macro is the same as pressing F1.
HighlightBlock - Highlights the current marked block.
HomeCursor - Moves the cursor position to the beginning of the
file. This macro automatically sets the starting cursor position
so that you can go back there with the MoveToPrevPos macro.
HomeCursorRaw - Moves the cursor to the beginning of the file. As
opposed to the HomeCursor macro, this command does not change
the "previous cursor" location, which you access with the
SwapPrevPos and MoveToPrevPos macros.
IndentBlock - Indents a block one space. This macro is the same as
pressing ^K^I.
InsertText("string") - Inserts string at the current cursor
position. The double quotes are required around string; string
can be up to 4,096 characters long.
LastHelp - Opens the Help window that was last viewed, just like
the Help|Previous Topic command. This macro is the same as
pressing Alt-F1.
LeftOfLine - Moves the cursor to the beginning of the line
(typically defined to be Home).
LiteralChar - Inserts the next key pressed verbatim into the file
(such as Ctrl-P).
*MakeProject - To a make of the current editor or primary file.
This macro is the same as pressing F9.
MarkLine - Set the block mark to mark the current line. This macro
is the same as pressing ^K^L.
MarkWord - Mark the word at the location of the cursor. This macro
is the same as pressing ^K^T.
MatchPairBackward - Finds the matching delimiter character that
complements the one at the current cursor position. Searches
backward (to the beginning) in the file.
MatchPairForward - Finds the matching delimiter character that
complements the one at the current cursor position. Searches
forward (to the end) in the file.
*Menu - Makes the menu bar active. This macro is the same as
pressing F10.
Modify - This macro is the same as pressing Ctrl-F4 or
Debug|Evaluate/Modify.
MoveBlock - Moves the current block to the cursor position. Unlike
the MoveBlockRaw macro, this macro highlights the new block.
MoveBlockRaw - Moves a block without ensuring the cursor remains
visible.
MoveToBlockBeg - Moves the cursor to the beginning of the current
block. Unlike the MoveToBlockBegRaw macro, this macro updates
the cursor on the screen and changes the "previous cursor"
location, which you access with the SwapPrevPos and
MoveToPrevPos macros.
MoveToBlockBegRaw - Moves the cursor to the beginning of the
current block. Unlike the MoveToBlockBeg macro, this "raw" macro
doesn't update the cursor onscreen and doesn't change the
"previous cursor" location, which you access with the
SwapPrevPos and MoveToPrevPos macros.
MoveToBlockEnd - Moves the cursor to the end of the current block.
Unlike the MoveToBlockEndRaw macro, this macro updates the
cursor onscreen and changes the "previous cursor" location,
which you access with the SwapPrevPos and MoveToPrevPos macros.
MoveToBlockEndRaw - Moves the cursor to the end of the current
block. Unlike the MoveToBlockEnd macro, this "raw" macro doesn't
update the cursor onscreen and doesn't change the "previous
cursor" location, which you access with the SwapPrevPos and
MoveToPrevPos macros.
MoveToMark(number) - Moves the cursor to the location designated
by the SetMark(number) macro. You can set 10 marks by passing
SetMark a parameter of 0 to 9. You move the cursor to any of the
10 marks by passing the corresponding number (0-9) to the
MoveToMark(number) macro.
MoveToPrevPos - Moves the cursor to the position designated by the
SetPrevPos macro.
MoveToTempPos - Moves to the temporary mark position.
*NextWindow - Make the window in the window list active. This
macro is the same as pressing F6.
OpenFile - Displays the Open dialog box. This macro is the same as
pressing F3.
OpenLine - Break the line at the current location leaving the
cursor at the end of the current line.
OutdentBlock - Unindents a block one space. This macro is the same
as pressing ^K^U.
PageDownRaw - Page the display and cursor down one screen but does
not ensure the screen is displaying the cursor.
PageDownScrolls - both the screen and cursor down one page.
PageScreenDown - Moves the screen down one screenful, possibly
moving the cursor out of view (typically defined to be PgDn).
PageScreenUp - Moves the screen up one screenful, possibly moving
the cursor out of view (typically defined to be PgUp).
PageUp - Scrolls both the screen and cursor up one page.
(Typically defined to be PgUp.)
PageUpRaw - Page the display and cursor up one screen but does not
ensure the screen is displaying the cursor.
PaintScreen - Forces a full refresh of the screen. PaintScreen
only paints lines from the buffer; it assumes it knows how to
blank end-of-lines. It's faster than FullPaintScreen.
*PrintBlock - Print the currently marked block. This macro is the
same as pressing ^K^P.
Quit - Exits from the integrated environment. If you've made
changes you haven't saved, you'll be given a chance to save them
before quitting. This macro is the same as pressing Alt-X.
ReadBlock - Lets you open a text file and insert it at the cursor
position. The ReadBlock macro automatically opens the Open
dialog box so you can choose a file to open.
RepeatSearch - Searchs for the text string that was last entered
in the find dialog box using the GetFindString macro.
Replace - Opens the Replace dialog box so you can search for and
replace text.
ResetProgram - Resets the current program. This macro is the same
as pressing Ctrl-F2 or choosing Run|Program Reset.
RestoreLine - Inserts the line deleted with the DeleteLine macro.
If the cursor has moved to another line since the DeleteLine
macro, this macro does nothing.
RightOfLine - Moves the cursor to the end of the line (typically
defined to be End).
RightOfWord - Moves the cursor to the right of a word.
RunProgram - Runs the current program. This macro is the same as
pressing Ctrl-F9 or choosing the Run|Run command.
RunToHere - Runs a program up to the line containing the cursor.
This macro is the same as pressing F4 or choosing Run|Go to
Cursor.
SaveFile - Saves the file in the current window. This macro is the
same as pressing F2 or choosing the File|Save command.
ScrollDown - Scrolls the screen down one line. This macro will not
allow the cursor to scroll out of view.
ScrollScreenDown - Moves the screen down one line, leaving the
cursor at the same relative position in the file. This command
will allow the cursor to scroll out of view.
ScrollScreenUp - Moves the screen up one line, leaving the cursor
at the same relative position in the file. This command will
allow the cursor to scroll out of view.
ScrollUp - Scrolls the screen up one line. This command will not
allow the cursor to scroll out of view.
SetAutoIndent - Turn on auto-indent mode. The following macro will
turn off auto-indent mode,
Macro ClearAutoIndent
SetAutoIndent;
ToggleAutoIndent;
end;
SetAutoOutdent - Turn on auto-outdent mode. The following macro
will turn off auto-outdent mode,
Macro ClearAutoOutdent
SetAutoOutdent;
ToggleAutoOutdent;
end;
SetBlockBeg - Marks the current cursor position as the beginning
of a block. Unlike the SetBlockBegRaw macro, this macro
highlights the new block.
SetBlockBegRaw - Sets the beginning of the block without showing
the block.
SetBlockEnd - Marks the current cursor position as the end of a
block. Unlike the SetBlockEndRaw macro, this macro highlights
the new block.
SetBlockEndRaw - Sets the end position of the block without
showing the block.
SetBreakpoint - Sets a breakboint at the cursor position. This
macro is the same as pressing Ctrl-F8 or choosing Debug|Toggle
Breakpoint.
SetInsertMode - Turns insert mode on. To turn it off, type
BEGIN SetInsertMode; Toggle Insert END;
SetMark(number) - Sets the current cursor position so that you can
return to it using the MoveToMark(number) macro. You can set
number to any number from 0 to 9. You move the cursor to any of
the 10 marks by passing the corresponding number (0-9) to the
MoveToMark(number) macro.
SetOptimalFillMode - Turn on optimal fill mode. The following
macro will turn off optimal fill mode,
Macro ClearOptimalFillMode
SetOptimalFillMode;
ToggleOptimalFillMode;
end;
SetPrevPos - Marks the current cursor position as the place to
return to when you use the SwapPrevPos or MoveToPrevPos macros.
Many macros implicitly set the "previous position" (the notable
exceptions are "raw" macros).
SmartRefreshScreen - Refreshes only the parts of the screen that
have changed.
SetRoamingCursorMode - Turn on roaming cursor mode. The following
macro will turn off roaming cursor mode,
Macro ClearRoamingCursorMode
SetRoamingCursorMode;
ToggleRoamingCursorMode;
end;
SetTabbingMode - Turn on tabbing mode. The following macro will
turn off tabbing mode,
Macro ClearTabbingMode
SetTabbingMode;
ToggleTabbingMode;
end;
SetTempPos - Sets the temporary mark position.
SmartTab - Smart tab is the default binding of the Tab key. It
will either insert spaces or a tab character depending on the
tabbing mode.
Step - Runs a program one statement at a time but stepping over
subroutines. This macro is the same as pressing F8 or choosing
Run|Step Over.
SwapPrevPos - Switches the current cursor position with the spot
designated by the SetPrevPos macro.
ToggleAutoIndent - Toggles the auto-indent mode. This macro is the
same as pressing ^O^I.
ToggleAutoOutdent - Toggles the auto-outdent mode. This macro is
the same as pressing ^O^U.
ToggleHideBlock - Highlights or hides the current marked block.
ToggleInsert - Switches insert modes, from Insert to Overwrite or
from Overwrite to Insert.
ToggleOptimalFillMode - Toggle the optimal fill mode. This macro
is the same as pressing ^O^F.
ToggleRoamingCursorMode - Toggle the roaming cursor mode. This
macro is the same as pressing ^O^R.
ToggleTabbingMode - Toggle the tabbing mode. This macro is the
same as pressing ^O^T.
TopOfScreen - Moves the cursor to the upper left corner of the
screen. This macro automatically sets the previous cursor
position so that you can go back to it with the MoveToPrevPos
macro.
TopOfScreenRaw - Moves the cursor to the upper left corner of the
screen. screen. As opposed to the TopOfScreen macro, this
command does not change the "previous cursor" location, which
you access with the SwapPrevPos and MoveToPrevPos macros.
Trace - Runs a program one statement at a time, moving into
subroutines as necessary. This macro is the same as pressing F7
or choosing Run|Trace Into.
ViewUserScreen - Switches views to the User Screen. This macro is
the same as pressing Alt-F5 or choosing the Window|User Screen
command.
*WordHelp - Bring up help on the word at the current cursor
position.
WordLeft - Moves the cursor one word to the left, placing it on
the first character of that word.
WordRight - Moves the cursor one word to the right, placing it on
the first character of that word.
WriteBlock - Lets you save the current block to a file. The
WriteBlock macro automatically opens the Write Block to File
dialog box so you can enter a file name.
*ZoomWindow - Zoom the current editor. This macro is the same as
pressing F5.
===================
5. Error messages
===================
While coding your macros, you may encounter certain errors.
Knowing the compiler capacity may help you avoid some of those
errors, which are given after this list of memory requirements.
o each macro invocation takes 1 byte
o each integer parameter takes 2 bytes
o each character parameter takes (number_of_characters_in_string +
1) bytes
o each macro requires 1 byte for end
Cannot allocate memory for file.
Not enough memory is available to process the file. TEMC needs
about 100K of available space to compile a file.
Expected item.
The line indicated is most likely missing the specified item.
File filename could not be created.
The file specified for output cannot be created. Either the disk
is full or you do not have rights to the current network drive or
the name specified is not legal.
File filename is empty.
The file passed to TEMC to compile has nothing in it.
File filename larger than 64K.
The script file is larger than the maximum 64K in size.
File filename not found.
The file specified does not exist.
Invalid key.
Key specified is not recognized.
Invalid symbol.
The symbol specified is not a valid TEMC symbol.
Out of memory.
Not enough memory is available to process the file. TEMC needs
about 100K of available space to compile a file.
Read error on file filename.
TEMC could not read the file source file.
Redefinition of key.
This key is defined elsewhere in the file.
Redefinition of macro macro.
This macro is defined elsewhere in the file.
Parameters to a macro call illegal.
Macros cannot have parameters. Trying to pass a parameter to a
Script too complex. One or more of the following conditions need
to be corrected:
o Too many keys defined.
o String parameter is too long (the maximum string length is 256
characters).
o Too many parameters.
o Macro size may be too large (the maximum size allowed is 1,024
bytes).
Undefined symbol symbol.
The symbol specified has not yet been defined.
Unexpected item.
The indicated line most likely would be correct if the item
specified was deleted or changed.
Unexpected end of file.
The last macro or BEGIN/END pair was not terminated.

View File

@ -0,0 +1,55 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Vision Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit TextView;
{$F+,O+,S-}
interface
uses Objects, Drivers, Views, Dos;
type
{ TTextDevice }
PTextDevice = ^TTextDevice;
TTextDevice = object(TScroller)
Dummy: Word;
function StrRead(var S: TextBuf): Byte; virtual;
procedure StrWrite(var S: TextBuf; Count: Byte); virtual;
end;
{ TTerminal }
PTerminalBuffer = ^TTerminalBuffer;
TTerminalBuffer = array[0..65534] of Char;
PTerminal = ^TTerminal;
TTerminal = object(TTextDevice)
BufSize: Word;
Buffer: PTerminalBuffer;
QueFront, QueBack: Word;
constructor Init(var Bounds:TRect; AHScrollBar, AVScrollBar: PScrollBar;
ABufSize: Word);
destructor Done; virtual;
procedure BufDec(var Val: Word);
procedure BufInc(var Val: Word);
function CalcWidth: Integer;
function CanInsert(Amount: Word): Boolean;
procedure Draw; virtual;
function NextLine(Pos:Word): Word;
function PrevLines(Pos:Word; Lines: Word): Word;
function StrRead(var S: TextBuf): Byte; virtual;
procedure StrWrite(var S: TextBuf; Count: Byte); virtual;
function QueEmpty: Boolean;
end;
procedure AssignDevice(var T: Text; Screen: PTextDevice);

View File

@ -0,0 +1,182 @@
TURBO HELP UTILITY
------------------
This file explains how to use THELP.COM. THELP is a memory-resident
utility that provides online help for Turbo Pascal and Turbo C++. If you
are using Turbo Debugger, for example, you can load THELP, then run
the debugger and get online help for Pascal or C while you are
debugging.
Table of Contents
-----------------
1. Starting THELP
2. Command-line Options Summary
3. Detailed Explanation of Keys Used When THELP is Active
4. Detailed Explanation of Command line Options
1. Starting THELP
------------------
Load THELP at the DOS command line simply by typing THELP. Make sure
the Turbo help file is in the current directory or use the /F command
line option described below. The INSTALL program on the distribution
disks inserts the correct path information in THELP.
Memory Usage - THELP requires about 20K bytes.
Default hotkey - The default hotkey is Numeric-Keypad-5 (scan
code 4ch, shift state 00h).
Paste speed - The default pasting speed is FAST. You'll have
to experiment if it pastes too quickly for your
editor. Note that you should turn off autoindent
in the integrated environment before using the
paste feature.
If you are using SideKick Plus or SideKick 1.x, make sure you
load THELP before you load SideKick.
2. Command-line Options Summary
-------------------------------
USAGE: THELP [options]
Here is a summary of the command line options. If you use more
than one option, they must be separated by spaces.
/Fname Full path and filename of help file
/H,/?,? Display this help screen
/Kxxyy Change hotkey: xx=shift state(hex),
yy=scan code(hex)
/Px Pasting speed: 0=slow, 1=medium, 2=fast
/S+ Enable snow checking for video (useful for older CGA adapters).
/S- Disable snow checking for video (for snappier displays).
/U Remove THELP from memory
/W Write Options to THELP.COM and exit
3. Detailed Explanation of Keys Used When THELP is Active
---------------------------------------------------------
Arrow keys: Moves the cursor.
PgUp/PgDn: Moves the cursor.
Shift-Arrow keys: Moves the cursor while marking a block.
TAB: Moves the cursor to the next keyword.
Shift-TAB: Moves the cursor to the previous keyword.
HOME: Go to the beginning of the line.
END: Go to the end of the line.
ENTER: Select help entry for the item highlighted in the
current help screen.
ESC: End Help.
F1: Help Index. F1 from any help screen brings up
the Help Index. You can search for a specific keyword
incrementally. For example, you can find "printf" by
typing p r i. With each letter you type, the list
jumps to the keyword that starts with p, then to pr,
then to pri, etc.
ALT-F1: Displays in reverse order the last 20 screens you
have reviewed.
CTL-F1: Bring up help screen for THELP's hot keys.
CTRL-P key: Paste the example text into the application.
4. Detailed Explanation of Command-line Options
------------------------------------------------
/Fname -- Full path and filename of help file
The name that follows the /F option should be the full
drive/directory pathname of the help file to use; e.g.,
THELP /FC:\TP\TURBO.HLP
THELP /FC:\TURBOC\TCHELP.TCH
By default, THELP looks for the help file on the logged drive and
directory.
/H,/?,? -- Display help screen
This option displays a summary of THELP's command-line options
/Kxxyy -- Change hotkey: xx=shift state, yy=scan code
Virtually any shift state/scan code combination may be selected. A
quick summary of some common shift-states and scan codes follows:
Shift States (may be OR'ed together)
right shift 01h
left shift 02h
control 04h
alt 08h
Scan Codes
A --- 1eh N --- 31h 0 --- 0bh F1 --- 3bh
B --- 30h O --- 18h 1 --- 02h F2 --- 3ch
C --- 2eh P --- 19h 2 --- 03h F3 --- 3dh
D --- 20h Q --- 10h 3 --- 04h F4 --- 3eh
E --- 12h R --- 13h 4 --- 05h F5 --- 3fh
F --- 21h S --- 1fh 5 --- 06h F6 --- 40h
G --- 22h T --- 14h 6 --- 07h F7 --- 41h
H --- 23h U --- 16h 7 --- 08h F8 --- 42h
I --- 17h V --- 2fh 8 --- 09h F9 --- 43h
J --- 24h W --- 11h 9 --- 0ah F10 --- 44h
K --- 25h X --- 2dh
L --- 26h Y --- 15h
M --- 32h Z --- 2ch
Enhanced Keyboards only (may not work with all computers, keyboards)
F11 --- 57h
F12 --- 58h
/Px -- Pasting speed: 0=slow, 1=medium, 2=fast
Some editors do not accept characters pasted into the keyboard buffer
as fast as THELP can put them there. By setting an appropriate paste
speed, virtually all possible configurations of editors may be used.
FAST speed pastes as many characters as will fit on every timer tick;
MEDIUM pastes up to four characters per tick; and SLOW pastes a single
character into the buffer ONLY when the buffer is empty.
/S -- Controls snow checking logic for video.
Some older CGA have a tendency to produce a "snow" effect when
software tries to write directly into their memory space. If you see
this snow you should start up THELP with /S+ to enable the snow
checking code. You may want to use the /W switch (see below) to make
it permanent. Snow checking takes time and it is better to live
without it. To disable snow checking use /S-; this is the default.
/U -- Remove THELP from memory
This option is used to remove THELP from memory. If other TSRs have
been loaded after THELP, make sure to remove them before removing
THELP.
/W -- Write Options to THELP.COM and exit
The /W parameter is used to create a new version of THELP that uses
the options you desire as a default. All options, including may be
specified and made 'permanent'.


View File

@ -0,0 +1,694 @@
======================================================================
Additional Turbo Vision Documentation
======================================================================
----------------------------------------------------------------------
Table of Contents
----------------------------------------------------------------------
A. Additional reference material
1. Enhancements to OBJECTS.PAS
a. New TCollection.AtFree method
b. Duplicate keys in sorted collections
c. Changes to TEmsStream.Init to support EMS 3.2
2. Enhancements to DRIVERS.PAS
a. MouseReverse variable
3. Enhancements to VIEWS.PAS
a. ErrorAttr variable
b. TWindow.Close method
c. cmListItemSelected constant
d. TListViewer.SelectItem method
4. Enhancements to DIALOGS.PAS
a. bfBroadcast constant
b. TButton.Press method
5. Enhancements to MEMORY.PAS
a. bfBroadcast constant
b. TButton.Press method
6. Stream RegisterXXXX procedures and ID codes
B. Additional explanatory material
1. Overlaying Turbo Vision applications
2. Ordering of inherited calls
----------------------------------------------------------------------
This appendix contains additional explanatory and reference
material about Turbo Vision.
1. Enhancements to OBJECTS.PAS
------------------------------
TCollection.AtFree method
-------------------------
procedure TCollection.AtFree(Index: Integer);
Deletes and disposes of the item at the given Index. Equivalent to
Item := At(Index);
AtDelete(Index);
FreeItem(Item);
Duplicate keys in sorted collections
------------------------------------
TSortedCollection implements sorted collections both with or without
duplicate keys. The TSortedCollection.Duplicates field controls
whether duplicates are allowed or not. It defaults to False,
indicating that duplicate keys are not allowed, but after creating a
TSortedCollection you can set Duplicates to True to allow elements
with duplicate keys in the collection.
When Duplicates is True, the Search method returns the index of the
first item in the collection that has the given key, and the Insert
method inserts an item before other items (if any) with the same
key. The IndexOf method uses Search to locate the first item with
the key given by the Item parameter, and then performs a linear
search to find the exact Item.
TSortedCollection overrides the Load and Store methods inherited
from TCollection to also load and store the value of the Duplicates
field.
TEmsStream.Init method
----------------------
constructor TEmsStream.Init(MinSize, MaxSize: Longint);
EMS drivers earlier than version 4.0 don't support resizeable
expanded memory blocks. With a pre-4.0 driver, an EMS stream cannot
be expanded beyond its initial size once it has been allocated. To
properly support both older and newer EMS drivers, a TEmsStream's
Init constructor takes two parameters which specify the minimum and
maximum size of the initial EMS memory block allocation. Init will
always allocate at least MinSize bytes.
If the EMS driver version number is greater than or equal to 4.0,
Init allocates only MinSize bytes of EMS, and then expands the block
as required by subsequent calls to TEmsStream.Write. MaxSize is
ignored.
If the driver version number is less than 4.0, Init allocates as
much expanded memory as is available up to MaxSize bytes, and an
error will occur if subsequent calls to TEmsStream.Write attempt to
expand the stream beyond the allocated size.
2. Enhancements to DRIVERS.PAS
------------------------------
MouseReverse variable in Drivers
-----------------------------------
const MouseReverse: Boolean = False;
Setting MouseReverse to True causes Turbo Vision's event manager to
reverse the mbLeftButton and mbRightButton flags in the Buttons
field of TEvent records.
3. Enhancements to VIEWS.PAS
----------------------------
ErrorAttr variable
------------------
const ErrorAttr: Byte = $CF;
Contains a video attribute byte used as the error return value of a
call to TView.GetColor. If TView.GetColor fails to correctly map a
palette index into a video attribute byte (because of an
out-of-range index), it returns the value given by ErrorAttr. The
default ErrorAttr value represents blinking high-intensity white
characters on a red background. If you see this color combination on
the screen, it is most likely an indication of a palette mapping
error.
TWindow.Close method
--------------------
Calls the TWindow's Valid method with a Command value of cmClose,
and then, if Valid returns True, closes the window by calling its
Done method.
cmListItemSelected constant
---------------------------
A TListViewer uses the Message function to send an evBroadcast event
with a Command value of cmListItemSelected to its TView.Owner
whenever an item in the list viewer is selected (by double-clicking
on it, or by moving the selection bar to the item and pressing the
spacebar). The InfoPtr of the event points to the TListViewer
itself.
TListViewer.SelectItem method
-----------------------------
The default SelectItem method sends a cmListItemSelected broadcast
to its Owner as follows:
Message(Owner, evBroadcast, cmListItemSelected, @Self);
4. Enhancements to DIALOGS.PAS
------------------------------
bfBroadcast constant in Dialogs
-------------------------------
const bfBroadcast = $04;
This flag is used in constructing the AFlags bit mask passed to
TButton.Init. It controls whether TButton objects should generate
events using the PutEvent method or the Message function. If
bfBroadcast is clear, a TButton uses PutEvent to geneate an
evCommand event whenever it is pressed:
E.What := evCommand;
E.Command := Command;
E.InfoPtr := @Self;
PutEvent(E);
If bfBroadcast is set, a TButton uses Message to send an evBroadcast
message to its Owner whenever it is pressed:
Message(Owner, evBroadcast, Command, @Self);
TButton.Press method
--------------------
procedure TButton.Press; virtual;
This method is called to generate the effect associated with
"pressing" a TButton object. The default method sends an evBroadcast
event with a command value of cmRecordHistory to the button's owner
(causing all THistory objects to record the contents of the
TInputLine objects they control), and then uses PutEvent or Message
to generate an event (see description of bfBroadcast flag). You can
override TButton.Press to change the behaviour of a button when it
is pressed.
5. Enhancements to MEMORY.PAS
-----------------------------
New SetMemTop procedure
-----------------------
procedure SetMemTop(MemTop: Pointer);
Sets the top of the application's memory block. The initial memory
top corresponds to the value stored in the HeapEnd variable.
SetMemTop is typically used to shrink the application's memory block
before executing a DOS shell or another program, and to expand the
memory block afterwards. For an example of how to use SetMemTop, See
TVDEMO.PAS in the \TP\TVDEMOS directory.
6. RegisterXXXX procedures and ID codes
---------------------------------------
To allow easy interface with streams, the App, ColorSel, Dialogs,
Editors, Menus, Objects, StdDlg, and Views units each define a
procedure which registers all object types in the unit using a
sequence of calls to RegisterType. These registration procedures all
have names of the form RegisterXXXX where XXXX is the name of the
containing unit. The types and object ID values registered by the
RegisterXXXX procedures are show below.
RegisterApp
TBackground 30
TDeskTop 31
RegisterColorSel
TColorSelector 21
TMonoSelector 22
TColorDisplay 23
TColorGroupList 24
TColorItemList 25
TColorDialog 26
RegisterDialogs
TDialog 10
TInputLine 11
TButton 12
TCluster 13
TRadioButtons 14
TCheckBoxes 15
TListBox 16
TStaticText 17
TLabel 18
THistory 19
TParamText 20
RegisterEditors
TEditor 70
TMemo 71
TFileEditor 72
TIndicator 73
TFileWindow 74
RegisterMenus
TMenuBar 40
TMenuBox 41
TStatusLine 42
RegisterObjects
TCollection 50
TStringCollection 51
RegisterStdDlg
TFileInputLine 60
TFileCollection 61
TFileList 62
TFileInfoPane 63
TFileDialog 64
TDirCollection 65
TDirListBox 66
TChDirDialog 67
RegisterViews
TView 1
TFrame 2
TScrollBar 3
TScroller 4
TListViewer 5
TGroup 6
TWindow 7
If your application uses stream I/O, you should call the appropriate
RegisterXXXX procedures in the application's Init method, and in
addition use RegisterType to register your own types:
type
TMyApp = object(TApplication)
constructor Init;
...
end;
constructor TMyApp.Init;
begin
RegisterApp;
RegisterDialogs;
RegisterMenus;
RegisterObjects;
RegisterViews;
RegisterType(RStringList);
RegisterType(RMyFirstType);
RegisterType(RMySecondType);
TApplication.Init;
...
end;
Notice the explicit call to RegisterType(RStringList) to register
the TStringList type. The RegisterObjects procedures does not
register the TStringList and TStrListMaker types, since they have
the same object type ID (52). Depending on whether your application
is using or generating string lists, you must manually register
TStringList or TStrListMaker.
See TVRDEMO.PAS and TVFORMS.PAS in the \TP\TVDEMOS directory for
examples of applications that perform stream registration.
----------------------------------------------------------------------
B. Additional explanatory material
1. Overlaying Turbo Vision applications
2. Ordering of inherited calls
----------------------------------------------------------------------
1. Overlaying Turbo Vision applications
---------------------------------------
Turbo Vision was designed to work efficiently in an overlaid
application. All Turbo Vision units can be overlaid, except for the
Drivers unit, which contains interrupt handlers and other low-level
system interfaces.
When designing an overlaid Turbo Vision application, carefully
consider which objects constitute the various "working sets" of your
application. At any given moment, the user will be interacting with
a group of objects. Therefore, the code for all of these objects
need to fit in the overlay pool at the same time to avoid excessive
disk access. Since Turbo Pascal's overlay manager swaps in entire
units at a time, do not place unrelated objects in the same overlaid
unit. If you do, when you use only one of the objects, the code for
all the others will also be swapped into the overlay pool and will
take up valuable space. Remember--when a unit is brought into the
overlay pool, another unit may very well be squeezed out.
Consider an example in which you're designing a special dialog that
contains some customized controls. Your dialog is derived from
TDialog and your custom controls are derived from TListViewer and
TInputLine. Placing all three derived object types in the same unit
makes sense because they're part of the same working set. However,
placing other unrelated objects in that unit would require a larger
overlay pool to hold your working set and therefore may cause disk
thrashing when you run the program.
Within a Turbo Vision application, the App, Memory, Menus Objects,
and Views units total about 50 kbytes of code and will almost always
be part of the current working set. In addition, units containing
your derived application object and any windows or dialogs with
which the user is currently interacting will also be part of the
working set, bringing the typical minimum overlay pool size to about
64K bytes.
Through experimentation, you can determine the ideal size of the
overlay pool. In general, the presence of EMS makes code swapping
much faster and allows you to reduce the size of overlay pool by 25%
to 35%. Determining the best size of the pool depends on many
factors, however and generally involves a tradeoff of speed vs.
capacity. The best approach allows for runtime flexibility with some
reasonable, established limits. If possible, we recommend that you
support a command-line parameter or a configuration file to control
the size of the overlay pool at startup (like the /X command-line
option for TURBO.EXE).
The following skeleton program presents a typical overlaid Turbo
Vision application:
program MyProg;
{$F+,O+,S-}
{$M 8192,65536,655360}
uses Overlay, Drivers, Memory, Objects, Views, Menus, Dialogs,
HistList, StdDlg, App;
{$O App }
{$O Dialogs }
{$O HistList }
{$O Memory }
{$O Menus }
{$O Objects }
{$O StdDlg }
{$O Views }
const
ExeFileName = 'MYPROG.EXE'; { EXE name for DOS 2.x }
OvrBufDisk = 96 * 1024; { Overlay pool size without EMS }
OvrBufEMS = 72 * 1024; { Overlay pool size with EMS }
type
TMyApp = object(TApplication)
constructor Init;
destructor Done; virtual;
.
.
end;
procedure InitOverlays;
var
FileName: string[79];
begin
FileName := ParamStr(0);
if FileName = '' then FileName := ExeFileName;
OvrInit(FileName);
if OvrResult <> 0 then
begin
PrintStr('Fatal error: Cannot open overlay file.');
Halt(1);
end;
OvrInitEMS;
if OvrResult = 0 then OvrSetBuf(OvrBufEMS) else
begin
OvrSetBuf(OvrBufDisk);
OvrSetRetry(OvrBufDisk div 2);
end;
end;
constructor TMyApp.Init;
begin
InitOverlays;
TApplication.Init;
.
.
end;
destructor TMyApp.Done;
begin
.
.
TApplication.Done;
end;
var
MyApp: TMyApp;
begin
MyApp.Init;
MyApp.Run;
MyApp.Done;
end.
Notice how the overlay manager is initialized before calling the
inherited TApplication.Init--this is a requirement since the App
unit, which contains TApplication, is overlaid. Also notice the use
of ParamStr(0) to get the name of the .EXE file; that only works
with DOS version 3.0 or later. In order to support earlier DOS
versions, a test for a null string combined with the ability to
supply an .EXE file name is required. Finally, notice that
OvrSetRetry isn't called if EMS is present, since it generally only
improves performance when the overlay file is on disk.
The above example assumes that you've used the recommended practice
of appending the overlay file to the end of .EXE file. This is
easily done using the DOS COPY command:
REN MYPROG.EXE TEMP.EXE
COPY/B TEMP.EXE+MYPROG.OVR MYPROG.EXE
See TVRDEMO.PAS in the \TP\TVDEMOS directory for an example of an
overlaid Turbo Vision application. And always remember to place a
{$F+,O+} directive at the beginning of all overlaid units.
For further information on Turbo Pascal's overlay manager, please
refer to Chapter 13 in the Programmer's Guide.
2. Ordering of inherited calls
------------------------------
Turbo Vision is designed so that you can extend it to suit your
application's specific needs by deriving new descendants from
existing Turbo Vision objects. Sometimes, your new object will want
to completely replace the inherited behavior for a given method. For
example, when TInputLine is derived from TView, TInputLine.Draw does
not call its inherited method, TView.Draw. That's because TView.Draw
simply creates an empty rectangle. Instead, TInputLine overrides the
inherited Draw and defines a new one:
procedure TInputLine.Draw;
...
begin
{ Insert code to draw an input line here }
end;
In fact, calling TView.Draw would cause an unpleasant flicker on the
screen when first TView cleared the rectangle, and then TInputLine
filled it in. Methods like Draw are an exception, though.
Programming effectively with Turbo Vision involves making lots of
inherited method calls. For each method you're overriding, you must
know which to do first: Execute the code that you're adding? Or
first call the inherited method and then execute your new code?
Moreover, as you've just seen with the Draw method, sometimes you
don't call your inherited method at all. Doing the right thing in
the right order, of course, depends on where your new object falls
in the Turbo Vision hierarchy and which method you're overriding.
The rules for inherited call ordering break into 3 categories
1) Constructors. Call the inherited method first.
procedure MyObject.Init(...);
begin
{ Call inherited Init first }
{ Insert code to init MyObject }
end;
2) Destructors. Call the inherited method last.
procedure MyObject.Done;
begin
{ Insert code to cleanup MyObject }
{ Call inherited Done last }
end;
3) All other methods: It depends. See below for an explanation.
Overriding Init and Load: The Call First Rule
---------------------------------------------
You should always call your inherited constructor first and then
initialize any new fields your descendent object defines. This
advice applies to Init and Load constructors equally
type
MyObject = object(TWindow)
Value: Word;
Ok: Boolean;
constructor Init(var Bounds: TRect; ATitle: TTitleStr;
AValue: Word; AOk: Boolean);
end;
constructor MyObject.Init(var Bounds: TRect; ATitle: TTitleStr;
AValue: Word; AOk: Boolean);
begin
TWindow.Init(Bounds, ATitle, wnNoNumber);
Value := 16;
Ok := True;
end;
Here, MyObject calls its inherited Init method, TWindow.Init, to
perform initialization, first. Then MyObject puts meaningful values
into Value and Ok. If you were to reverse the order of these steps,
you'd be in for an unpleasant surprise: Value would be zero and Ok
would be False! That's because TWindow follows the Init convention
and calls its inherited method, TGroup.Init. TGroup.Init calls
TView.Init; which--finally--calls TObject.Init, the ultimate
ancestor to all Turbo Vision objects. TObject.Init zeros ALL the
fields in MyObject, including Value and Ok.
Your Init and Load methods can rely on this and refrain from zeroing
new fields--as long as you're deriving an object from some TView
descendant.
The Exception
-------------
Having said "always call the inherited constructor first", it's not
always true. When working with non-view objects like TCollection or
TStream descendants, you don't HAVE to call your inherited Init or
Load first. But you should, unless there is some compelling reason
to break the rule. And there might be, as in the following case when
an inherited constructor includes a call to a virtual method which
has been overridden. TCollection.Load relies on the virtual method
GetItem to get a collection item from the stream
constructor TCollection.Load(var S: TStream);
begin
...
for I := 0 to Count - 1 do AtPut(I, GetItem(S));
end;
Since GetItem is virtual, you may have overridden it and your
GetItem may rely on your descendent object's Load method to
initialize a field before GetItem is called. In this case, you'd
want your new Load method to read the field value first, then call
TCollection.Load, which would end up "calling back" to your GetItem.
Here's a partial implementation of a collection of binary data (not
objects). The size of a data item is fixed for the entire collection
and held in the new field, ItemSize
type
PDataCollection = ^TDataCollection;
TDataCollection = object(TStringCollection)
ItemSize: Word;
KeyType: KeyTypes;
constructor Init(ALimit, ADelta, AnItemSize: Integer);
constructor Load(var S: TStream);
function Compare(Key1, Key2: Pointer): Integer; virtual;
procedure FreeItem(Item: Pointer); virtual;
function GetItem(var S: TStream): Pointer; virtual;
procedure PutItem(var S: TStream; Item: Pointer); virtual;
procedure Store(var S: TStream); virtual;
end;
...
constructor TDataCollection.Load(var S: TStream);
begin
S.Read(ItemSize, SizeOf(ItemSize));
TStringCollection.Load(S);
end;
function TDataCollection.GetItem(var S: TStream): Pointer;
var Item: Pointer;
begin
GetMem(Item, ItemSize);
S.Read(Item^, ItemSize);
GetItem := Item;
end;
...
Load first reads the ItemSize off the stream, then it calls
TSTringCollection.Load, which "calls back" to GetItem. Now GetItem
knows how big the item it's supposed to load is and can allocate
heap and read data correctly. That's why the "call inherited first"
applies to TView descendants all the time and to all other objects
unless there's a compelling reason. And of course, Load and Store go
hand-in-hand, so in this example, Store would write data to the
stream in the same order as Load reads it. This code is extracted
from the DATACOLL.PAS unit in the \TP\TVDEMOS directory.
Destructors: call them last
---------------------------
A destructor's job is to undo the constructor's handiwork in reverse
order. Therefore, a destructor should always free its own dynamic
memory and then call its inherited destructor to do the same.
All other methods: it depends
-----------------------------
You saw how TInputLine doesn't call its inherited Draw method. If it
did, TView.Draw would have to be called first or else it would
obliterate any writing done by TInputLine.Draw. For the remaining
Turbo Vision methods, whether to make an inherited call or not--and
in what order--depends on which method you're overriding. In
general, call the inherited method first. We've covered the most
common methods to override: Init, Done, Draw, Load, and Store. Now
consider HandleEvent. Here's a skeleton of a descendent object's
HandleEvent method
procedure MyObject.HandleEvent(var Event: TEvent);
begin
{ Insert code to change inherited behavior }
{ Call inherited HandleEvent }
{ Insert code to add additional behavior }
end;
First, code that will CHANGE the inherited behavior is executed.
Then the inherited call is made. Finally, the code that will EXTEND
the inherited behavior is added.
If you want to change the way the inherited method behaves or filter
out events, then put this code ahead of the inherited call. Most
Turbo Vision views call their inherited HandleEvent and then add
code to handle new events
procedure TDialog.HandleEvent(var Event: TEvent);
begin
TWindow.HandleEvent(Event);
case Event.What of
evKeyDown:
...
evCommand:
...
end;
end;
TDialog's HandleEvent manages all keyboard and mouse events,
including tabs. But what if you need to define a new dialog that
ignores tabs? Since you want to change your inherited method's
behavior (the handling of tabs) you'll put this tab-eating code
BEFORE the call to TDialog.HandleEvent
procedure TNoTabsDialog.HandleEvent(var Event: TEvent);
begin
if (Event.What = evKeyDown) then
if (Event.KeyCode = kbTab) or (Event.KeyCode = kbShiftTab) then
ClearEvent(Event);
TDialog.HandleEvent(Event);
end;
That's it. Your TNoTabsDialog will throw away the tabs before
TDialog.HandleEvent can ever see them and the tab key will not move
from control to control when using your dialog.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,558 @@
{*******************************************************}
{ }
{ Turbo Pascal Version 6.0 }
{ Turbo Vision Unit }
{ }
{ Copyright (c) 1990 Borland International }
{ }
{*******************************************************}
unit Views;
{$F+,O+,S-,X+}
interface
uses Objects, Drivers, Memory;
const
{ TView State masks }
sfVisible = $0001;
sfCursorVis = $0002;
sfCursorIns = $0004;
sfShadow = $0008;
sfActive = $0010;
sfSelected = $0020;
sfFocused = $0040;
sfDragging = $0080;
sfDisabled = $0100;
sfModal = $0200;
sfDefault = $0400;
sfExposed = $0800;
{ TView Option masks }
ofSelectable = $0001;
ofTopSelect = $0002;
ofFirstClick = $0004;
ofFramed = $0008;
ofPreProcess = $0010;
ofPostProcess = $0020;
ofBuffered = $0040;
ofTileable = $0080;
ofCenterX = $0100;
ofCenterY = $0200;
ofCentered = $0300;
{ TView GrowMode masks }
gfGrowLoX = $01;
gfGrowLoY = $02;
gfGrowHiX = $04;
gfGrowHiY = $08;
gfGrowAll = $0F;
gfGrowRel = $10;
{ TView DragMode masks }
dmDragMove = $01;
dmDragGrow = $02;
dmLimitLoX = $10;
dmLimitLoY = $20;
dmLimitHiX = $40;
dmLimitHiY = $80;
dmLimitAll = $F0;
{ TView Help context codes }
hcNoContext = 0;
hcDragging = 1;
{ TScrollBar part codes }
sbLeftArrow = 0;
sbRightArrow = 1;
sbPageLeft = 2;
sbPageRight = 3;
sbUpArrow = 4;
sbDownArrow = 5;
sbPageUp = 6;
sbPageDown = 7;
sbIndicator = 8;
{ TScrollBar options for TWindow.StandardScrollBar }
sbHorizontal = $0000;
sbVertical = $0001;
sbHandleKeyboard = $0002;
{ TWindow Flags masks }
wfMove = $01;
wfGrow = $02;
wfClose = $04;
wfZoom = $08;
{ TWindow number constants }
wnNoNumber = 0;
{ TWindow palette entries }
wpBlueWindow = 0;
wpCyanWindow = 1;
wpGrayWindow = 2;
{ Standard command codes }
cmValid = 0;
cmQuit = 1;
cmError = 2;
cmMenu = 3;
cmClose = 4;
cmZoom = 5;
cmResize = 6;
cmNext = 7;
cmPrev = 8;
cmHelp = 9;
{ Application command codes }
cmCut = 20;
cmCopy = 21;
cmPaste = 22;
cmUndo = 23;
cmClear = 24;
cmTile = 25;
cmCascade = 26;
{ TDialog standard commands }
cmOK = 10;
cmCancel = 11;
cmYes = 12;
cmNo = 13;
cmDefault = 14;
{ Standard messages }
cmReceivedFocus = 50;
cmReleasedFocus = 51;
cmCommandSetChanged = 52;
{ TScrollBar messages }
cmScrollBarChanged = 53;
cmScrollBarClicked = 54;
{ TWindow select messages }
cmSelectWindowNum = 55;
{ TListViewer messages }
cmListItemSelected = 56;
{ Color palettes }
CFrame = #1#1#2#2#3;
CScrollBar = #4#5#5;
CScroller = #6#7;
CListViewer = #26#26#27#28#29;
CBlueWindow = #8#9#10#11#12#13#14#15;
CCyanWindow = #16#17#18#19#20#21#22#23;
CGrayWindow = #24#25#26#27#28#29#30#31;
{ TDrawBuffer maximum view width }
MaxViewWidth = 132;
type
{ Command sets }
PCommandSet = ^TCommandSet;
TCommandSet = set of Byte;
{ Color palette type }
PPalette = ^TPalette;
TPalette = String;
{ TDrawBuffer, buffer used by draw methods }
TDrawBuffer = array[0..MaxViewWidth - 1] of Word;
{ TView object Pointer }
PView = ^TView;
{ TGroup object Pointer }
PGroup = ^TGroup;
{ TView object }
TView = object(TObject)
Owner: PGroup;
Next: PView;
Origin: TPoint;
Size: TPoint;
Cursor: TPoint;
GrowMode: Byte;
DragMode: Byte;
HelpCtx: Word;
State: Word;
Options: Word;
EventMask: Word;
constructor Init(var Bounds: TRect);
constructor Load(var S: TStream);
destructor Done; virtual;
procedure BlockCursor;
procedure CalcBounds(var Bounds: TRect; Delta: TPoint); virtual;
procedure ChangeBounds(var Bounds: TRect); virtual;
procedure ClearEvent(var Event: TEvent);
function CommandEnabled(Command: Word): Boolean;
function DataSize: Word; virtual;
procedure DisableCommands(Commands: TCommandSet);
procedure DragView(Event: TEvent; Mode: Byte;
var Limits: TRect; MinSize, MaxSize: TPoint);
procedure Draw; virtual;
procedure DrawView;
procedure EnableCommands(Commands: TCommandSet);
procedure EndModal(Command: Word); virtual;
function EventAvail: Boolean;
function Execute: Word; virtual;
function Exposed: Boolean;
procedure GetBounds(var Bounds: TRect);
procedure GetClipRect(var Clip: TRect);
function GetColor(Color: Word): Word;
procedure GetCommands(var Commands: TCommandSet);
procedure GetData(var Rec); virtual;
procedure GetEvent(var Event: TEvent); virtual;
procedure GetExtent(var Extent: TRect);
function GetHelpCtx: Word; virtual;
function GetPalette: PPalette; virtual;
procedure GetPeerViewPtr(var S: TStream; var P);
function GetState(AState: Word): Boolean;
procedure GrowTo(X, Y: Integer);
procedure HandleEvent(var Event: TEvent); virtual;
procedure Hide;
procedure HideCursor;
procedure KeyEvent(var Event: TEvent);
procedure Locate(var Bounds: TRect);
procedure MakeFirst;
procedure MakeGlobal(Source: TPoint; var Dest: TPoint);
procedure MakeLocal(Source: TPoint; var Dest: TPoint);
function MouseEvent(var Event: TEvent; Mask: Word): Boolean;
function MouseInView(Mouse: TPoint): Boolean;
procedure MoveTo(X, Y: Integer);
function NextView: PView;
procedure NormalCursor;
function Prev: PView;
function PrevView: PView;
procedure PutEvent(var Event: TEvent); virtual;
procedure PutInFrontOf(Target: PView);
procedure PutPeerViewPtr(var S: TStream; P: PView);
procedure Select;
procedure SetBounds(var Bounds: TRect);
procedure SetCommands(Commands: TCommandSet);
procedure SetCursor(X, Y: Integer);
procedure SetData(var Rec); virtual;
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure Show;
procedure ShowCursor;
procedure SizeLimits(var Min, Max: TPoint); virtual;
procedure Store(var S: TStream);
function TopView: PView;
function Valid(Command: Word): Boolean; virtual;
procedure WriteBuf(X, Y, W, H: Integer; var Buf);
procedure WriteChar(X, Y: Integer; C: Char; Color: Byte;
Count: Integer);
procedure WriteLine(X, Y, W, H: Integer; var Buf);
procedure WriteStr(X, Y: Integer; Str: String; Color: Byte);
end;
{ TFrame types }
TTitleStr = string[80];
{ TFrame object }
{ Palette layout }
{ 1 = Passive frame }
{ 2 = Passive title }
{ 3 = Active frame }
{ 4 = Active title }
{ 5 = Icons }
PFrame = ^TFrame;
TFrame = object(TView)
constructor Init(var Bounds: TRect);
procedure Draw; virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure SetState(AState: Word; Enable: Boolean); virtual;
end;
{ ScrollBar characters }
TScrollChars = array[0..4] of Char;
{ TScrollBar object }
{ Palette layout }
{ 1 = Page areas }
{ 2 = Arrows }
{ 3 = Indicator }
PScrollBar = ^TScrollBar;
TScrollBar = object(TView)
Value: Integer;
Min: Integer;
Max: Integer;
PgStep: Integer;
ArStep: Integer;
constructor Init(var Bounds: TRect);
constructor Load(var S: TStream);
procedure Draw; virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure ScrollDraw; virtual;
function ScrollStep(Part: Integer): Integer; virtual;
procedure SetParams(AValue, AMin, AMax, APgStep, AArStep: Integer);
procedure SetRange(AMin, AMax: Integer);
procedure SetStep(APgStep, AArStep: Integer);
procedure SetValue(AValue: Integer);
procedure Store(var S: TStream);
end;
{ TScroller object }
{ Palette layout }
{ 1 = Normal text }
{ 2 = Selected text }
PScroller = ^TScroller;
TScroller = object(TView)
HScrollBar: PScrollBar;
VScrollBar: PScrollBar;
Delta: TPoint;
Limit: TPoint;
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
constructor Load(var S: TStream);
procedure ChangeBounds(var Bounds: TRect); virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure ScrollDraw; virtual;
procedure ScrollTo(X, Y: Integer);
procedure SetLimit(X, Y: Integer);
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure Store(var S: TStream);
end;
{ TListViewer }
{ Palette layout }
{ 1 = Active }
{ 2 = Inactive }
{ 3 = Focused }
{ 4 = Selected }
{ 5 = Divider }
PListViewer = ^TListViewer;
TListViewer = object(TView)
HScrollBar: PScrollBar;
VScrollBar: PScrollBar;
NumCols: Integer;
TopItem: Integer;
Focused: Integer;
Range: Integer;
constructor Init(var Bounds: TRect; ANumCols: Word;
AHScrollBar, AVScrollBar: PScrollBar);
constructor Load(var S: TStream);
procedure ChangeBounds(var Bounds: TRect); virtual;
procedure Draw; virtual;
procedure FocusItem(Item: Integer); virtual;
function GetPalette: PPalette; virtual;
function GetText(Item: Integer; MaxLen: Integer): String; virtual;
function IsSelected(Item: Integer): Boolean; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure SelectItem(Item: Integer); virtual;
procedure SetRange(ARange: Integer);
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure Store(var S: TStream);
end;
{ Video buffer }
PVideoBuf = ^TVideoBuf;
TVideoBuf = array[0..3999] of Word;
{ Selection modes }
SelectMode = (NormalSelect, EnterSelect, LeaveSelect);
{ TGroup object }
TGroup = object(TView)
Last: PView;
Current: PView;
Phase: (phFocused, phPreProcess, phPostProcess);
Buffer: PVideoBuf;
constructor Init(var Bounds: TRect);
constructor Load(var S: TStream);
destructor Done; virtual;
procedure ChangeBounds(var Bounds: TRect); virtual;
function DataSize: Word; virtual;
procedure Delete(P: PView);
procedure Draw; virtual;
procedure EndModal(Command: Word); virtual;
procedure EventError(var Event: TEvent); virtual;
function ExecView(P: PView): Word;
function Execute: Word; virtual;
function First: PView;
function FirstThat(P: Pointer): PView;
procedure ForEach(P: Pointer);
procedure GetData(var Rec); virtual;
function GetHelpCtx: Word; virtual;
procedure GetSubViewPtr(var S: TStream; var P);
procedure HandleEvent(var Event: TEvent); virtual;
procedure Insert(P: PView);
procedure InsertBefore(P, Target: PView);
procedure Lock;
procedure PutSubViewPtr(var S: TStream; P: PView);
procedure Redraw;
procedure SelectNext(Forwards: Boolean);
procedure SetData(var Rec); virtual;
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure Store(var S: TStream);
procedure Unlock;
function Valid(Command: Word): Boolean; virtual;
end;
{ TWindow object }
{ Palette layout }
{ 1 = Frame passive }
{ 2 = Frame active }
{ 3 = Frame icon }
{ 4 = ScrollBar page area }
{ 5 = ScrollBar controls }
{ 6 = Scroller normal text }
{ 7 = Scroller selected text }
{ 8 = Reserved }
PWindow = ^TWindow;
TWindow = object(TGroup)
Flags: Byte;
ZoomRect: TRect;
Number: Integer;
Palette: Integer;
Frame: PFrame;
Title: PString;
constructor Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Integer);
constructor Load(var S: TStream);
destructor Done; virtual;
procedure Close; virtual;
function GetPalette: PPalette; virtual;
function GetTitle(MaxSize: Integer): TTitleStr; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitFrame; virtual;
procedure SetState(AState: Word; Enable: Boolean); virtual;
procedure SizeLimits(var Min, Max: TPoint); virtual;
function StandardScrollBar(AOptions: Word): PScrollBar;
procedure Store(var S: TStream);
procedure Zoom; virtual;
end;
{ Message dispatch function }
function Message(Receiver: PView; What, Command: Word;
InfoPtr: Pointer): Pointer;
{ Views registration procedure }
procedure RegisterViews;
const
{ Event masks }
PositionalEvents: Word = evMouse;
FocusedEvents: Word = evKeyboard + evCommand;
{ Minimum window size }
MinWinSize: TPoint = (X: 16; Y: 6);
{ Shadow definitions }
ShadowSize: TPoint = (X: 2; Y: 1);
ShadowAttr: Byte = $08;
{ Markers control }
ShowMarkers: Boolean = False;
{ MapColor error return value }
ErrorAttr: Byte = $CF;
{ Stream Registration Records }
RView: TStreamRec = (
ObjType: 1;
VmtLink: Ofs(TypeOf(TView)^);
Load: @TView.Load;
Store: @TView.Store
);
RFrame: TStreamRec = (
ObjType: 2;
VmtLink: Ofs(TypeOf(TFrame)^);
Load: @TFrame.Load;
Store: @TFrame.Store
);
RScrollBar: TStreamRec = (
ObjType: 3;
VmtLink: Ofs(TypeOf(TScrollBar)^);
Load: @TScrollBar.Load;
Store: @TScrollBar.Store
);
RScroller: TStreamRec = (
ObjType: 4;
VmtLink: Ofs(TypeOf(TScroller)^);
Load: @TScroller.Load;
Store: @TScroller.Store
);
RListViewer: TStreamRec = (
ObjType: 5;
VmtLink: Ofs(TypeOf(TListViewer)^);
Load: @TListViewer.Load;
Store: @TLIstViewer.Store
);
RGroup: TStreamRec = (
ObjType: 6;
VmtLink: Ofs(TypeOf(TGroup)^);
Load: @TGroup.Load;
Store: @TGroup.Store
);
RWindow: TStreamRec = (
ObjType: 7;
VmtLink: Ofs(TypeOf(TWindow)^);
Load: @TWindow.Load;
Store: @TWindow.Store
);
{ Characters used for drawing selected and default items in }
{ monochrome color sets }
SpecialChars: array[0..5] of Char = (#175, #174, #26, #27, ' ', ' ');
{ True if the command set has changed since being set to false }
CommandSetChanged: Boolean = False;

View File

@ -0,0 +1,118 @@
{ Copyright (c) 1989,90 by Borland International }
program FigureDemo;
{ From Chapter 4 the Turbo Pascal 6.0 User's Guide.
Extending FIGURES.PAS with type Arc.
If you are running this program in the IDE, be sure to enable
the full graphics save option when you load TURBO.EXE:
turbo -g
This ensures that the IDE fully swaps video RAM and keeps
"dustclouds" from appearing on the user screen when in
graphics mode. You can enable this option permanently
via the Options|Environment|Startup dialog.
This program uses the Graph unit and its .BGI driver files to
display graphics on your system. The "PathToDrivers"
constant defined below is set to \TP\BGI, which is the default
location of the BGI files as installed by the INSTALL program.
If you have installed these files in a different location, make
sure the .BGI file for your system (EGAVGA.BGI, etc.) is in the
current directory or modify the "PathToDrivers" constant
accordingly.
}
uses Crt, DOS, Graph, Figures;
const
PathToDrivers = '\TP\BGI'; { Default location of *.BGI files }
type
Arc = object (Circle)
StartAngle, EndAngle : Integer;
constructor Init(InitX, InitY: Integer; InitRadius: Integer;
InitStartAngle, InitEndAngle: Integer);
procedure Show; virtual;
procedure Hide; virtual;
end;
var
GraphDriver: Integer;
GraphMode: Integer;
ErrorCode: Integer;
AnArc: Arc;
ACircle: Circle;
{--------------------------------------------------------}
{ Arc's method declarations: }
{--------------------------------------------------------}
constructor Arc.Init(InitX,InitY: Integer; InitRadius: Integer;
InitStartAngle, InitEndAngle: Integer);
begin
Circle.Init(InitX, InitY, InitRadius);
StartAngle := InitStartAngle;
EndAngle := InitEndAngle;
end;
procedure Arc.Show;
begin
Visible := True;
Graph.Arc(X, Y, StartAngle, EndAngle, Radius);
end;
procedure Arc.Hide;
var
TempColor: Word;
begin
TempColor := Graph.GetColor;
Graph.SetColor(GetBkColor);
Visible := False;
{ Draw the arc in the background color to hide it }
Graph.Arc(X, Y, StartAngle, EndAngle, Radius);
SetColor(TempColor);
end;
{--------------------------------------------------------}
{ Main program: }
{--------------------------------------------------------}
begin
GraphDriver := Detect; { Let BGI determine which board you're using }
DetectGraph(GraphDriver, GraphMode);
InitGraph(GraphDriver, GraphMode, PathToDrivers);
if GraphResult <> GrOK then
begin
Writeln(GraphErrorMsg(GraphDriver));
if GraphDriver = grFileNotFound then
begin
Writeln('in ', PathToDrivers,
'. Modify this program''s "PathToDrivers"');
Writeln('constant to specify the actual location of this file.');
Writeln;
end;
Writeln('Press Enter...');
Readln;
Halt(1);
end;
{ All descendents of type Point contain virtual methods and }
{ *must* be initialized before use through a constructor call. }
ACircle.Init(151, 82, { Initial X,Y at 151,82 }
50); { Initial radius of 50 pixels }
AnArc.Init(151, 82, { Initial X,Y at 151,82 }
25, 0, 90); { Initial radius of 50 pixels }
{ Start angle: 0; End angle: 90 }
{ Replace AnArc with ACircle to drag a circle instead of an }
{ arc. Press Enter to stop dragging and end the program. }
ACircle.Drag(5); { Parameter is # of pixels to drag by }
CloseGraph;
end.

View File

@ -0,0 +1,197 @@
{ Turbo Figures }
{ Copyright (c) 1989,90 by Borland International, Inc. }
unit Figures;
{ From Chapter 4 the Turbo Pascal 6.0 User's Guide.
Virtual methods & polymorphic objects.
}
interface
uses Graph, Crt;
type
Location = object
X,Y: Integer;
procedure Init(InitX, InitY: Integer);
function GetX: Integer;
function GetY: Integer;
end;
PointPtr = ^Point;
Point = object (Location)
Visible: Boolean;
constructor Init(InitX, InitY: Integer);
destructor Done; virtual;
procedure Show; virtual;
procedure Hide; virtual;
function IsVisible: Boolean;
procedure MoveTo(NewX, NewY: Integer);
procedure Drag(DragBy: Integer); virtual;
end;
CirclePtr = ^Circle;
Circle = object (Point)
Radius: Integer;
constructor Init(InitX, InitY: Integer; InitRadius: Integer);
procedure Show; virtual;
procedure Hide; virtual;
procedure Expand(ExpandBy: Integer); virtual;
procedure Contract(ContractBy: Integer); virtual;
end;
implementation
{--------------------------------------------------------}
{ Location's method implementations: }
{--------------------------------------------------------}
procedure Location.Init(InitX, InitY: Integer);
begin
X := InitX;
Y := InitY;
end;
function Location.GetX: Integer;
begin
GetX := X;
end;
function Location.GetY: Integer;
begin
GetY := Y;
end;
{--------------------------------------------------------}
{ Points's method implementations: }
{--------------------------------------------------------}
constructor Point.Init(InitX, InitY: Integer);
begin
Location.Init(InitX, InitY);
Visible := False;
end;
destructor Point.Done;
begin
Hide;
end;
procedure Point.Show;
begin
Visible := True;
PutPixel(X, Y, GetColor);
end;
procedure Point.Hide;
begin
Visible := False;
PutPixel(X, Y, GetBkColor);
end;
function Point.IsVisible: Boolean;
begin
IsVisible := Visible;
end;
procedure Point.MoveTo(NewX, NewY: Integer);
begin
Hide;
X := NewX;
Y := NewY;
Show;
end;
function GetDelta(var DeltaX: Integer; var DeltaY: Integer): Boolean;
var
KeyChar: Char;
Quit: Boolean;
begin
DeltaX := 0; DeltaY := 0; { 0 means no change in position; }
GetDelta := True; { True means we return a delta }
repeat
KeyChar := ReadKey; { First, read the keystroke }
Quit := True; { Assume it's a useable key }
case Ord(KeyChar) of
0: begin { 0 means an extended, 2-byte code }
KeyChar := ReadKey; { Read second byte of code }
case Ord(KeyChar) of
72: DeltaY := -1; { Up arrow; decrement Y }
80: DeltaY := 1; { Down arrow; increment Y }
75: DeltaX := -1; { Left arrow; decrement X }
77: DeltaX := 1; { Right arrow; increment X }
else Quit := False; { Ignore any other code }
end; { case }
end;
13: GetDelta := False; { CR pressed means no delta }
else Quit := False; { Ignore any other keystroke }
end; { case }
until Quit;
end;
procedure Point.Drag(DragBy: Integer);
var
DeltaX, DeltaY: Integer;
FigureX, FigureY: Integer;
begin
Show; { Display figure to be dragged }
FigureX := GetX; { Get the initial position of figure }
FigureY := GetY;
{ This is the drag loop: }
while GetDelta(DeltaX, DeltaY) do
begin { Apply delta to figure X,Y: }
FigureX := FigureX + (DeltaX * DragBy);
FigureY := FigureY + (DeltaY * DragBy);
MoveTo(FigureX, FigureY); { And tell the figure to move }
end;
end;
{--------------------------------------------------------}
{ Circle's method implementations: }
{--------------------------------------------------------}
constructor Circle.Init(InitX, InitY: Integer; InitRadius: Integer);
begin
Point.Init(InitX, InitY);
Radius := InitRadius;
end;
procedure Circle.Show;
begin
Visible := True;
Graph.Circle(X, Y, Radius);
end;
procedure Circle.Hide;
var
TempColor: Word;
begin
TempColor := Graph.GetColor;
Graph.SetColor(GetBkColor);
Visible := False;
Graph.Circle(X, Y, Radius);
Graph.SetColor(TempColor);
end;
procedure Circle.Expand(ExpandBy: Integer);
begin
Hide;
Radius := Radius + ExpandBy;
if Radius < 0 then Radius := 0;
Show;
end;
procedure Circle.Contract(ContractBy: Integer);
begin
Expand(-ContractBy);
end;
{ No initialization section }
end.

View File

@ -0,0 +1,103 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program Hello;
uses Objects, Drivers, Views, Menus, Dialogs, App;
const
GreetThemCmd = 100;
type
PHelloApp = ^THelloApp;
THelloApp = object(TApplication)
procedure GreetingBox;
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
end;
{ THelloApp }
procedure THelloApp.GreetingBox;
var
R: TRect;
D: PDialog;
C: Word;
begin
{ Create a dialog }
R.Assign(25, 5, 55, 16);
D := New(PDialog, Init(R, 'Hello, World!'));
{ Create and insert controls into the dialog}
R.Assign(3, 5, 15, 6);
D^.Insert(New(PStaticText, Init(R, 'How are you?')));
R.Assign(16, 2, 28, 4);
D^.Insert(New(PButton, Init(R, 'Terrific', cmCancel, bfNormal)));
R.Assign(16, 4, 28, 6);
D^.Insert(New(PButton, Init(R, 'Ok', cmCancel, bfNormal)));
R.Assign(16, 6, 28, 8);
D^.Insert(New(PButton, Init(R, 'Lousy', cmCancel, bfNormal)));
R.Assign(16, 8, 28, 10);
D^.Insert( New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
{ Execute the modal dialog }
C := DeskTop^.ExecView(D);
end;
procedure THelloApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
GreetThemCmd: GreetingBox;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure THelloApp.InitMenuBar;
var
R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~H~ello', hcNoContext, NewMenu(
NewItem('~G~reeting...','', 0, GreetThemCmd, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext, nil)))), nil))));
end;
procedure THelloApp.InitStatusLine;
var
R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y-1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit, nil)), nil)));
end;
var
HelloWorld: THelloApp;
begin
HelloWorld.Init;
HelloWorld.Run;
HelloWorld.Done;
end.

View File

@ -0,0 +1,211 @@
{ Turbo List }
{ Copyright (c) 1989,90 by Borland International, Inc. }
program ListDemo;
{ From Chapter 4 the Turbo Pascal 6.0 User's Guide.
Dynamic objects & destructors.
If you are running this program in the IDE, be sure to enable
the full graphics save option when you load TURBO.EXE:
turbo -g
This ensures that the IDE fully swaps video RAM and keeps
"dustclouds" from appearing on the user screen when in
graphics mode. You can enable this option permanently
via the Options|Environment|Startup dialog.
This program uses the Graph unit and its .BGI driver files to
display graphics on your system. The "PathToDrivers"
constant defined below is set to \TP\BGI, which is the default
location of the BGI files as installed by the INSTALL program.
If you have installed these files in a different location, make
sure the .BGI file for your system (EGAVGA.BGI, etc.) is in the
current directory or modify the "PathToDrivers" constant
accordingly.
}
uses Graph, Figures;
const
PathToDrivers = '\TP\BGI'; { Default location of *.BGI files }
type
ArcPtr = ^Arc;
Arc = object(Circle)
StartAngle, EndAngle: Integer;
constructor Init(InitX, InitY: Integer; InitRadius: Integer;
InitStartAngle, InitEndAngle: Integer);
procedure Show; virtual;
procedure Hide; virtual;
end;
NodePtr = ^Node;
Node = record
Item: PointPtr;
Next: NodePtr;
end;
ListPtr = ^List;
List = object
Nodes: NodePtr;
constructor Init;
destructor Done; virtual;
procedure Add(Item: PointPtr);
procedure Report;
end;
var
GraphDriver: Integer;
GraphMode: Integer;
Temp: String;
AList: List;
PArc: ArcPtr;
PCircle: CirclePtr;
RootNode: NodePtr;
{--------------------------------------------------------}
{ Procedures that are not methods: }
{--------------------------------------------------------}
procedure OutTextLn(TheText: String);
begin
OutText(TheText);
MoveTo(0, GetY+12);
end;
procedure HeapStatus(StatusMessage: String);
begin
Str(MemAvail: 6, Temp);
OutTextLn(StatusMessage+Temp);
end;
{--------------------------------------------------------}
{ Arc's method implementations: }
{--------------------------------------------------------}
constructor Arc.Init(InitX, InitY: Integer; InitRadius: Integer;
InitStartAngle, InitEndAngle: Integer);
begin
Circle.Init(InitX, InitY, InitRadius);
StartAngle := InitStartAngle;
EndAngle := InitEndAngle;
end;
procedure Arc.Show;
begin
Visible := True;
Graph.Arc(X, Y, StartAngle, EndAngle, Radius);
end;
procedure Arc.Hide;
var
TempColor: Word;
begin
TempColor := Graph.GetColor;
Graph.SetColor(GetBkColor);
Visible := False;
Graph.Arc(X, Y, StartAngle, EndAngle, Radius);
SetColor(TempColor);
end;
{--------------------------------------------------------}
{ List's method implementations: }
{--------------------------------------------------------}
constructor List.Init;
begin
Nodes := nil;
end;
destructor List.Done;
var
N: NodePtr;
begin
while Nodes <> nil do
begin
N := Nodes;
Nodes := N^.Next;
Dispose(N^.Item, Done);
Dispose(N);
end;
end;
procedure List.Add(Item: PointPtr);
var
N: NodePtr;
begin
New(N);
N^.Item := Item;
N^.Next := Nodes;
Nodes := N;
end;
procedure List.Report;
var
Current: NodePtr;
begin
Current := Nodes;
while Current <> nil do
begin
Str(Current^.Item^.GetX:3, Temp);
OutTextLn('X = ' + Temp);
Str(Current^.Item^.GetY:3, Temp);
OutTextLn('Y = ' + Temp);
Current := Current^.Next;
end;
end;
{--------------------------------------------------------}
{ Main program: }
{--------------------------------------------------------}
begin
{ Let BGI determine which board you're using: }
DetectGraph(GraphDriver, GraphMode);
InitGraph(GraphDriver, GraphMode, PathToDrivers);
if GraphResult <> GrOK then
begin
Writeln(GraphErrorMsg(GraphDriver));
if GraphDriver = grFileNotFound then
begin
Writeln('in ', PathToDrivers,
'. Modify this program''s "PathToDrivers"');
Writeln('constant to specify the actual location of this file.');
Writeln;
end;
Writeln('Press Enter...');
Readln;
Halt(1);
end;
HeapStatus('Heap space before list is allocated: ');
{ Create a list }
AList.Init;
{ Now create and add several figures to it in one operation }
AList.Add(New(ArcPtr, Init(151, 82, 25, 200, 330)));
AList.Add(New(CirclePtr, Init(400, 100, 40)));
AList.Add(New(CirclePtr, Init(305, 136, 5)));
{ Traverse the list and display X,Y of the list's figures }
AList.Report;
HeapStatus('Heap space after list is allocated ');
{ Deallocate the whole list with one destructor call }
AList.Done;
HeapStatus('Heap space after list is cleaned up: ');
OutText('Press Enter to end program: ');
Readln;
CloseGraph;
end.

View File

@ -0,0 +1,86 @@
{ Turbo Points }
{ Copyright (c) 1989,90 by Borland International }
unit Points;
{ From Chapter 4 the Turbo Pascal 6.0 User's Guide. }
interface
uses Graph;
type
Location = object
X,Y: Integer;
procedure Init(InitX, InitY: Integer);
function GetX: Integer;
function GetY: Integer;
end;
Point = object(Location)
Visible: Boolean;
procedure Init(InitX, InitY: Integer);
procedure Show;
procedure Hide;
function IsVisible: Boolean;
procedure MoveTo(NewX, NewY: Integer);
end;
implementation
{--------------------------------------------------------}
{ Location's method implementations: }
{--------------------------------------------------------}
procedure Location.Init(InitX, InitY: Integer);
begin
X := InitX;
Y := InitY;
end;
function Location.GetX: Integer;
begin
GetX := X;
end;
function Location.GetY: Integer;
begin
GetY := Y;
end;
{--------------------------------------------------------}
{ Points's method implementations: }
{--------------------------------------------------------}
procedure Point.Init(InitX, InitY: Integer);
begin
Location.Init(InitX, InitY);
Visible := False;
end;
procedure Point.Show;
begin
Visible := True;
PutPixel(X, Y, GetColor);
end;
procedure Point.Hide;
begin
Visible := False;
PutPixel(X, Y, GetBkColor);
end;
function Point.IsVisible: Boolean;
begin
IsVisible := Visible;
end;
procedure Point.MoveTo(NewX, NewY: Integer);
begin
Hide;
Location.Init(NewX, NewY);
Show;
end;
end.

View File

@ -0,0 +1,25 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID01;
uses App;
type
TMyApp = object(TApplication)
end;
var
MyApp: TMyApp;
begin
MyApp.Init;
MyApp.Run;
MyApp.Done;
end.

View File

@ -0,0 +1,40 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID02;
uses Objects, Drivers, Views, Menus, App;
type
TMyApp = object(TApplication)
procedure InitStatusLine; virtual;
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)),
nil)
));
end;
var
MyApp: TMyApp;
begin
MyApp.Init;
MyApp.Run;
MyApp.Done;
end.

View File

@ -0,0 +1,68 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID03;
uses Objects, Drivers, Views, Menus, App;
const
cmFileOpen = 100;
cmNewWin = 101;
type
TMyApp = object(TApplication)
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
end;
{ TMyApp }
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
var
MyApp: TMyApp;
begin
MyApp.Init;
MyApp.Run;
MyApp.Done;
end.

View File

@ -0,0 +1,101 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID04;
uses Objects, Drivers, Views, Menus, App;
const
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
type
TMyApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure NewWindow;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 26, 7);
R.Move(Random(58), Random(16));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
MyApp.Init;
MyApp.Run;
MyApp.Done;
end.

View File

@ -0,0 +1,138 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID05;
uses Objects, Drivers, Views, Menus, App;
const
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
type
TMyApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure NewWindow;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
end;
PInterior = ^TInterior;
TInterior = object(TView)
constructor Init(var Bounds: TRect);
procedure Draw; virtual;
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect);
begin
TView.Init(Bounds);
GrowMode := gfGrowHiX + gfGrowHiY;
Options := Options or ofFramed;
end;
procedure TInterior.Draw;
const
Greeting: string = 'Hello, World!';
begin
TView.Draw;
WriteStr(4, 2, Greeting,$01);
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
var
S: string[3];
Interior: PInterior;
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
GetClipRect(Bounds);
Bounds.Grow(-1,-1);
Interior := New(PInterior, Init(Bounds));
Insert(Interior);
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 24, 7);
R.Move(Random(55), Random(16));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
MyApp.Init;
MyApp.Run;
MyApp.Done;
end.

View File

@ -0,0 +1,185 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
{ NOTE: This program intentionally puts up a window
that does not completely draw itself and the result
may be "garbage" characters on the screen.
}
program TVGUID06;
uses Objects, Drivers, Views, Menus, App;
const
FileToRead = 'TVGUID06.PAS';
MaxLines = 100;
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
var
LineCount: Integer;
Lines: array[0..MaxLines - 1] of PString;
type
TMyApp = object(TApplication)
procedure InitStatusLine; virtual;
procedure InitMenuBar; virtual;
procedure NewWindow;
procedure HandleEvent(var Event: TEvent); virtual;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
end;
PInterior = ^TInterior;
TInterior = object(TView)
constructor Init(var Bounds: TRect);
procedure Draw; virtual;
end;
procedure ReadFile;
var
F: Text;
S: String;
begin
LineCount := 0;
Assign(F, FileToRead);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Writeln('Cannot open ', FileToRead);
Halt(1);
end;
while not Eof(F) and (LineCount < MaxLines) do
begin
Readln(F, S);
Lines[LineCount] := NewStr(S);
Inc(LineCount);
end;
Close(F);
end;
procedure DoneFile;
var
I: Integer;
begin
for I := 0 to LineCount - 1 do
if Lines[I] <> nil then DisposeStr(Lines[i]);
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect);
begin
TView.Init(Bounds);
GrowMode := gfGrowHiX + gfGrowHiY;
Options := Options or ofFramed;
end;
procedure TInterior.Draw;
var
Y: Integer;
begin
for Y := 0 to Size.Y - 1 do
begin
WriteStr(0, Y, Lines[Y]^, $01);
end;
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
var
S: string[3];
Interior: PInterior;
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
GetClipRect(Bounds);
Bounds.Grow(-1,-1);
Interior := New(PInterior, Init(Bounds));
Insert(Interior);
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 24, 7);
R.Move(Random(55), Random(16));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
ReadFile;
MyApp.Init;
MyApp.Run;
MyApp.Done;
DoneFile;
end.

View File

@ -0,0 +1,187 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID07;
uses Objects, Drivers, Views, Menus, App;
const
FileToRead = 'TVGUID07.PAS';
MaxLines = 100;
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
var
LineCount: Integer;
Lines: array[0..MaxLines - 1] of PString;
type
TMyApp = object(TApplication)
procedure InitStatusLine; virtual;
procedure InitMenuBar; virtual;
procedure NewWindow;
procedure HandleEvent(var Event: TEvent); virtual;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
end;
PInterior = ^TInterior;
TInterior = object(TView)
constructor Init(var Bounds: TRect);
procedure Draw; virtual;
end;
procedure ReadFile;
var
F: Text;
S: String;
begin
LineCount := 0;
Assign(F, FileToRead);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Writeln('Cannot open ', FileToRead);
Halt(1);
end;
while not Eof(F) and (LineCount < MaxLines) do
begin
Readln(F, S);
Lines[LineCount] := NewStr(S);
Inc(LineCount);
end;
Close(F);
end;
procedure DoneFile;
var
I: Integer;
begin
for I := 0 to LineCount - 1 do
if Lines[I] <> nil then DisposeStr(Lines[i]);
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect);
begin
TView.Init(Bounds);
GrowMode := gfGrowHiX + gfGrowHiY;
Options := Options or ofFramed;
end;
procedure TInterior.Draw;
var
Color: Byte;
Y: Integer;
B: TDrawBuffer;
begin
TView.Draw;
Color := GetColor(1);
for Y := 0 to Size.Y - 1 do
begin
MoveChar(B, ' ', Color, Size.X);
if (Y < LineCount) and (Lines[Y] <> nil) then
MoveStr(B, Copy(Lines[Y]^, 1, Size.X), Color);
WriteLine(0, Y, Size.X, 1, B);
end;
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
var
S: string[3];
Interior: PInterior;
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
GetClipRect(Bounds);
Bounds.Grow(-1, -1);
Interior := New(PInterior, Init(Bounds));
Insert(Interior);
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 24, 7);
R.Move(Random(55), Random(16));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
ReadFile;
MyApp.Init;
MyApp.Run;
MyApp.Done;
DoneFile;
end.

View File

@ -0,0 +1,202 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID08;
uses Objects, Drivers, Views, Menus, App;
const
FileToRead = 'TVGUID08.PAS';
MaxLines = 100;
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
var
LineCount: Integer;
Lines: array[0..MaxLines - 1] of PString;
type
TMyApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure NewWindow;
end;
PInterior = ^TInterior;
TInterior = object(TScroller)
constructor Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
procedure Draw; virtual;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
procedure MakeInterior(Bounds: TRect);
end;
procedure ReadFile;
var
F: Text;
S: String;
begin
LineCount := 0;
Assign(F, FileToRead);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Writeln('Cannot open ', FileToRead);
Halt(1);
end;
while not Eof(F) and (LineCount < MaxLines) do
begin
Readln(F, S);
Lines[LineCount] := NewStr(S);
Inc(LineCount);
end;
Close(F);
end;
procedure DoneFile;
var
I: Integer;
begin
for I := 0 to LineCount - 1 do
if Lines[I] <> nil then DisposeStr(Lines[i]);
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
begin
TScroller.Init(Bounds, AHScrollBar, AVScrollBar);
GrowMode := gfGrowHiX + gfGrowHiY;
Options := Options or ofFramed;
SetLimit(128, LineCount);
end;
procedure TInterior.Draw;
var
Color: Byte;
I, Y: Integer;
B: TDrawBuffer;
begin
Color := GetColor(1);
for Y := 0 to Size.Y - 1 do
begin
MoveChar(B, ' ', Color, Size.X);
i := Delta.Y + Y;
if (I < LineCount) and (Lines[I] <> nil) then
MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color);
WriteLine(0, Y, Size.X, 1, B);
end;
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String;
WindowNo: Word);
var
S: string[3];
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
MakeInterior(Bounds);
end;
procedure TDemoWindow.MakeInterior(Bounds: TRect);
var
HScrollBar, VScrollBar: PScrollBar;
Interior: PInterior;
R: TRect;
begin
VScrollBar := StandardScrollBar(sbVertical + sbHandleKeyboard);
HScrollBar := StandardScrollBar(sbHorizontal + sbHandleKeyboard);
GetExtent(Bounds);
Bounds.Grow(-1,-1);
Interior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar));
Insert(Interior);
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 24, 7);
R.Move(Random(55), Random(16));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
ReadFile;
MyApp.Init;
MyApp.Run;
MyApp.Done;
DoneFile;
end.

View File

@ -0,0 +1,216 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID09;
uses Objects, Drivers, Views, Menus, App;
const
FileToRead = 'TVGUID09.PAS';
MaxLines = 100;
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
var
LineCount: Integer;
Lines: array[0..MaxLines - 1] of PString;
type
TMyApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure NewWindow;
end;
PInterior = ^TInterior;
TInterior = object(TScroller)
constructor Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
procedure Draw; virtual;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
function MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
end;
procedure ReadFile;
var
F: Text;
S: String;
begin
LineCount := 0;
Assign(F, FileToRead);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Writeln('Cannot open ', FileToRead);
Halt(1);
end;
while not Eof(F) and (LineCount < MaxLines) do
begin
Readln(F, S);
Lines[LineCount] := NewStr(S);
Inc(LineCount);
end;
Close(F);
end;
procedure DoneFile;
var
I: Integer;
begin
for I := 0 to LineCount - 1 do
if Lines[I] <> nil then DisposeStr(Lines[i]);
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
begin
TScroller.Init(Bounds, AHScrollBar, AVScrollBar);
Options := Options or ofFramed;
SetLimit(128, LineCount);
end;
procedure TInterior.Draw;
var
Color: Byte;
I, Y: Integer;
B: TDrawBuffer;
begin
Color := GetColor(1);
for Y := 0 to Size.Y - 1 do
begin
MoveChar(B, ' ', Color, Size.X);
i := Delta.Y + Y;
if (I < LineCount) and (Lines[I] <> nil) then
MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color);
WriteLine(0, Y, Size.X, 1, B);
end;
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String;
WindowNo: Word);
var
S: string[3];
R: TRect;
RInterior, LInterior: PInterior;
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
GetExtent(Bounds);
R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y);
LInterior := MakeInterior(R, True);
LInterior^.GrowMode := gfGrowHiY;
Insert(Linterior);
R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y);
RInterior := MakeInterior(R,False);
RInterior^.GrowMode := gfGrowHiX + gfGrowHiY;
Insert(RInterior);
end;
function TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
var
HScrollBar, VScrollBar: PScrollBar;
R: TRect;
begin
R.Assign(Bounds.B.X-1, Bounds.A.Y+1, Bounds.B.X, Bounds.B.Y-1);
VScrollBar := New(PScrollBar, Init(R));
VScrollBar^.Options := VScrollBar^.Options or ofPostProcess;
if Left then VScrollBar^.GrowMode := gfGrowHiY;
Insert(VScrollBar);
R.Assign(Bounds.A.X+2, Bounds.B.Y-1, Bounds.B.X-2, Bounds.B.Y);
HScrollBar := New(PScrollBar, Init(R));
HScrollBar^.Options := HScrollBar^.Options or ofPostProcess;
if Left then HScrollBar^.GrowMode := gfGrowHiY + gfGrowLoY;
Insert(HScrollBar);
Bounds.Grow(-1,-1);
MakeInterior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar));
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 45, 13);
R.Move(Random(34), Random(11));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
ReadFile;
MyApp.Init;
MyApp.Run;
MyApp.Done;
DoneFile;
end.

View File

@ -0,0 +1,224 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID10;
uses Objects, Drivers, Views, Menus, App;
const
FileToRead = 'TVGUID10.PAS';
MaxLines = 100;
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
var
LineCount: Integer;
Lines: array[0..MaxLines - 1] of PString;
type
TMyApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure NewWindow;
end;
PInterior = ^TInterior;
TInterior = object(TScroller)
constructor Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
procedure Draw; virtual;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
RInterior, LInterior: PInterior;
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
function MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
procedure SizeLimits(var Min, Max: TPoint); virtual;
end;
procedure ReadFile;
var
F: Text;
S: String;
begin
LineCount := 0;
Assign(F, FileToRead);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Writeln('Cannot open ', FileToRead);
Halt(1);
end;
while not Eof(F) and (LineCount < MaxLines) do
begin
Readln(F, S);
Lines[LineCount] := NewStr(S);
Inc(LineCount);
end;
Close(F);
end;
procedure DoneFile;
var
I: Integer;
begin
for I := 0 to LineCount - 1 do
if Lines[I] <> nil then DisposeStr(Lines[i]);
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
begin
TScroller.Init(Bounds, AHScrollBar, AVScrollBar);
Options := Options or ofFramed;
SetLimit(128, LineCount);
end;
procedure TInterior.Draw;
var
Color: Byte;
I, Y: Integer;
B: TDrawBuffer;
begin
Color := GetColor(1);
for Y := 0 to Size.Y - 1 do
begin
MoveChar(B, ' ', Color, Size.X);
i := Delta.Y + Y;
if (I < LineCount) and (Lines[I] <> nil) then
MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color);
WriteLine(0, Y, Size.X, 1, B);
end;
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String;
WindowNo: Word);
var
S: string[3];
R: TRect;
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
GetExtent(Bounds);
R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y);
LInterior := MakeInterior(R, True);
LInterior^.GrowMode := gfGrowHiY;
Insert(Linterior);
R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y);
RInterior := MakeInterior(R,False);
RInterior^.GrowMode := gfGrowHiX + gfGrowHiY;
Insert(RInterior);
end;
function TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
var
HScrollBar, VScrollBar: PScrollBar;
R: TRect;
begin
R.Assign(Bounds.B.X - 1, Bounds.A.Y + 1, Bounds.B.X, Bounds.B.Y - 1);
VScrollBar := New(PScrollBar, Init(R));
VScrollBar^.Options := VScrollBar^.Options or ofPostProcess;
if Left then VScrollBar^.GrowMode := gfGrowHiY;
Insert(VScrollBar);
R.Assign(Bounds.A.X + 2, Bounds.B.Y - 1, Bounds.B.X - 2, Bounds.B.Y);
HScrollBar := New(PScrollBar, Init(R));
HScrollBar^.Options := HScrollBar^.Options or ofPostProcess;
if Left then HScrollBar^.GrowMode := gfGrowHiY + gfGrowLoY;
Insert(HScrollBar);
Bounds.Grow(-1, -1);
MakeInterior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar));
end;
procedure TDemoWindow.SizeLimits(var Min, Max: TPoint);
var R: TRect;
begin
TWindow.SizeLimits(Min, Max);
Min.X := LInterior^.Size.X + 9;
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
nil))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 45, 13);
R.Move(Random(34), Random(11));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
ReadFile;
MyApp.Init;
MyApp.Run;
MyApp.Done;
DoneFile;
end.

View File

@ -0,0 +1,242 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID11;
uses Objects, Drivers, Views, Menus, Dialogs, App;
const
FileToRead = 'TVGUID11.PAS';
MaxLines = 100;
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
cmNewDialog = 102;
var
LineCount: Integer;
Lines: array[0..MaxLines - 1] of PString;
type
TMyApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure NewDialog;
procedure NewWindow;
end;
PInterior = ^TInterior;
TInterior = object(TScroller)
constructor Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
procedure Draw; virtual;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
RInterior, LInterior: PInterior;
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
function MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
procedure SizeLimits(var Min, Max: TPoint); virtual;
end;
PDemoDialog = ^TDemoDialog;
TDemoDialog = object(TDialog)
end;
procedure ReadFile;
var
F: Text;
S: String;
begin
LineCount := 0;
Assign(F, FileToRead);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Writeln('Cannot open ', FileToRead);
Halt(1);
end;
while not Eof(F) and (LineCount < MaxLines) do
begin
Readln(F, S);
Lines[LineCount] := NewStr(S);
Inc(LineCount);
end;
Close(F);
end;
procedure DoneFile;
var
I: Integer;
begin
for I := 0 to LineCount - 1 do
if Lines[I] <> nil then DisposeStr(Lines[i]);
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
begin
TScroller.Init(Bounds, AHScrollBar, AVScrollBar);
Options := Options or ofFramed;
SetLimit(128, LineCount);
end;
procedure TInterior.Draw;
var
Color: Byte;
I, Y: Integer;
B: TDrawBuffer;
begin
Color := GetColor(1);
for Y := 0 to Size.Y - 1 do
begin
MoveChar(B, ' ', Color, Size.X);
i := Delta.Y + Y;
if (I < LineCount) and (Lines[I] <> nil) then
MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color);
WriteLine(0, Y, Size.X, 1, B);
end;
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
var
S: string[3];
R: TRect;
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
GetExtent(Bounds);
R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y);
LInterior := MakeInterior(R, True);
LInterior^.GrowMode := gfGrowHiY;
Insert(Linterior);
R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y);
RInterior := MakeInterior(R,False);
RInterior^.GrowMode := gfGrowHiX + gfGrowHiY;
Insert(RInterior);
end;
function TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
var
HScrollBar, VScrollBar: PScrollBar;
R: TRect;
begin
R.Assign(Bounds.B.X-1, Bounds.A.Y+1, Bounds.B.X, Bounds.B.Y-1);
VScrollBar := New(PScrollBar, Init(R));
VScrollBar^.Options := VScrollBar^.Options or ofPostProcess;
if Left then VScrollBar^.GrowMode := gfGrowHiY;
Insert(VScrollBar);
R.Assign(Bounds.A.X+2, Bounds.B.Y-1, Bounds.B.X-2, Bounds.B.Y);
HScrollBar := New(PScrollBar, Init(R));
HScrollBar^.Options := HScrollBar^.Options or ofPostProcess;
if Left then HScrollBar^.GrowMode := gfGrowHiY + gfGrowLoY;
Insert(HScrollBar);
Bounds.Grow(-1,-1);
MakeInterior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar));
end;
procedure TDemoWindow.SizeLimits(var Min, Max: TPoint);
var R: TRect;
begin
TWindow.SizeLimits(Min, Max);
Min.X := LInterior^.Size.X + 9;
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
cmNewDialog: NewDialog;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
NewItem('~D~ialog', 'F2', kbF2, cmNewDialog, hcNoContext,
nil)))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewDialog;
var
Dialog: PDemoDialog;
R: TRect;
begin
R.Assign(0, 0, 40, 13);
R.Move(Random(39), Random(10));
Dialog := New(PDemoDialog, Init(R, 'Demo Dialog'));
DeskTop^.Insert(Dialog);
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 45, 13);
R.Move(Random(34), Random(11));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
ReadFile;
MyApp.Init;
MyApp.Run;
MyApp.Done;
DoneFile;
end.

View File

@ -0,0 +1,244 @@
{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Demo program from the Turbo Vision Guide }
{ }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVGUID12;
uses Objects, Drivers, Views, Menus, App, Dialogs;
const
FileToRead = 'TVGUID12.PAS';
MaxLines = 100;
WinCount: Integer = 0;
cmFileOpen = 100;
cmNewWin = 101;
cmNewDialog = 102;
var
LineCount: Integer;
Lines: array[0..MaxLines - 1] of PString;
type
TMyApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure NewDialog;
procedure NewWindow;
end;
PInterior = ^TInterior;
TInterior = object(TScroller)
constructor Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
procedure Draw; virtual;
end;
PDemoWindow = ^TDemoWindow;
TDemoWindow = object(TWindow)
RInterior, LInterior: PInterior;
constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
function MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
procedure SizeLimits(var Min, Max: TPoint); virtual;
end;
PDemoDialog = ^TDemoDialog;
TDemoDialog = object(TDialog)
end;
procedure ReadFile;
var
F: Text;
S: String;
begin
LineCount := 0;
Assign(F, FileToRead);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Writeln('Cannot open ', FileToRead);
Halt(1);
end;
while not Eof(F) and (LineCount < MaxLines) do
begin
Readln(F, S);
Lines[LineCount] := NewStr(S);
Inc(LineCount);
end;
Close(F);
end;
procedure DoneFile;
var
I: Integer;
begin
for I := 0 to LineCount - 1 do
if Lines[I] <> nil then DisposeStr(Lines[i]);
end;
{ TInterior }
constructor TInterior.Init(var Bounds: TRect; AHScrollBar,
AVScrollBar: PScrollBar);
begin
TScroller.Init(Bounds, AHScrollBar, AVScrollBar);
Options := Options or ofFramed;
SetLimit(128, LineCount);
end;
procedure TInterior.Draw;
var
Color: Byte;
I, Y: Integer;
B: TDrawBuffer;
begin
Color := GetColor(1);
for Y := 0 to Size.Y - 1 do
begin
MoveChar(B, ' ', Color, Size.X);
i := Delta.Y + Y;
if (I < LineCount) and (Lines[I] <> nil) then
MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color);
WriteLine(0, Y, Size.X, 1, B);
end;
end;
{ TDemoWindow }
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
var
S: string[3];
R: TRect;
begin
Str(WindowNo, S);
TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber);
GetExtent(Bounds);
R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y);
LInterior := MakeInterior(R, True);
LInterior^.GrowMode := gfGrowHiY;
Insert(Linterior);
R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y);
RInterior := MakeInterior(R,False);
RInterior^.GrowMode := gfGrowHiX + gfGrowHiY;
Insert(RInterior);
end;
function TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean): PInterior;
var
HScrollBar, VScrollBar: PScrollBar;
R: TRect;
begin
R.Assign(Bounds.B.X-1, Bounds.A.Y+1, Bounds.B.X, Bounds.B.Y-1);
VScrollBar := New(PScrollBar, Init(R));
VScrollBar^.Options := VScrollBar^.Options or ofPostProcess;
if Left then VScrollBar^.GrowMode := gfGrowHiY;
Insert(VScrollBar);
R.Assign(Bounds.A.X+2, Bounds.B.Y-1, Bounds.B.X-2, Bounds.B.Y);
HScrollBar := New(PScrollBar, Init(R));
HScrollBar^.Options := HScrollBar^.Options or ofPostProcess;
if Left then HScrollBar^.GrowMode := gfGrowHiY + gfGrowLoY;
Insert(HScrollBar);
Bounds.Grow(-1,-1);
MakeInterior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar));
end;
procedure TDemoWindow.SizeLimits(var Min, Max: TPoint);
var R: TRect;
begin
TWindow.SizeLimits(Min, Max);
Min.X := LInterior^.Size.X + 9;
end;
{ TMyApp }
procedure TMyApp.HandleEvent(var Event: TEvent);
begin
TApplication.HandleEvent(Event);
if Event.What = evCommand then
begin
case Event.Command of
cmNewWin: NewWindow;
cmNewDialog: NewDialog;
else
Exit;
end;
ClearEvent(Event);
end;
end;
procedure TMyApp.InitMenuBar;
var R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~F~ile', hcNoContext, NewMenu(
NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext,
NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext,
NewLine(
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext,
nil))))),
NewSubMenu('~W~indow', hcNoContext, NewMenu(
NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext,
NewItem('~D~ialog', 'F2', kbF2, cmNewDialog, hcNoContext,
nil)))),
nil))
)));
end;
procedure TMyApp.InitStatusLine;
var R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
NewStatusKey('~F4~ New', kbF4, cmNewWin,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
nil)))),
nil)
));
end;
procedure TMyApp.NewDialog;
var
Dialog: PDemoDialog;
R: TRect;
C: Word;
begin
R.Assign(0, 0, 40, 13);
R.Move(Random(39), Random(10));
Dialog := New(PDemoDialog, Init(R, 'Demo Dialog'));
C := DeskTop^.ExecView(Dialog);
Dispose(Dialog, Done);
end;
procedure TMyApp.NewWindow;
var
Window: PDemoWindow;
R: TRect;
begin
Inc(WinCount);
R.Assign(0, 0, 45, 13);
R.Move(Random(34), Random(11));
Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount));
DeskTop^.Insert(Window);
end;
var
MyApp: TMyApp;
begin
ReadFile;
MyApp.Init;
MyApp.Run;
MyApp.Done;
DoneFile;
end.

Some files were not shown because too many files have changed in this diff Show More