Borland Turbo Pascal v6
This commit is contained in:
parent
3ccb69b30f
commit
c8956768f2
383
Borland Turbo Pascal v6/BGI/ARTY.PAS
Normal file
383
Borland Turbo Pascal v6/BGI/ARTY.PAS
Normal 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.
|
||||
|
BIN
Borland Turbo Pascal v6/BGI/ATT.BGI
Normal file
BIN
Borland Turbo Pascal v6/BGI/ATT.BGI
Normal file
Binary file not shown.
1422
Borland Turbo Pascal v6/BGI/BGIDEMO.PAS
Normal file
1422
Borland Turbo Pascal v6/BGI/BGIDEMO.PAS
Normal file
File diff suppressed because it is too large
Load Diff
35
Borland Turbo Pascal v6/BGI/BGIDRIV.PAS
Normal file
35
Borland Turbo Pascal v6/BGI/BGIDRIV.PAS
Normal 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.
|
||||
|
31
Borland Turbo Pascal v6/BGI/BGIFONT.PAS
Normal file
31
Borland Turbo Pascal v6/BGI/BGIFONT.PAS
Normal 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.
|
||||
|
31
Borland Turbo Pascal v6/BGI/BGILINK.MAK
Normal file
31
Borland Turbo Pascal v6/BGI/BGILINK.MAK
Normal 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
|
||||
|
126
Borland Turbo Pascal v6/BGI/BGILINK.PAS
Normal file
126
Borland Turbo Pascal v6/BGI/BGILINK.PAS
Normal 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.
|
||||
|
BIN
Borland Turbo Pascal v6/BGI/CGA.BGI
Normal file
BIN
Borland Turbo Pascal v6/BGI/CGA.BGI
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/EGAVGA.BGI
Normal file
BIN
Borland Turbo Pascal v6/BGI/EGAVGA.BGI
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/GOTH.CHR
Normal file
BIN
Borland Turbo Pascal v6/BGI/GOTH.CHR
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/GRAPH.TPU
Normal file
BIN
Borland Turbo Pascal v6/BGI/GRAPH.TPU
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/HERC.BGI
Normal file
BIN
Borland Turbo Pascal v6/BGI/HERC.BGI
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/IBM8514.BGI
Normal file
BIN
Borland Turbo Pascal v6/BGI/IBM8514.BGI
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/LITT.CHR
Normal file
BIN
Borland Turbo Pascal v6/BGI/LITT.CHR
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/PC3270.BGI
Normal file
BIN
Borland Turbo Pascal v6/BGI/PC3270.BGI
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/SANS.CHR
Normal file
BIN
Borland Turbo Pascal v6/BGI/SANS.CHR
Normal file
Binary file not shown.
BIN
Borland Turbo Pascal v6/BGI/TRIP.CHR
Normal file
BIN
Borland Turbo Pascal v6/BGI/TRIP.CHR
Normal file
Binary file not shown.
328
Borland Turbo Pascal v6/DEMOS/BOUNDS.PAS
Normal file
328
Borland Turbo Pascal v6/DEMOS/BOUNDS.PAS
Normal 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.
|
301
Borland Turbo Pascal v6/DEMOS/BREAKOUT.PAS
Normal file
301
Borland Turbo Pascal v6/DEMOS/BREAKOUT.PAS
Normal 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.
|
150
Borland Turbo Pascal v6/DEMOS/BRICKS.PAS
Normal file
150
Borland Turbo Pascal v6/DEMOS/BRICKS.PAS
Normal 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.
|
23
Borland Turbo Pascal v6/DEMOS/CIRCULAR.PAS
Normal file
23
Borland Turbo Pascal v6/DEMOS/CIRCULAR.PAS
Normal 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.
|
238
Borland Turbo Pascal v6/DEMOS/COUNT.PAS
Normal file
238
Borland Turbo Pascal v6/DEMOS/COUNT.PAS
Normal 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.
|
74
Borland Turbo Pascal v6/DEMOS/CPASDEMO.C
Normal file
74
Borland Turbo Pascal v6/DEMOS/CPASDEMO.C
Normal 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 */
|
115
Borland Turbo Pascal v6/DEMOS/CPASDEMO.PAS
Normal file
115
Borland Turbo Pascal v6/DEMOS/CPASDEMO.PAS
Normal 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.
|
146
Borland Turbo Pascal v6/DEMOS/CRTDEMO.PAS
Normal file
146
Borland Turbo Pascal v6/DEMOS/CRTDEMO.PAS
Normal 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.
|
239
Borland Turbo Pascal v6/DEMOS/DIRDEMO.PAS
Normal file
239
Borland Turbo Pascal v6/DEMOS/DIRDEMO.PAS
Normal 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.
|
26
Borland Turbo Pascal v6/DEMOS/DISPLAY.PAS
Normal file
26
Borland Turbo Pascal v6/DEMOS/DISPLAY.PAS
Normal 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.
|
21
Borland Turbo Pascal v6/DEMOS/ERROR.PAS
Normal file
21
Borland Turbo Pascal v6/DEMOS/ERROR.PAS
Normal 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.
|
40
Borland Turbo Pascal v6/DEMOS/EXECDEMO.PAS
Normal file
40
Borland Turbo Pascal v6/DEMOS/EXECDEMO.PAS
Normal 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.
|
44
Borland Turbo Pascal v6/DEMOS/FIB8087.PAS
Normal file
44
Borland Turbo Pascal v6/DEMOS/FIB8087.PAS
Normal 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.
|
212
Borland Turbo Pascal v6/DEMOS/LISTER.PAS
Normal file
212
Borland Turbo Pascal v6/DEMOS/LISTER.PAS
Normal 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.
|
||||
|
52
Borland Turbo Pascal v6/DEMOS/OVRDEMO.PAS
Normal file
52
Borland Turbo Pascal v6/DEMOS/OVRDEMO.PAS
Normal 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.
|
19
Borland Turbo Pascal v6/DEMOS/OVRDEMO1.PAS
Normal file
19
Borland Turbo Pascal v6/DEMOS/OVRDEMO1.PAS
Normal 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.
|
19
Borland Turbo Pascal v6/DEMOS/OVRDEMO2.PAS
Normal file
19
Borland Turbo Pascal v6/DEMOS/OVRDEMO2.PAS
Normal 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.
|
41
Borland Turbo Pascal v6/DEMOS/PROCVAR.PAS
Normal file
41
Borland Turbo Pascal v6/DEMOS/PROCVAR.PAS
Normal 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.
|
66
Borland Turbo Pascal v6/DEMOS/QSORT.PAS
Normal file
66
Borland Turbo Pascal v6/DEMOS/QSORT.PAS
Normal 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.
|
199
Borland Turbo Pascal v6/DEMOS/SCREEN.PAS
Normal file
199
Borland Turbo Pascal v6/DEMOS/SCREEN.PAS
Normal 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.
|
156
Borland Turbo Pascal v6/DEMOS/TCALC/TCALC.DOC
Normal file
156
Borland Turbo Pascal v6/DEMOS/TCALC/TCALC.DOC
Normal 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 ')'
|
||||
;
|
||||
%%
|
||||
|
20
Borland Turbo Pascal v6/DEMOS/TCALC/TCALC.PAS
Normal file
20
Borland Turbo Pascal v6/DEMOS/TCALC/TCALC.PAS
Normal 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.
|
1961
Borland Turbo Pascal v6/DEMOS/TCALC/TCCELL.PAS
Normal file
1961
Borland Turbo Pascal v6/DEMOS/TCALC/TCCELL.PAS
Normal file
File diff suppressed because it is too large
Load Diff
227
Borland Turbo Pascal v6/DEMOS/TCALC/TCCELLSP.PAS
Normal file
227
Borland Turbo Pascal v6/DEMOS/TCALC/TCCELLSP.PAS
Normal 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.
|
40
Borland Turbo Pascal v6/DEMOS/TCALC/TCCOMPAR.ASM
Normal file
40
Borland Turbo Pascal v6/DEMOS/TCALC/TCCOMPAR.ASM
Normal 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
|
BIN
Borland Turbo Pascal v6/DEMOS/TCALC/TCCOMPAR.OBJ
Normal file
BIN
Borland Turbo Pascal v6/DEMOS/TCALC/TCCOMPAR.OBJ
Normal file
Binary file not shown.
261
Borland Turbo Pascal v6/DEMOS/TCALC/TCHASH.PAS
Normal file
261
Borland Turbo Pascal v6/DEMOS/TCALC/TCHASH.PAS
Normal 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.
|
333
Borland Turbo Pascal v6/DEMOS/TCALC/TCINPUT.PAS
Normal file
333
Borland Turbo Pascal v6/DEMOS/TCALC/TCINPUT.PAS
Normal 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.
|
242
Borland Turbo Pascal v6/DEMOS/TCALC/TCLSTR.PAS
Normal file
242
Borland Turbo Pascal v6/DEMOS/TCALC/TCLSTR.PAS
Normal 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.
|
233
Borland Turbo Pascal v6/DEMOS/TCALC/TCMENU.PAS
Normal file
233
Borland Turbo Pascal v6/DEMOS/TCALC/TCMENU.PAS
Normal 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.
|
151
Borland Turbo Pascal v6/DEMOS/TCALC/TCMVSMEM.ASM
Normal file
151
Borland Turbo Pascal v6/DEMOS/TCALC/TCMVSMEM.ASM
Normal 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
|
BIN
Borland Turbo Pascal v6/DEMOS/TCALC/TCMVSMEM.OBJ
Normal file
BIN
Borland Turbo Pascal v6/DEMOS/TCALC/TCMVSMEM.OBJ
Normal file
Binary file not shown.
676
Borland Turbo Pascal v6/DEMOS/TCALC/TCPARSER.PAS
Normal file
676
Borland Turbo Pascal v6/DEMOS/TCALC/TCPARSER.PAS
Normal 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.
|
1366
Borland Turbo Pascal v6/DEMOS/TCALC/TCRUN.PAS
Normal file
1366
Borland Turbo Pascal v6/DEMOS/TCALC/TCRUN.PAS
Normal file
File diff suppressed because it is too large
Load Diff
522
Borland Turbo Pascal v6/DEMOS/TCALC/TCSCREEN.PAS
Normal file
522
Borland Turbo Pascal v6/DEMOS/TCALC/TCSCREEN.PAS
Normal 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.
|
1721
Borland Turbo Pascal v6/DEMOS/TCALC/TCSHEET.PAS
Normal file
1721
Borland Turbo Pascal v6/DEMOS/TCALC/TCSHEET.PAS
Normal file
File diff suppressed because it is too large
Load Diff
378
Borland Turbo Pascal v6/DEMOS/TCALC/TCUTIL.PAS
Normal file
378
Borland Turbo Pascal v6/DEMOS/TCALC/TCUTIL.PAS
Normal 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.
|
42
Borland Turbo Pascal v6/DEMOS/TEST286.PAS
Normal file
42
Borland Turbo Pascal v6/DEMOS/TEST286.PAS
Normal 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.
|
||||
|
13
Borland Turbo Pascal v6/DEMOS/TURBOC.CFG
Normal file
13
Borland Turbo Pascal v6/DEMOS/TURBOC.CFG
Normal file
@ -0,0 +1,13 @@
|
||||
-c
|
||||
-p
|
||||
-r-
|
||||
-u-
|
||||
-zCCODE
|
||||
-zP
|
||||
-zA
|
||||
-zRCONST
|
||||
-zS
|
||||
-zT
|
||||
-zDDATA
|
||||
-zG
|
||||
-zB
|
204
Borland Turbo Pascal v6/DEMOS/WALLS.PAS
Normal file
204
Borland Turbo Pascal v6/DEMOS/WALLS.PAS
Normal 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.
|
284
Borland Turbo Pascal v6/DEMOS/WIN.ASM
Normal file
284
Borland Turbo Pascal v6/DEMOS/WIN.ASM
Normal 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
|
BIN
Borland Turbo Pascal v6/DEMOS/WIN.OBJ
Normal file
BIN
Borland Turbo Pascal v6/DEMOS/WIN.OBJ
Normal file
Binary file not shown.
130
Borland Turbo Pascal v6/DEMOS/WIN.PAS
Normal file
130
Borland Turbo Pascal v6/DEMOS/WIN.PAS
Normal 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.
|
206
Borland Turbo Pascal v6/DEMOS/WINDEMO.PAS
Normal file
206
Borland Turbo Pascal v6/DEMOS/WINDEMO.PAS
Normal 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.
|
113
Borland Turbo Pascal v6/DOC/BUFFERS.DOC
Normal file
113
Borland Turbo Pascal v6/DOC/BUFFERS.DOC
Normal 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.
|
95
Borland Turbo Pascal v6/DOC/CRT.INT
Normal file
95
Borland Turbo Pascal v6/DOC/CRT.INT
Normal 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;
|
||||
|
||||
|
438
Borland Turbo Pascal v6/DOC/DIALOGS.INT
Normal file
438
Borland Turbo Pascal v6/DOC/DIALOGS.INT
Normal 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;
|
152
Borland Turbo Pascal v6/DOC/DOS.INT
Normal file
152
Borland Turbo Pascal v6/DOC/DOS.INT
Normal 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;
|
||||
|
||||
|
235
Borland Turbo Pascal v6/DOC/DRIVERS.INT
Normal file
235
Borland Turbo Pascal v6/DOC/DRIVERS.INT
Normal 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;
|
774
Borland Turbo Pascal v6/DOC/EDITORS.DOC
Normal file
774
Borland Turbo Pascal v6/DOC/EDITORS.DOC
Normal 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.
|
||||
|
134
Borland Turbo Pascal v6/DOC/FIXES.DOC
Normal file
134
Borland Turbo Pascal v6/DOC/FIXES.DOC
Normal 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);
|
||||
|
338
Borland Turbo Pascal v6/DOC/GRAPH.INT
Normal file
338
Borland Turbo Pascal v6/DOC/GRAPH.INT
Normal 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;
|
||||
|
341
Borland Turbo Pascal v6/DOC/HELPME!.DOC
Normal file
341
Borland Turbo Pascal v6/DOC/HELPME!.DOC
Normal 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.
|
||||
|
38
Borland Turbo Pascal v6/DOC/HISTLIST.INT
Normal file
38
Borland Turbo Pascal v6/DOC/HISTLIST.INT
Normal 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;
|
28
Borland Turbo Pascal v6/DOC/MEMORY.INT
Normal file
28
Borland Turbo Pascal v6/DOC/MEMORY.INT
Normal 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);
|
206
Borland Turbo Pascal v6/DOC/MENUS.INT
Normal file
206
Borland Turbo Pascal v6/DOC/MENUS.INT
Normal 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
|
||||
);
|
371
Borland Turbo Pascal v6/DOC/OBJECTS.INT
Normal file
371
Borland Turbo Pascal v6/DOC/OBJECTS.INT
Normal 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);
|
47
Borland Turbo Pascal v6/DOC/OVERLAY.INT
Normal file
47
Borland Turbo Pascal v6/DOC/OVERLAY.INT
Normal 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
|
||||
|
19
Borland Turbo Pascal v6/DOC/PRINTER.INT
Normal file
19
Borland Turbo Pascal v6/DOC/PRINTER.INT
Normal 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;
|
||||
|
65
Borland Turbo Pascal v6/DOC/SYSTEM.INT
Normal file
65
Borland Turbo Pascal v6/DOC/SYSTEM.INT
Normal 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
|
||||
|
941
Borland Turbo Pascal v6/DOC/TEMC.DOC
Normal file
941
Borland Turbo Pascal v6/DOC/TEMC.DOC
Normal 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.
|
55
Borland Turbo Pascal v6/DOC/TEXTVIEW.INT
Normal file
55
Borland Turbo Pascal v6/DOC/TEXTVIEW.INT
Normal 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);
|
182
Borland Turbo Pascal v6/DOC/THELP.DOC
Normal file
182
Borland Turbo Pascal v6/DOC/THELP.DOC
Normal 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'.
|
||||
|
694
Borland Turbo Pascal v6/DOC/TVISION.DOC
Normal file
694
Borland Turbo Pascal v6/DOC/TVISION.DOC
Normal 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.
|
1265
Borland Turbo Pascal v6/DOC/UTILS.DOC
Normal file
1265
Borland Turbo Pascal v6/DOC/UTILS.DOC
Normal file
File diff suppressed because it is too large
Load Diff
558
Borland Turbo Pascal v6/DOC/VIEWS.INT
Normal file
558
Borland Turbo Pascal v6/DOC/VIEWS.INT
Normal 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;
|
118
Borland Turbo Pascal v6/DOCDEMOS/FIGDEMO.PAS
Normal file
118
Borland Turbo Pascal v6/DOCDEMOS/FIGDEMO.PAS
Normal 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.
|
197
Borland Turbo Pascal v6/DOCDEMOS/FIGURES.PAS
Normal file
197
Borland Turbo Pascal v6/DOCDEMOS/FIGURES.PAS
Normal 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.
|
103
Borland Turbo Pascal v6/DOCDEMOS/HELLO.PAS
Normal file
103
Borland Turbo Pascal v6/DOCDEMOS/HELLO.PAS
Normal 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.
|
211
Borland Turbo Pascal v6/DOCDEMOS/LISTDEMO.PAS
Normal file
211
Borland Turbo Pascal v6/DOCDEMOS/LISTDEMO.PAS
Normal 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.
|
86
Borland Turbo Pascal v6/DOCDEMOS/POINTS.PAS
Normal file
86
Borland Turbo Pascal v6/DOCDEMOS/POINTS.PAS
Normal 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.
|
25
Borland Turbo Pascal v6/DOCDEMOS/TVGUID01.PAS
Normal file
25
Borland Turbo Pascal v6/DOCDEMOS/TVGUID01.PAS
Normal 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.
|
40
Borland Turbo Pascal v6/DOCDEMOS/TVGUID02.PAS
Normal file
40
Borland Turbo Pascal v6/DOCDEMOS/TVGUID02.PAS
Normal 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.
|
68
Borland Turbo Pascal v6/DOCDEMOS/TVGUID03.PAS
Normal file
68
Borland Turbo Pascal v6/DOCDEMOS/TVGUID03.PAS
Normal 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.
|
101
Borland Turbo Pascal v6/DOCDEMOS/TVGUID04.PAS
Normal file
101
Borland Turbo Pascal v6/DOCDEMOS/TVGUID04.PAS
Normal 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.
|
138
Borland Turbo Pascal v6/DOCDEMOS/TVGUID05.PAS
Normal file
138
Borland Turbo Pascal v6/DOCDEMOS/TVGUID05.PAS
Normal 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.
|
185
Borland Turbo Pascal v6/DOCDEMOS/TVGUID06.PAS
Normal file
185
Borland Turbo Pascal v6/DOCDEMOS/TVGUID06.PAS
Normal 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.
|
187
Borland Turbo Pascal v6/DOCDEMOS/TVGUID07.PAS
Normal file
187
Borland Turbo Pascal v6/DOCDEMOS/TVGUID07.PAS
Normal 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.
|
202
Borland Turbo Pascal v6/DOCDEMOS/TVGUID08.PAS
Normal file
202
Borland Turbo Pascal v6/DOCDEMOS/TVGUID08.PAS
Normal 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.
|
216
Borland Turbo Pascal v6/DOCDEMOS/TVGUID09.PAS
Normal file
216
Borland Turbo Pascal v6/DOCDEMOS/TVGUID09.PAS
Normal 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.
|
224
Borland Turbo Pascal v6/DOCDEMOS/TVGUID10.PAS
Normal file
224
Borland Turbo Pascal v6/DOCDEMOS/TVGUID10.PAS
Normal 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.
|
242
Borland Turbo Pascal v6/DOCDEMOS/TVGUID11.PAS
Normal file
242
Borland Turbo Pascal v6/DOCDEMOS/TVGUID11.PAS
Normal 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.
|
244
Borland Turbo Pascal v6/DOCDEMOS/TVGUID12.PAS
Normal file
244
Borland Turbo Pascal v6/DOCDEMOS/TVGUID12.PAS
Normal 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
Loading…
Reference in New Issue
Block a user