dos_compilers/Borland Turbo Pascal v55/FORMS.PAS
2024-07-02 06:49:04 -07:00

571 lines
11 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ Turbo Forms }
{ Copyright (c) 1989 by Borland International, Inc. }
unit Forms;
{ Turbo Pascal 5.5 object-oriented example.
This unit defines field- and form-editing object types.
Refer to OOPDEMOS.DOC for an overview of this unit.
}
{$S-}
interface
uses Objects;
const
CSkip = ^@;
CHome = ^A;
CRight = ^D;
CPrev = ^E;
CEnd = ^F;
CDel = ^G;
CBack = ^H;
CSave = ^J;
CEnter = ^M;
CUndo = ^R;
CLeft = ^S;
CIns = ^V;
CNext = ^X;
CClear = ^Y;
CEsc = ^[;
type
FStringPtr = ^FString;
FString = string[79];
FieldPtr = ^Field;
Field = object(Node)
X, Y, Size: Integer;
Title: FStringPtr;
Value: Pointer;
Extra: record end;
constructor Init(PX, PY, PSize: Integer; PTitle: FString);
constructor Load(var S: Stream);
destructor Done; virtual;
procedure Clear; virtual;
function Edit: Char; virtual;
procedure Show; virtual;
procedure Store(var S: Stream);
end;
FTextPtr = ^FText;
FText = object(Field)
Len: Integer;
constructor Init(PX, PY, PSize: Integer; PTitle: FString;
PLen: Integer);
function Edit: Char; virtual;
procedure GetStr(var S: FString); virtual;
function PutStr(var S: FString): Boolean; virtual;
procedure Show; virtual;
end;
FStrPtr = ^FStr;
FStr = object(FText)
constructor Init(PX, PY: Integer; PTitle: FString; PLen: Integer);
procedure GetStr(var S: FString); virtual;
function PutStr(var S: FString): Boolean; virtual;
end;
FNumPtr = ^FNum;
FNum = object(FText)
procedure Show; virtual;
end;
FIntPtr = ^FInt;
FInt = object(FNum)
Min, Max: Longint;
constructor Init(PX, PY: Integer; PTitle: FString;
PMin, PMax: Longint);
procedure GetStr(var S: FString); virtual;
function PutStr(var S: FString): Boolean; virtual;
end;
FZipPtr = ^FZip;
FZip = object(FInt)
constructor Init(PX, PY: Integer; PTitle: FString);
procedure GetStr(var S: FString); virtual;
function PutStr(var S: FString): Boolean; virtual;
end;
FRealPtr = ^FReal;
FReal = object(FNum)
Decimals: Integer;
constructor Init(PX, PY: Integer; PTitle: FString;
PLen, PDecimals: Integer);
procedure GetStr(var S: FString); virtual;
function PutStr(var S: FString): Boolean; virtual;
end;
FormPtr = ^Form;
Form = object(Base)
X1, Y1, X2, Y2, Size: Integer;
Fields: List;
constructor Init(PX1, PY1, PX2, PY2: Integer);
constructor Load(var S: Stream);
destructor Done; virtual;
function Edit: Char;
procedure Show(Erase: Boolean);
procedure Add(P: FieldPtr);
procedure Clear;
procedure Get(var FormBuf);
procedure Put(var FormBuf);
procedure Store(var S: Stream);
end;
FStream = object(BufStream)
procedure RegisterTypes; virtual;
end;
ColorIndex = (BackColor, ForeColor, TitleColor, ValueColor);
procedure Beep;
procedure Color(C: ColorIndex);
function ReadChar: Char;
implementation
uses Crt;
type
Bytes = array[0..32767] of Byte;
{ Field }
constructor Field.Init(PX, PY, PSize: Integer; PTitle: FString);
begin
X := PX;
Y := PY;
Size := PSize;
GetMem(Title, Length(PTitle) + 1);
Title^ := PTitle;
GetMem(Value, Size);
end;
constructor Field.Load(var S: Stream);
var
L: Byte;
begin
S.Read(X, SizeOf(Integer) * 3);
S.Read(L, SizeOf(Byte));
GetMem(Title, L + 1);
Title^[0] := Chr(L);
S.Read(Title^[1], L);
GetMem(Value, Size);
S.Read(Extra, SizeOf(Self) - SizeOf(Field));
end;
destructor Field.Done;
begin
FreeMem(Value, Size);
FreeMem(Title, Length(Title^) + 1);
end;
procedure Field.Clear;
begin
FillChar(Value^, Size, 0);
end;
function Field.Edit: Char;
begin
Abstract;
end;
procedure Field.Show;
begin
Abstract;
end;
procedure Field.Store(var S: Stream);
begin
S.Write(X, SizeOf(Integer) * 3);
S.Write(Title^, Length(Title^) + 1);
S.Write(Extra, SizeOf(Self) - SizeOf(Field));
end;
{ FText }
constructor FText.Init(PX, PY, PSize: Integer; PTitle: FString;
PLen: Integer);
begin
Field.Init(PX, PY, PSize, PTitle);
Len := PLen;
end;
function FText.Edit: Char;
var
P: Integer;
Ch: Char;
Start, Stop: Boolean;
S: FString;
begin
P := 0;
Start := True;
Stop := False;
GetStr(S);
repeat
GotoXY(X, Y);
Color(TitleColor);
Write(Title^);
Color(ValueColor);
Write(S, '': Len - Length(S));
GotoXY(X + Length(Title^) + P, Y);
Ch := ReadChar;
case Ch of
#32..#255:
begin
if Start then S := '';
if Length(S) < Len then
begin
Inc(P);
Insert(Ch, S, P);
end;
end;
CLeft: if P > 0 then Dec(P);
CRight: if P < Length(S) then Inc(P) else;
CHome: P := 0;
CEnd: P := Length(S);
CDel: Delete(S, P + 1, 1);
CBack:
if P > 0 then
begin
Delete(S, P, 1);
Dec(P);
end;
CClear:
begin
S := '';
P := 0;
end;
CUndo:
begin
GetStr(S);
P := 0;
end;
CEnter, CNext, CPrev, CSave:
if PutStr(S) then
begin
Show;
Stop := True;
end else
begin
Beep;
P := 0;
end;
CEsc: Stop := True;
else
Beep;
end;
Start := False;
until Stop;
Edit := Ch;
end;
procedure FText.GetStr(var S: FString);
begin
Abstract;
end;
function FText.PutStr(var S: FString): Boolean;
begin
Abstract;
end;
procedure FText.Show;
var
S: FString;
begin
GetStr(S);
GotoXY(X, Y);
Color(TitleColor);
Write(Title^);
Color(ValueColor);
Write(S, '': Len - Length(S));
end;
{ FStr }
constructor FStr.Init(PX, PY: Integer; PTitle: FString; PLen: Integer);
begin
FText.Init(PX, PY, PLen + 1, PTitle, PLen);
end;
procedure FStr.GetStr(var S: FString);
begin
S := FString(Value^);
end;
function FStr.PutStr(var S: FString): Boolean;
begin
FString(Value^) := S;
PutStr := True;
end;
{ FNum }
procedure FNum.Show;
var
S: FString;
begin
GetStr(S);
GotoXY(X, Y);
Color(TitleColor);
Write(Title^);
Color(ValueColor);
Write(S: Len);
end;
{ FInt }
constructor FInt.Init(PX, PY: Integer; PTitle: FString;
PMin, PMax: Longint);
var
L: Integer;
S: string[15];
begin
Str(PMin, S); L := Length(S);
Str(PMax, S); if L < Length(S) then L := Length(S);
FNum.Init(PX, PY, SizeOf(Longint), PTitle, L);
Min := PMin;
Max := PMax;
end;
procedure FInt.GetStr(var S: FString);
begin
Str(Longint(Value^), S);
end;
function FInt.PutStr(var S: FString): Boolean;
var
N: Longint;
E: Integer;
begin
Val(S, N, E);
if (E = 0) and (N >= Min) and (N <= Max) then
begin
Longint(Value^) := N;
PutStr := True;
end else PutStr := False;
end;
{ FZip }
constructor FZip.Init(PX, PY: Integer; PTitle: FString);
begin
FInt.Init(PX, PY, PTitle, 0, 99999);
end;
procedure FZip.GetStr(var S: FString);
begin
FInt.GetStr(S);
Insert(Copy('0000', 1, 5 - Length(S)), S, 1);
end;
function FZip.PutStr(var S: FString): Boolean;
begin
PutStr := (Length(S) = 5) and FInt.PutStr(S);
end;
{ FReal }
constructor FReal.Init(PX, PY: Integer; PTitle: FString;
PLen, PDecimals: Integer);
begin
FNum.Init(PX, PY, SizeOf(Real), PTitle, PLen);
Decimals := PDecimals;
end;
procedure FReal.GetStr(var S: FString);
begin
Str(Real(Value^): 0: Decimals, S);
end;
function FReal.PutStr(var S: FString): Boolean;
var
R: Real;
E: Integer;
T: FString;
begin
Val(S, R, E);
PutStr := False;
if E = 0 then
begin
Str(R: 0: Decimals, T);
if Length(T) <= Len then
begin
Real(Value^) := R;
PutStr := True;
end;
end;
end;
{ Form }
constructor Form.Init(PX1, PY1, PX2, PY2: Integer);
begin
X1 := PX1;
Y1 := PY1;
X2 := PX2;
Y2 := PY2;
Size := 0;
Fields.Clear;
end;
constructor Form.Load(var S: Stream);
begin
S.Read(X1, SizeOf(Integer) * 5);
Fields.Load(S);
end;
destructor Form.Done;
begin
Fields.Delete;
end;
function Form.Edit: Char;
var
P: FieldPtr;
Ch: Char;
begin
Window(X1, Y1, X2, Y2);
P := FieldPtr(Fields.First);
repeat
Ch := P^.Edit;
case Ch of
CEnter, CNext: P := FieldPtr(P^.Next);
CPrev: P := FieldPtr(P^.Prev);
end;
until (Ch = CSave) or (Ch = CEsc);
Edit := Ch;
Window(1, 1, 80, 25);
end;
procedure Form.Show(Erase: Boolean);
var
P: FieldPtr;
begin
Window(X1, Y1, X2, Y2);
if Erase then
begin
Color(ForeColor);
ClrScr;
end;
P := FieldPtr(Fields.First);
while P <> nil do
begin
P^.Show;
P := FieldPtr(Fields.Next(P));
end;
Window(1, 1, 80, 25);
end;
procedure Form.Add(P: FieldPtr);
begin
Inc(Size, P^.Size);
Fields.Append(P);
end;
procedure Form.Clear;
var
P: FieldPtr;
begin
P := FieldPtr(Fields.First);
while P <> nil do
begin
P^.Clear;
P := FieldPtr(Fields.Next(P));
end;
end;
procedure Form.Get(var FormBuf);
var
I: Integer;
P: FieldPtr;
begin
I := 0;
P := FieldPtr(Fields.First);
while P <> nil do
begin
Move(P^.Value^, Bytes(FormBuf)[I], P^.Size);
Inc(I, P^.Size);
P := FieldPtr(Fields.Next(P));
end;
end;
procedure Form.Put(var FormBuf);
var
I: Integer;
P: FieldPtr;
begin
I := 0;
P := FieldPtr(Fields.First);
while P <> nil do
begin
Move(Bytes(FormBuf)[I], P^.Value^, P^.Size);
Inc(I, P^.Size);
P := FieldPtr(Fields.Next(P));
end;
end;
procedure Form.Store(var S: Stream);
begin
S.Write(X1, SizeOf(Integer) * 5);
Fields.Store(S);
end;
{ FStream }
procedure FStream.RegisterTypes;
begin
BufStream.RegisterTypes;
Register(TypeOf(FStr), @FStr.Store, @FStr.Load);
Register(TypeOf(FInt), @FInt.Store, @FInt.Load);
Register(TypeOf(FZip), @FZip.Store, @FZip.Load);
Register(TypeOf(FReal), @FReal.Store, @FReal.Load);
end;
{ Global routines }
procedure Beep;
begin
Sound(500); Delay(25); NoSound;
end;
procedure Color(C: ColorIndex);
type
Palette = array[ColorIndex] of Byte;
const
CP: Palette = ($17, $70, $30, $5E);
MP: Palette = ($07, $70, $70, $07);
begin
if LastMode = CO80 then TextAttr := CP[C] else TextAttr := MP[C];
end;
function ReadChar: Char;
var
Ch: Char;
begin
Ch := ReadKey;
case Ch of
#0:
case ReadKey of
#15, #72: Ch := CPrev; { Shift-Tab, Up }
#60: Ch := CSave; { F2 }
#71: Ch := CHome; { Home }
#75: Ch := CLeft; { Left }
#77: Ch := CRight; { Right }
#79: Ch := CEnd; { End }
#80: Ch := CNext; { Down }
#82: Ch := CIns; { Ins }
#83: Ch := CDel; { Del }
end;
#9: Ch := CNext; { Tab }
end;
ReadChar := Ch;
end;
end.