home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 25
/
CD_ASCQ_25_1095.iso
/
dos
/
prg
/
tjgold
/
install.002
/
GOLDIO.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-07-12
|
101KB
|
3,354 lines
{--------------------------------------------------------------------------}
{ Product: TechnoJock's Turbo Toolkit }
{ Version: GOLD }
{ Build: 1.01 }
{ }
{ Copyright 1986-1995 TechnoJock Software, Inc. }
{ All Rights Reserved }
{ Restricted by License }
{--------------------------------------------------------------------------}
{********************************}
{** Unit: GOLDIO **}
{********************************}
{++++++++++++++++++++++++++++++} unit GOLDIO; {++++++++++++++++++++++++++++++}
{$I GOLDFLAG.INC}
{$IFNDEF GOLDIO}
{$DEFINE GOLDIO}
{$ENDIF}
{++++++++++++++++++++++++++++++++} INTERFACE {+++++++++++++++++++++++++++++++}
uses DOS, CRT, GoldAttr,
GoldHard, GoldTint, GoldMisc, GoldKey, GoldFast,
GoldWin, GoldLink, GoldStr, GoldDate, GoldReal;
const
MaxForms = 10; {alter as necessary}
IntCharacters: set of char = [#129, #132,#142,#148,#153,#154,#225]; {international users modify for your country}
LabelLeft = 0;
LabelTop = -1;
ButtonMarker = 9999;
IDLastField = 255;
NoRules = $00;
AllowNull = $01;
SuppressZero = $02;
RightJustify = $04;
EraseDefault = $08;
JumpIfFull = $10;
NoMID = 255; {used in Makeform}
IOZero = 0;
IOString = 1;
IOByte = 2;
IOWord = 3;
IOInteger = 4;
IOLongInt = 5;
IOReal = 6;
IOPassword = 7;
IOSelect = 8;
IODate = 9;
IOOther = 10;
IOHotkey = 11;
CheckFld = 1;
RadioFld = succ(CheckFld);
ListFld = succ(RadioFld);
ScrollFld = IOString;
RefreshNone = 0;
RefreshCurrent = 1;
RefreshAll = 2;
RefreshOthers = 3;
EndInput = 99;
NoChar = #0;
FirstIOCol = IOEditErase;
LastIOCol = IOListScroll;
type
gCursPos = (CursLeft,CursRight,CursPrev);
gStatus = (Activate, HiStatus, NormStatus, OffStatus);
gValidate = (ValidatebyField,ValidateAtEnd);
gAction = (None,NextField,PrevField,NextForm,PrevForm,
Refresh,Enter,Help,
Stop1,Stop2,Stop3,Stop4,Stop5,Stop6,Stop7,Stop8,Stop9,Stop10,
Stop11,Stop12,Stop13,Stop14,Stop15,Stop16,Stop17,Stop18,Stop19,Stop20,
Stop21,Stop22,Stop23,Stop24,Stop25,Stop26,Stop27,Stop28,Stop29,Stop30,
Stop31,Stop32,Stop33,Stop34,Stop35,Stop36,Stop37,Stop38,Stop39,Stop40,
Stop41,Stop42,Stop43,Stop44,Stop45,Stop46,Stop47,Stop48,Stop49,Stop50,
Stop51,Stop52,Stop53,Stop54,Stop55,Stop56,Stop57,Stop58,Stop59,Stop60,
Stop61,Stop62,Stop63,Stop64,Stop65,Stop66,Stop67,Stop68,Stop69,Stop70,
Stop71,Stop72,Stop73,Stop74,Stop75,Stop76,Stop77,Stop78,Stop79,Stop80,
Stop81,Stop82,Stop83,Stop84,Stop85,Stop86,Stop87,Stop88,Stop89,Stop90,
Stop91,Stop92,Stop93,Stop94,Stop95,Stop96,Stop97,Stop98,Stop99,
Finished,Cancel1,Cancel2,Cancel3,Cancel4,Cancel5,Cancel6,
Cancel7,Cancel8,Cancel9,Escaped);
gActiveState = (FldOff, FldOn, FldHidden);
IOCharSet = set of char;
MoveFieldProc = procedure(var CurrentField:byte;var Refresh:byte);
CharHookProc = procedure(var K : word; var CurrentField:byte;var Refresh:byte);
InsProc = procedure(Insert:boolean);
HindHookProc = procedure(CurrentField:byte;var Refresh:byte);
FinishedProc = function:byte;
FormCloseProc = function(FormID: byte):boolean;
FieldSettingsPtr = ^FieldSettings;
ProcessKeyProc = function(InKey:word;X,Y:byte):gAction;
SuspendProc = function:boolean;
DisplayProc = procedure(FNP:FieldSettingsPtr;Status:gStatus);
HotKeyProc = function(FNP:FieldSettingsPtr;var Key:word;var Act:gAction):boolean;
GenericFieldProc = procedure(FNP:FieldSettingsPtr);
IOTints = array[FirstIOCol..LastIOCol] of byte;
gActionCharSet = record
NextChar: word;
PrevChar: word;
FinishChar: word;
EscChar: word;
UpChar: word;
DownChar: word;
LeftChar: word;
RightChar: word;
EraseChar: word;
end; { gActionCharSet }
ScrollInfoPtr = ^ScrollInfo;
ScrollInfo = record
Maxlen: byte;
StartChar: byte;
ForceCase: gCase;
end;
FieldSettings = record
ID:integer;
MID: byte;
Upfield: byte;
Downfield: byte;
Leftfield: byte;
Rightfield: byte;
X1: byte;
Y1: byte;
X2: byte;
Y2: byte;
IconWidth: byte;
Hotkey: word;
Message: strscreen;
FieldLabel: strscreen;
MsgX: byte;
MsgY: byte;
LabX: shortint;
LabY: shortint;
CursorX: byte;
StrLocX: byte;
FieldLen: byte;
FieldStr: string;
FieldFmt: strscreen;
RealDP: byte;
FieldRules: word;
AllowChar: set of char;
DisAllowChar: set of char;
FirstCharPress: boolean;
UsesCursors: boolean;
UsesEnter: boolean;
Active: gActiveState;
Visible: boolean;
ProcessKeyHook: ProcessKeyProc;
SuspendHook: SuspendProc;
DisplayHook: DisplayProc;
RefreshFieldHook: GenericFieldProc;
UpdateVarHook: GenericFieldProc;
HotKeyHook: HotKeyProc;
DisposeHook: GenericFieldProc;
case FieldType:byte of
IOString : (SPtr: ^string);
IOByte : (BPtr: ^byte;BMax:byte;BMin:byte);
IOWord : (WPtr: ^word;WMax:word;WMin:word);
IOInteger : (IPtr: ^integer;IMax:integer;IMin:integer);
IOLongInt : (LPtr: ^longInt;LMax:longint;LMin:longInt;Delta:longint);
IOReal : (RPtr: ^extended;RMax:extended;RMin:extended);
IODate : (DPtr: ^Dates;DFormat:gDate;DMax:Dates;DMin:Dates);
IOOther : (SourcePtr:pointer; DataPtr,DataPtrS: pointer; DataSize:longint; OMisc:word);
end; { FieldSettings }
FieldNodePtr = ^FieldNode;
FieldNode = record
FieldInfo: FieldSettingsPtr;
NextField: FieldNodePtr;
end; { FieldNode }
FormSettingsPtr = ^FormSettings;
FormSettings = record
Col: IOTints;
AllowEsc: boolean;
WhiteSpace: char;
LeaveFieldHook: MoveFieldProc;
EnterFieldHook: MoveFieldProc;
CharHook: CharHookProc;
HindHook: HindHookProc;
FinishedHook: FinishedProc;
LaunchCloseProc: WinCloseProc;
InsertProc: InsProc;
TotalFields: byte;
ActionChars: gActionCharSet;
DefaultRules: word;
LastAction: gAction;
MsgX: byte;
MsgY: byte;
MsgRestrict: boolean;
MsgLastX: byte;
MsgLastY: byte;
MsgLastL: byte;
OldLine: array [1..160] of byte;
ValState:gValidate;
{INTERNAL}
ActiveField: byte;
PreviousField: byte; {used when help called}
ActiveFieldPtr: FieldNodePtr;
Displayed: boolean;
InsertMode: boolean;
ValidateOnStop: boolean;
FirstField: FieldNodePtr;
WinNum: integer;
DefaultButtonID: byte;
FieldFullOn: boolean;
TInputFinished: boolean;
TSRefresh,TSField: byte;
TRefresh: byte;
DeskFormCloseCallBack: FormCloseProc;
end; { FormSettings }
IOSet = record
LastECode: integer;
EMsgFunc: ErrMsgFunc;
CurrentForm: byte; {the Form with input focus}
TotalForms: byte; {total number of defined Forms}
IChar : char; {last IO character input by user}
ActionChars: gActionCharSet; {default action characters}
WhiteSpace: char;
AllowEsc: boolean;
FieldFullOn: Boolean;
Form: array[0..MaxForms] of FormSettingsPtr; {0th Form is for internal use only}
DefaultRules: word;
DefaultValidate:gValidate;
LastCT: byte; {updated by ActivatePrivateForm}
UsingPrivateForm: boolean;
ValidationMsgTitle:string[40];
ValidationMsgNum:string[60];
ValidationMsgDate:string[60];
ValidationMsgNumPart1:string[60];
ValidationMsgNumPart2:string[20];
ValidationMsgEmpty: string[40];
FieldFullTitle:string[20];
FieldFullMsg: string[100];
end; { IOSet }
{HOOKS}
procedure NoFieldHook(var CurrentField:byte;var Refresh:byte);
procedure NoCharHook(var Ch:word; var CurrentField:byte;var Refresh:byte);
procedure NoHindHook(CurrentField:byte;var Refresh:byte);
function NoFinishedHook:byte;
procedure DefaultInsertHook(On:boolean);
procedure AssignLeaveFieldHook(Proc:MoveFieldProc);
procedure AssignEnterFieldHook(Proc:MoveFieldProc);
procedure AssignCharHook(Proc:CharHookProc);
procedure AssignHindHook(Proc:HindHookProc);
procedure AssignFinishedHook(Proc:FinishedProc);
procedure AssignInsHook(Proc:InsProc);
{Form}
procedure ResetForm(FormNum:byte);
procedure CreateForms(Count:byte);
procedure ActivateForm(FormNo:byte);
procedure DisposeForms;
procedure AssignActionChars(Nxt,Prv,U,D,L,R,Fin,Esc,E: word);
procedure AssignFinishChar(W:word);
procedure AllowEsc(On:boolean);
function FieldWithFocus:integer;
procedure SetDefaultRules(Rules:word);
procedure SetDefaultButton(FieldID:integer);
procedure SetMessageXY(X,Y:byte; InWindow: boolean);
procedure SetInsertMode(On:boolean);
procedure SetFormWindow(X1,Y1,X2,Y2,style:byte);
procedure SetValidation(Val:gValidate);
procedure IOSetColor(A:TintElement;C:byte);
procedure DefineColors(HiFB,LoFB,MsgFB:byte);
function FormWinNum: byte;
function FormExitAction: gAction;
procedure DisposeFormWin;
{FIELD}
procedure AddField(FieldID:integer;DefU,DefD,DefL,DefR,DefX,DefY:byte);
procedure KwikAddField(FieldID:integer;DefX,DefY:byte);
procedure KwikAddLastField(FieldID:integer;DefX,DefY:byte);
procedure DisposeFields;
{FIELD PROPERTIES}
procedure SetMessage(FieldID,X,Y:integer; Str : string);
procedure SetLabel(FieldID,X,Y:integer; Str : string);
procedure SetHK(FieldID:integer; Hotkey: word);
procedure FieldSetState(FieldID:integer; State:gActiveState);
function FieldGetState(FieldID:integer):gActiveState;
procedure FieldRules(FieldID:integer;Rules:word;AChar:IOcharset;DChar:IOcharset);
{Field Assignments}
procedure StringField(FieldID:integer;var Strvar:String;DefFormat:string);
procedure ByteField(FieldID:integer;var Bytevar:Byte;DefFormat:string;Min,Max:byte);
procedure WordField(FieldID:integer;var Wordvar:Word;DefFormat:string;Min,Max : word);
procedure IntegerField(FieldID:integer;var Integervar:Integer;DefFormat:string;Min,Max:Integer);
procedure LongIntField(FieldID:integer;var LongIntvar:LongInt;DefFormat:string;Min,Max : LongInt);
procedure DateField(FieldID:integer;var Datevar:Dates;DateFormat:gDate;DefFormat:string;Min,Max : Dates);
procedure RealField(FieldID:integer;var Realvar:extended;DefFormat:string;Min,Max:extended);
{display procedures}
procedure DisplayAllLabels;
procedure DisplayAllFields;
procedure DisplayForm;
procedure ProcessInput(StartField:byte);
function EditForm(StartField:byte):gAction;
{desktop}
function LaunchFormInit(X1,Y1,X2,Y2,style:byte; CloseProc:FormCloseProc):byte;
procedure LaunchForm(StartField:byte);
{INTERNALS - used by other GOLD units}
procedure IOSetError(ECode:integer);
function LastIOError: integer;
function FieldPtr(FieldID:integer):FieldNodePtr;
procedure DisplayMessage(FSP:FieldSettingsPtr;var Msg:string);
procedure RemoveMessage(FSP:FieldSettingsPtr);
function IsRule(RuleBase:word; Rule:word):boolean;
procedure StrToVar(FSP:FieldSettingsPtr);
procedure OutOfRangeMessage(MinS,MaxS:StrScreen);
procedure CannotBeEmptyMessage;
procedure FieldFullMessage;
function VarToStr(FSP:FieldSettingsPtr):string;
function VarToString(FieldID:integer):String;
procedure BasicDisplay(FNP:FieldSettingsPtr;Status:gStatus);
procedure BasicRefresh(FSP:FieldSettingsPtr);
function BasicKeyHandler(InKey:word;X,Y:byte):gAction;
procedure BasicDisposeHook(FNP:FieldSettingsPtr);
procedure SetCursor(FSP:FieldSettingsPtr);
procedure ActivatePrivateForm;
procedure DisposePrivateForm;
{MakeForm exports}
procedure CheckFormAllocation;
function FieldInfoPtr(Count:integer): FieldSettingsPtr;
function AllocateNewField:FieldSettingsPtr;
procedure SetBasicHooks(FieldInfo:FieldSettingsPtr;SetCurs:boolean);
function FieldHit(X,Y:word; CheckActive:boolean):word;
function GetDateFormatStr(DateFormat:gDate):string;
{$IFDEF TTT5}
procedure Create_Tables(No_Of_Tables:byte);
procedure Activate_Table(Table_no:byte);
procedure Assign_LeaveFieldHook(Proc:MoveFieldProc);
procedure Assign_EnterFieldHook(Proc:MoveFieldProc);
procedure Assign_InsHook(Proc:InsProc);
procedure Create_Fields(No_of_fields:byte);
procedure Define_Colors(HiF,HiB,LoF,LoB,MsgF,MsgB:byte);
procedure Add_Message(DefID,DefX,DefY:byte;DefString:string);
procedure Add_Field(DefID,DefU,DefD,DefL,DefR,DefX,DefY:byte);
procedure String_Field(DefID:byte;var Strvar:String;DefFormat:string);
procedure Assign_Finish_Char(Ch:char);
procedure Byte_Field(DefID:byte;var ByteVar:Byte;DefFormat:string;Min,Max:byte);
procedure Word_Field(DefID:byte;var Wordvar:Word;DefFormat:string;Min,Max:word);
procedure Integer_Field(DefID:byte;var Integervar:integer;DefFormat:string;Min,Max:integer);
procedure LongInt_Field(DefID:byte;var LongIntvar:longint;DefFormat:string;Min,Max:longint);
procedure Date_Field(DefID:byte;var Datevar:Dates;DateFormat:gDate;DefFormat:string;
Min,Max : Dates);
procedure Real_Field(DefID:byte;var Realvar:real;DefFormat:string;Min,Max:real);
procedure Set_Default_Rules(Rules:word);
procedure Field_Rules(DefID:byte;Rules:word;AChar:IOcharset;DChar:IOcharset);
procedure Update_Variables;
procedure Display_All_Fields;
procedure Allow_Esc(OK:boolean);
procedure Allow_Beep(OK:boolean);
procedure Init_Insert_Mode(ON:boolean);
procedure Dispose_Fields;
procedure Dispose_Tables;
procedure Process_Input(StartField:byte);
{$ENDIF}
var IOVars: IOSet;
ActiveForm: FormSettingsPtr;
{+++++++++++++++++++++++++++++} IMPLEMENTATION {+++++++++++++++++++++++++++++}
const
Valid = 0;
NotValid = 1;
var
CurrentForm : byte;
TotalForms : byte;
{******************************}
{** Miscellaneous Routines **}
{******************************}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function IoEMsg(ECode:integer): string;
{}
begin
case Ecode of
0: exit;
1001: IoEMsg := 'Form number out of range, see MAXFormS in GoldIO';
1002: IoEMsg := 'Not enough memory to create Forms';
1003: IoEMsg := 'Cannot activate Form - number out of range';
1004: IoEMsg := 'An AddField did not have a corresponding xxxField, e.g. StringField';
1005: IoEMsg := 'Invalid FieldID specified';
1006: IoEMsg := 'Forms already created - call DisposeForms first';
1007: IoEMsg := 'Field type incompatible with AddItem type';
1008: IoEMsg := 'Insufficient memory to AddItem';
1009: IoEMsg := 'Unable to create Form Window';
1010: IoEMsg := 'Field type incompatible with ScrollForceCase';
else
IoEMsg := 'Internal I/O error';
end; {case}
end; { IoEMsg }
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
procedure IOSetError(ECode:integer);
{}
{$IFOPT D+}
var Msg: string;
{$ENDIF}
begin
IOVars.LastEcode := ECode;
{$IFOPT D+}
if Ecode <> 0 then
begin
str(Ecode,Msg);
Msg := Msg+': '+IOVars.EMsgFunc(Ecode);
SetWinIgnore(true);
if PromptCustom(' GoldIO Error ',Msg,' ~I~gnore ',' ~A~bort ','',279,286,0,0, 10000) = 2 then
Halt;
SetWinIgnore(false);
end;
{$ENDIF}
end; {IOSetError}
function LastIOError: integer;
{}
begin
LastIOError := IOVars.LastECode;
end; { LastIOError }
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
procedure NoFieldHook(var CurrentField:byte;var Refresh:byte);
{empty procs}
begin
Refresh := RefreshNone;
end; { NoFieldHook }
procedure NoCharHook(var Ch:word; var CurrentField:byte;var Refresh:byte);
{empty procs}
begin
Refresh := RefreshNone;
end; { NoCharHook }
procedure NoHindHook(CurrentField:byte;var Refresh:byte);
{empty procs}
begin
Refresh := RefreshNone;
end; { NoHindHook }
function NoFinishedHook:byte;
{}
begin
NoFinishedHook := 0;
end; { NoFinishedHook }
procedure DefaultInsertHook(On:boolean);
{}
begin
if ON then
CursorOn
else
CursorFull;
end; { DefaultInsertHook }
function DefaultProcessKey(InKey:word;X,Y:byte):gAction;
{}
begin
DefaultProcessKey := none;
end; { DefaultProcessKey }
function DefaultSuspend:boolean;
{}
begin
DefaultSuspend := true;
end; { DefaultSuspend }
procedure DefaultDisplay(Status:gStatus);
{}
begin
{abstract}
end; { DefaultDisplay }
function BasicHotKeyHandler(FNP:FieldSettingsPtr;var Key:word;var Act:gAction):boolean;
{}
var Selected: boolean;
begin
if FNP <> nil then with FNP^ do
Selected := (Key <> 0) and (Key = HotKey) and (Active = FldOn)
else
Selected := false;
if Selected then
Key := 0; {absorb the key}
BasicHotkeyHandler := Selected;
end; { BasicHotKeyHandler }
procedure BasicDisposeHook(FNP:FieldSettingsPtr);
{abstract}
begin
end; { BasicDisposeHook }
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
function FieldPtr(FieldID:integer):FieldNodePtr;
{}
var FNP:FieldNodePtr;
begin
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
if FieldID = IDLastField then
while (FNP^.NextField) <> nil do
FNP := FNP^.NextField
else
while (FNP <> nil) and (FNP^.FieldInfo^.ID <> FieldID) do
FNP := FNP^.NextField;
FieldPtr := FNP;
end; { FieldPtr }
function FieldInfoPtr(Count:integer): FieldSettingsPtr;
{}
var FNP: FieldNodePtr;
begin
FNP := FieldPtr(Count);
if FNP = nil then
FieldInfoPtr := nil
else
FieldInfoPtr := FNP^.FieldInfo;
end; { FieldInfoPtr }
function FieldNumber(FNP:FieldNodePtr):integer;
{}
var P: FieldNodePtr;
FN: integer;
begin
if FNP = nil then
FieldNumber := 0
else
FieldNumber := FNP^.FieldInfo^.ID;
end; { FieldNumber }
function IsRule(RuleBase:word; Rule:word):boolean;
{}
begin
IsRule := (RuleBase and Rule) = Rule;
end; { IsRule }
{**********************}
{** Form Routines **}
{**********************}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function IOCloseHandler(Handle: integer):boolean;
{}
var
WinP: WStructurePtr;
begin
{Check to see if form can be closed}
IOCloseHandler := true;
WinDispose(Handle);
end; {IOCloseHandler}
function IgnoreFormClose(Form:byte):boolean;
{No op}
begin
IgnoreFormClose := true;
end; {IgnoreFormClose}
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
procedure ResetForm(FormNum:byte);
var A: TintElement;
begin
with IOVars.Form[FormNum]^ do
begin
for A := FirstIOCol to LastIOCol do
Col[A] := Tint[A];
ActionChars := IOVars.ActionChars;
AllowEsc := IOVars.AllowEsc;
WhiteSpace := IOVars.Whitespace;
LeaveFieldHook := NoFieldHook;
EnterFieldHook := NoFieldHook;
CharHook := NoCharHook;
HindHook := NoHindHook;
LaunchCloseProc := IOCloseHandler;
FinishedHook := NoFinishedHook;
InsertProc := DefaultInsertHook;
FirstField := nil;
ActiveFieldPtr := nil;
TotalFields := 0;
ActiveField := 0;
PreviousField := 0;
WinNum := 0;
DefaultButtonID := 0;
Displayed := false;
ValidateOnStop := true;
DefaultRules := IOVars.DefaultRules;
MsgX := 0;
MsgY := 50; {if its too large TTT automatically sets to last line of display}
MsgRestrict := true; {write in active window}
MsgLastL := 0;
ValState := IOVars.DefaultValidate;
InsertMode := true;
FieldFullOn := IOVars.FieldFullOn;
DeskFormCloseCallBack := IgnoreFormClose;
end;
end; { ResetForm }
procedure CreateForms(Count:byte);
{}
var I: integer;
RoomNeeded: integer;
begin
if IOVars.TotalForms <> 0 then
begin
IOSetError(1006); {Forms already created}
exit;
end;
if Count in [1..MaxForms] then
begin
RoomNeeded := sizeof(IOVars.Form[1]^);
for I := 1 to Count do
begin
if GoldMaxAvail >= RoomNeeded then
begin
getmem(IOVars.Form[I],RoomNeeded);
ResetForm(I)
end else {not enough heap space}
begin
IOSetError(1002);
exit;
end;
end;
for I := succ(Count) to MaxForms do
IOVars.Form[I] := nil;
IOVars.TotalForms := Count;
IOVars.CurrentForm := 1;
ActiveForm := IOVars.Form[1];
end else
IOSetError(1001); {Form out of range}
end; { CreateForms }
procedure ActivatePrivateForm;
{INTERNAL}
var FormSize:integer;
begin
FormSize := sizeof(IOVars.Form[0]^);
if GoldMaxAvail < FormSize then
IOSetError(1002)
else
begin
getmem(IOVars.Form[0],FormSize);
ResetForm(0);
IOVars.LastCT := IOVars.CurrentForm;
IOVars.CurrentForm := 0;
ActiveForm := IOVars.Form[0];
IOVars.UsingPrivateForm := true;
end;
end; { ActivatePrivateForm }
procedure DisposePrivateForm;
{INTERNAL}
begin
with IOVars do
begin
freemem(Form[0],sizeof(Form[0]^));
CurrentForm := LastCT;
ActiveForm := Form[LastCT];
UsingPrivateForm := false;
end;
end; { DisposePrivateForm }
procedure ActivateForm(FormNo:byte);
{}
begin
if FormNo > IOVars.TotalForms then
IOSetError(1003);
IOVars.CurrentForm := FormNo;
ActiveForm := IOVars.Form[FormNo];
end; { ActivateForm }
procedure DisposeForms;
{}
var I: integer;
begin
with IOVars do
begin
for I := 1 to TotalForms do
begin
if Form[I] <> nil then
begin
if Form[I]^.WinNum <> 0 then
WinDispose(Form[I]^.WinNum);
freemem(Form[I],sizeof(Form[I]^));
Form[I] := nil;
end;
end;
TotalForms := 0;
end;
end; { DisposeForms }
procedure CheckFormAllocation;
{}
begin
if not IOVars.UsingPrivateForm and (IOVars.TotalForms = 0) then
CreateForms(1);
end; { CheckFormAllocation }
{************************}
{** Form Properties **}
{************************}
procedure AssignActionChars(Nxt,Prv,U,D,L,R,Fin,Esc,E: word);
{}
begin
CheckFormAllocation;
with IOVars.Form[IOVars.CurrentForm]^.ActionChars do
begin
if Nxt <> 0 then
NextChar := Nxt;
if Prv <> 0 then
PrevChar := Prv;
if Fin <> 0 then
FinishChar := Fin;
if Esc <> 0 then
EscChar := Esc;
if U <> 0 then
UpChar := U;
if D <> 0 then
DownChar := D;
if L <> 0 then
LeftChar := L;
if R <> 0 then
RightChar := R;
if E <> 0 then
EraseChar := E;
end;
end; { AssignActionChars }
procedure AllowEsc(On:boolean);
{For TTT5 compatibility only - use AssignActionChars instead}
begin
if On then
IOVars.Form[IOVars.CurrentForm]^.ActionChars.EscChar := 27
else
IOVars.Form[IOVars.CurrentForm]^.ActionChars.EscChar := 0;
end; { AllowEsc }
function FieldWithFocus:integer;
{}
begin
FieldWithFocus := IOVars.Form[IOVars.CurrentForm]^.ActiveField;
end; { FieldWithFocus }
procedure SetDefaultRules(Rules:word);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.DefaultRules := Rules;
end; { SetDefaultRules }
procedure SetDefaultButton(FieldID:integer);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.DefaultButtonID := byte(FieldID);
end; { SetDefaultRules }
procedure SetValidation(Val:gValidate);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.ValState := Val;
end; { SetValidation }
procedure AssignLeaveFieldHook(Proc:MoveFieldProc);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.LeaveFieldHook := Proc;
end; { AssignLeaveFieldHook }
procedure AssignEnterFieldHook(Proc:MoveFieldProc);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.EnterFieldHook := Proc;
end; { AssignEnterFieldHook }
procedure AssignCharHook(Proc:CharHookProc);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.CharHook := Proc;
end; { AssignCharHook }
procedure AssignFinishedHook(Proc:FinishedProc);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.FinishedHook := Proc;
end; { AssignFinsihedHook }
procedure AssignHindHook(Proc:HindHookProc);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.HindHook := Proc;
end; { AssignHindHook }
procedure AssignInsHook(Proc:InsProc);
{}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.InsertProc := Proc;
end; { AssignInsHook }
procedure AssignFinishChar(W:word);
{For TTT5 compatibility only - use AssignActionChars instead}
begin
CheckFormAllocation;
IOVars.Form[IOVars.CurrentForm]^.ActionChars.FinishChar := W;
end; { AssignFinishChar }
procedure DefineColors(HiFB,LoFB,MsgFB:byte);
{For TTT5 compatibility only - use SetxxxColors instead}
begin
CheckFormAllocation;
with IOVars.Form[IOVars.CurrentForm]^ do
begin
Col[IOEditHi] := HiFB;
Col[IOEditNorm] := LoFB;
Col[IOMessage] := MsgFB;
end;
end; { DefineColors }
procedure SetMessageXY(X,Y:byte; InWindow:boolean);
{Defines the default location for messages. These cordinates are used
when an individual field is assigned an X,Y of 0,0}
begin
CheckFormAllocation;
with IOVars.Form[IOVars.CurrentForm]^ do
begin
MsgX := X;
MsgY := Y;
MsgRestrict := InWindow;
end;
end; { SetMessageXY }
procedure SetInsertMode(On:boolean);
{}
begin
CheckFormAllocation;
with IOVars.Form[IOVars.CurrentForm]^ do
InsertMode := On;
end; { SetInsertMode }
procedure IOSetColor(A:TintElement;C:byte);
{}
begin
if A in [FirstIOCol..LastIOCol] then
IOVars.Form[IOVars.CurrentForm]^.Col[A] := C;
end; { IOSetColor }
procedure SetFormWinColors(WinNum: byte);
{}
begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
WinSetColor(WinNum,WinBody,Col[IOWinBody]);
WinSetColor(WinNum,WinBorder,Col[IOWinBorder1]);
WinSetColor(WinNum,WinBorder,Col[IOWinBorder1]);
WinSetColor(WinNum,WinBorder3DOut,Col[IOWinBorder1]);
WinSetColor(WinNum,WinBorder3DIn,Col[IOWinBorder2]);
WinSetColor(WinNum,WinTitle,Col[IOWinTitle]);
WinSetColor(WinNum,WinIcons,Col[IOWinIcons]);
WinSetColor(WinNum,WinBorderOff,Col[IOWinBorderOff]);
end;
end; {SetFormWinColors}
procedure SetFormWindow(X1,Y1,X2,Y2,style:byte);
{}
begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
WinNum := WinCreate(X1,Y1,X2,Y2,style);
if WinNum = 0 then
IOSetError(1009)
else
SetFormWinColors(WinNum);
end; {with}
end; { SetFormWindow }
function FormWinNum: byte;
{}
begin
FormWinNum := IOVars.Form[IOVars.CurrentForm]^.WinNum;
end; { FormWinNum }
function FormExitAction: gAction;
{}
begin
FormExitAction := IOVars.Form[IOVars.CurrentForm]^.LastAction;
end; { FormExitAction }
function AllocateNewField:FieldSettingsPtr;
{INTERNAL}
begin
if GoldMaxAvail < sizeof(IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^)
+
sizeof(IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^.FieldInfo^)
then
begin
IOSetError(8); {not enough memory to create field}
AllocateNewField := nil;
end else
begin
if IOVars.Form[IOVars.CurrentForm]^.FirstField = nil then {first field}
begin
getmem(IOVars.Form[IOVars.CurrentForm]^.FirstField,
sizeof(IOVars.Form[IOVars.CurrentForm]^.FirstField^));
IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr := IOVars.Form[IOVars.CurrentForm]^.FirstField;
end else
begin
getmem(IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^.NextField,
sizeof(IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^));
IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr := IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^.NextField;
end;
IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^.NextField := nil;
getmem(IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^.FieldInfo,
sizeof(IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^.FieldInfo^));
inc(IOVars.Form[IOVars.CurrentForm]^.ActiveField);
AllocateNewField := IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr^.FieldInfo;
end;
end; { AllocateNewField }
procedure AddField(FieldID:integer;DefU,DefD,DefL,DefR,DefX,DefY:byte);
{}
var FieldDetails: FieldSettingsPtr;
begin
CheckFormAllocation;
FieldDetails := AllocateNewField;
if FieldDetails <> nil then
with FieldDetails^ do
begin
ID := FieldID;
MID := NoMID;
Upfield := DefU;
Downfield := DefD;
Leftfield := DefL;
Rightfield := DefD;
X1 := DefX;
Y1 := DefY;
Y2 := Y1;
IconWidth := 0;
HotKey := 0;
HotKeyHook := BasicHotKeyHandler;
Message := '';
FieldLabel := '';
FieldFmt := '';
MsgX := 0;
MsgY := 0;
FieldRules := IOVars.Form[IOVars.CurrentForm]^.DefaultRules;
inc(IOVars.Form[IOVars.CurrentForm]^.TotalFields);
AllowChar := [NoChar];
DisAllowChar := [NoChar];
FieldType := 0;
UsesCursors := false;
UsesEnter := false;
Active := FldOn;
Visible := true;
DataPtr := nil;
DataSize := 0;
DataPtrS := nil;
OMisc := 0;
end;
end; { AddField }
procedure KwikAddField(FieldID:integer;DefX,DefY:byte);
{}
begin
if FieldID = 1 then
AddField(FieldID,IDLastField,succ(FieldID),IDLastField,succ(FieldID),DefX,DefY)
else
AddField(FieldID,pred(FieldID),succ(FieldID),pred(FieldID),succ(FieldID),DefX,DefY);
end; { KwikAddField }
procedure KwikAddLastField(FieldID:integer;DefX,DefY:byte);
{}
begin
AddField(FieldID,pred(FieldID),1,pred(FieldID),1,DefX,DefY);
end; { KwikAddLastField }
procedure DisposeFormWin;
{}
begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
WinDispose(WinNum);
WinNum := 0;
end;
end; { DisposeFormWin }
procedure DisposeFields;
{Runs down the field list and disposes of the allocated memory}
var Temp1,Temp2: FieldNodePtr;
begin
Temp1 := IOVars.Form[IOVars.CurrentForm]^.FirstField;
while Temp1 <> nil do
begin
Temp2 := Temp1^.NextField;
if Temp1^.FieldInfo <> nil then
begin
Temp1^.FieldInfo^.DisposeHook(Temp1^.FieldInfo);
freemem(Temp1^.FieldInfo,sizeof(Temp1^.FieldInfo^));
end;
freemem(Temp1,sizeof(Temp1^));
Temp1 := Temp2;
end;
with IOVars.Form[IOVars.CurrentForm]^ do
begin
FirstField := nil;
TotalFields := 0;
ActiveField := 0;
if WinNum <> 0 then
DisposeFormWin;
Displayed := false;
end;
end; { DisposeFields }
{************************}
{** Field Properties **}
{************************}
procedure SetMessage(FieldID,X,Y:integer; Str : string);
{}
var FSP: FieldSettingsPtr;
begin
FSP := FieldInfoPtr(FieldID);
if (FSP <> nil) then
with FSP^ do
begin
MsgX := X;
MsgY := Y;
Message := Str;
end
else
IOSetError(5); {invalid field ID}
end; { SetMessage }
procedure SetLabel(FieldID,X,Y:integer; Str: string);
{}
var FSP: FieldSettingsPtr;
begin
FSP := FieldInfoPtr(FieldID);
if (FSP <> nil) then
begin
FSP^.FieldLabel := Str;
FSP^.LabX := X;
FSP^.LabY := Y;
end
else
IOSetError(5); {invalid field ID}
end; { SetLabel }
procedure SetHK(FieldID:integer; Hotkey: word);
{}
var FSP: FieldSettingsPtr;
begin
FSP := FieldInfoPtr(FieldID);
if (FSP <> nil) then
FSP^.HotKey := HotKey
else
IOSetError(5); {invalid field ID}
end; { SetHK }
procedure FieldSetState(FieldID:integer; State:gActiveState);
{}
var FSP: FieldSettingsPtr;
begin
FSP := FieldInfoPtr(FieldID);
if (FSP <> nil) then
FSP^.Active := State;
end; { FieldSetActive }
function FieldGetState(FieldID:integer):gActiveState;
{}
var FSP: FieldSettingsPtr;
begin
FSP := FieldInfoPtr(FieldID);
if (FSP <> nil) then
FieldGetState := FSP^.Active
else
FieldGetState := FldHidden;
end; { FieldGetActive }
{*******************************}
{** Internal Field Routines **}
{*******************************}
function LastCharLeftJustified(Str,Fmt:string): byte;
var LenS,LenF,S,Counter: byte;
begin
Counter := 0;
S := 0;
LenF := length(Fmt);
LenS := length(Str);
repeat
inc(Counter);
if Fmt[Counter] in FmtChars then
Inc(S);
until (S > LenS) or (Counter > LenF);
LastCharLeftJustified := Counter;
end; { LastCharLeftJustified }
function PosofLastInputChar(DefFormat:string): byte;
var Counter: byte;
begin
Counter := succ(length(DefFormat));
repeat
dec(Counter);
until (DefFormat[Counter] in FmtChars) or (Counter = 0);
PosofLastInputChar := counter;
end; { PosofLastInputChar }
procedure SetCursor(FSP:FieldSettingsPtr);
{}
begin
if (FSP <> nil) then
with FSP^ do
begin
if OMisc = ScrollFld then
begin
with FSP^ do
with ScrollInfoPtr(DataPtrS)^ do
if (StrLocX <= length(FieldStr)) then
begin
StrLocX := succ(length(FieldStr));
if (StrLocX - StartChar) > FieldLen then
begin
StartChar := StrLocX - FieldLen;
CursorX := X2;
end else
CursorX := succ(X1) + StrLocX - StartChar;
end;
end else
if IsRule(FieldRules,RightJustify) then
begin
CursorX := pred(X1) + PosofLastInputChar(FieldFmt);
StrLocX := length(FieldStr);
end else
begin
if FieldStr = '' then
StrLocX := 1
else
begin
StrLocX := succ(Length(FieldStr));
if StrLocX > FieldLen then
StrLocX := FieldLen;
end;
CursorX := LastCharLeftJustified(FieldStr,FieldFmt);
if CursorX > length(FieldFmt) then
dec(CursorX);
while ( (FieldFmt[CursorX] in FmtChars) = false)
and (CursorX > 0) do
dec(CursorX);
CursorX := CursorX + pred(X1);
end;
end; {with}
end; { SetCursor }
function MaxStringlength(DefFormat:string) : byte;
var I,Counter: byte;
begin
Counter := 0;
for I := 1 to length(DefFormat) do
if (DefFormat[I] in FmtChars) then
inc(Counter);
MaxStringlength := Counter;
end; { MaxStringLength }
{***********************}
{** Form Management **}
{***********************}
function LabelXCoord(X,FX:shortint;FieldLabel:string): byte;
{Returns the starting column of the field label.
X is the LabX value
FX is the starting column of the field
FieldLabel is the label string
}
var LX: integer;
begin
if X > 0 then
LX := X
else if X = LabelLeft then {zero}
LX := pred(FX)-length(strip('A',Himarker,FieldLabel))
else
LX := FX;
if LX < 1 then
LabelXCoord := 0
else
LabelXCoord := LX;
end; { LabelXCoord }
function LabelYCoord(Y,FY:shortint;FieldLabel:string): byte;
{}
begin
if Y > 0 then
LabelYCoord := Y
else if Y = LabelLeft then
LabelYCoord := FY
else
LabelYCoord := pred(FY);
end; { LabelYCoord }
procedure DisplayLabel(FNP:FieldNodePtr; Hi:boolean);
{}
var X,Y,N,H: byte;
LStart: integer;
begin
if (FNP <> nil) then
with FNP^.FieldInfo^ do
with IOVars.Form[IOVars.CurrentForm]^ do
begin
if FieldLabel <> '' then
begin
if Hi then {assign the display colors based on status}
begin
N := Col[IOLabelHi];
H := Col[IOLabelHiHot];
end else
if Active = FldOn then
begin
N := Col[IOLabelNorm];
H := Col[IOLabelNormHot];
end else
begin
N := Col[IOLabelOff];
H := Col[IOLabelOff];
end;
X := LabelXCoord(LabX,X1,FieldLabel);
Y := LabelYCoord(LabY,Y1,FieldLabel);
if X = 0 then
WriteRight(pred(X1),Y,N,strip('A',Himarker,FieldLabel))
else
WriteHi(X,Y,H,N,FieldLabel);
end;
end;
end; { DisplayLabel }
procedure PaintForm;
{Displays fields, labels and background}
var Temp: WStructurePtr;
begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
if WinNum <> 0 then
begin
Temp := WinPtr(WinNum);
if (Temp <> nil) and not (Temp^.Painted) then
WinPaint(WinNum);
if WinNum = 1 then
WinDrawAll;
ShowNow := false;
WinDisplay(WinNum);
end;
DisplayAllLabels;
Displayed := true;
end;
end; { PaintForm }
procedure DisplayAllFields;
var FNP: FieldNodePtr;
begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
if not Displayed then
PaintForm;
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
while FNP <> nil do
begin
if FNP^.FieldInfo^.MID = NoMID then {not being used in Makeform}
FNP^.FieldInfo^.RefreshFieldHook(FNP^.FieldInfo);
case FNP^.FieldInfo^.Active of
FldOff: FNP^.FieldInfo^.DisplayHook(FNP^.FieldInfo,OffStatus);
FldOn: FNP^.FieldInfo^.DisplayHook(FNP^.FieldInfo,NormStatus);
end; {case}
FNP := FNP^.NextField;
end;
end; {with}
end; { DisplayAllFields }
procedure DisplayAllLabels;
var FNP: FieldNodePtr;
begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
while FNP <> nil do
begin
DisplayLabel(FNP,false);
FNP := FNP^.NextField;
end;
end; {with}
end; { DisplayAllLabels }
procedure DisplayForm;
{}
begin
PaintForm;
DisplayAllFields;
end; { DisplayForm }
procedure UpdateVariables;
{}
var FNP: FieldNodePtr;
begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
while FNP <> nil do
begin
FNP^.FieldInfo^.UpdateVarHook(FNP^.FieldInfo);
FNP := FNP^.NextField;
end;
end; {with}
end; { UpdateVariables }
{*********************************}
{** Basic Variable Management **}
{*********************************}
function VarToStr(FSP:FieldSettingsPtr):string;
{}
var Str: string;
begin
if (FSP <> nil) then
with FSP^ do
begin
case FieldType of
IOString : Str := SPtr^;
IOByte : if (FieldRules and SuppressZero = SuppressZero) and (BPtr^ = 0) then
Str := ''
else
Str := IntToStr(BPtr^);
IOWord : if (FieldRules and SuppressZero = SuppressZero) and (WPtr^ = 0) then
Str := ''
else
Str := IntToStr(WPtr^);
IOInteger : if (FieldRules and SuppressZero = SuppressZero) and (IPtr^ = 0) then
Str := ''
else
Str := IntToStr(IPtr^);
IOLongInt : if (FieldRules and SuppressZero = SuppressZero) and (LPtr^ = 0) then
Str := ''
else
Str := IntToStr(LPtr^);
IODate : if (FieldRules and SuppressZero = SuppressZero) and (DPtr^ = 0) then
Str := ''
else
Str := UnformattedDate(JulToStr(DPtr^,DFormat));
IOReal : if (FieldRules and SuppressZero = SuppressZero) and (RPtr^ = 0.0) then
Str := ''
else
begin
Str := RealToStr(RPtr^,RealDP);
if RealDP <> Floating then
delete(Str,LastPos('.',Str),1);
end;
end; {case}
VarToStr := Str;
end;
end; { VarToStr }
function VarToString(FieldID:integer):String;
{}
var FSP: FieldNodePtr;
begin
FSP := FieldPtr(FieldID);
VarToString := VarToStr(FSP^.FieldInfo);
SetCursor(FSP^.FieldInfo);
end; { VarToString }
procedure FieldRules(FieldID:integer;Rules:word;AChar:IOcharset;DChar:IOcharset);
{}
var FSP: FieldSettingsPtr;
begin
FSP := FieldInfoPtr(FieldID);
if (FSP <> nil) then
with FSP^ do
begin
FieldRules := Rules;
AllowChar := AChar;
if (RealDP <> Floating) and (DChar = [#0]) and (FieldType = IOReal) then
DisAllowChar := ['.']
else
DisallowChar := DChar;
if (FieldType = IOReal)
and (RealDP > 0)
and (RealDP <> Floating) then
FieldRules := FieldRules and RightJustify;
FieldStr := VarToString(FieldID); {sets cursor and updates field string incase change to supress zero}
end else
IOSetError(5); {invalid field ID}
end; {FieldRules}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
procedure BasicRefresh(FSP:FieldSettingsPtr);
{}
begin
if (FSP <> nil) then
with FSP^ do
begin
FieldStr := VarToStr(FSP);
SetCursor(FSP);
end;
end; { BasicRefresh }
procedure StrToVar(FSP:FieldSettingsPtr);
{Updates the variable attached to the field}
begin
if (FSP <> nil) then
with FSP^ do
begin
StrVars.SuppressErrors := true;
case FieldType of
IOString : SPtr^ := FieldStr;
IOByte : BPtr^ := byte(StrtoInt(FieldStr));
IOWord : WPtr^ := word(StrtoInt(FieldStr));
IOInteger : IPtr^ := StrtoInt(FieldStr);
IOLongInt : LPtr^ := StrtoLong(FieldStr);
IOReal : with IOVars.Form[IOVars.CurrentForm]^ do
RPtr^ := StrtoReal(Strip('B',WhiteSpace,
PicFormat(FieldStr,FieldFmt,Whitespace,IsRule(FieldRules,RightJustify))));
IODate : If FieldStr = '' then
DPtr^ := 0
else
DPtr^ := StrtoJul(FieldStr,Dformat);
IOOther : if OMisc = IOString then
SPtr^ := FieldStr;
end; {case}
StrVars.SuppressErrors := false;
end; {with}
(* !! Why AM I DOING THIS
SetCursor(FSP);
*)
end; {StrtoVar}
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
{***************************}
{** Basic Input Handler **}
{***************************}
procedure EraseField(ID:byte);
{}
begin
with ActiveForm^ do
begin
ActiveFieldPtr^.FieldInfo^.FieldStr := '';
ActiveFieldPtr^.FieldInfo^.UpdateVarHook(ActiveFieldPtr^.FieldInfo);
SetCursor(ActiveFieldPtr^.FieldInfo);
end;
end; { EraseField }
procedure CursorRight;
{}
var RJ: boolean;
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
RJ := IsRule(FieldRules,RightJustify);
if (RJ and (StrLocX < length(FieldStr)) and (StrLocX < FieldLen))
or ((RJ=false) and (StrLocX <= length(FieldStr)) and (StrLocX < FieldLen)) then
begin
inc(StrLocX);
repeat
inc(CursorX);
until FieldFmt[CursorX + 1 - X1] in FmtChars;
end;
GotoXY(CursorX,Y1);
end; {with}
end; { CursorRight }
procedure CursorLeft;
{}
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
if (StrLocX > 1)
or (IsRule(FieldRules,RightJustify) and (StrLocX > 0) and (length(FieldStr) <> FieldLen)) then
begin
dec(StrLocX);
repeat
dec(CursorX);
until FieldFmt[CursorX + 1 - X1] in FmtChars;
end;
end; {with}
end; { Cursorleft }
procedure CursorHome;
{}
var Counter1: byte;
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
repeat
Counter1 := CursorX;
CursorLeft;
until Counter1 = CursorX;
end; { CursorHome }
procedure DeleteChar;
{}
var I: integer;
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
if StrLocX > 0 then
begin
delete(FieldStr,StrLocX,1);
if IsRule(FieldRules,RightJustify) then
dec(StrLocX);
end;
end; {with}
end; { DeleteChar }
procedure FieldFullMessage;
{Display a FieldFull message}
begin
Thunk;
if ActiveForm^.FieldFullOn then
PromptOK(IOvars.FieldFullTitle,IOvars.FieldFullMsg);
end; { FieldFullMessage }
procedure InsertCharacter(K : char);
{}
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
if (length(FieldStr) < FieldLen) then
begin
if IsRule(FieldRules,RightJustify) then
begin
inc(StrLocX);
insert(K,FieldStr,StrLocX);
end else
begin
insert(K,FieldStr,StrLocX);
CursorRight;
end;
end else
if (FieldLen = 1) then
FieldStr := K
else
FieldFullMessage;
end;
end; { InsertCharacter }
procedure OverTypeCharacter(K : char);
{}
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
if (StrLocX = 0) and IsRule(FieldRules,RightJustify) then
begin
insert(K,FieldStr,StrLocX);
inc(StrLocX);
end else
begin
delete(FieldStr,StrLocX,1);
insert(K,FieldStr,StrLocX);
CursorRight;
end;
end;
end; { OverTypeCharacter }
procedure Backspaced;
{}
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
if StrLocX > 1 then
begin
if IsRule(FieldRules,RightJustify) then
begin
delete(FieldStr,pred(StrLocX),1);
dec(StrLocX);
end else
begin
CursorLeft;
delete(FieldStr,StrLocX,1);
end;
end;
end;
end; { Backspaced }
{***************************}
{** Basic Field Display **}
{***************************}
procedure Hilight(FNP:FieldSettingsPtr);
{display cell in bright colors}
var Temp: StrScreen;
L,P: byte;
begin
if (FNP <> nil) then
with FNP^ do
with IOVars.Form[IOVars.CurrentForm]^ do
begin
Temp := PicFormat(FieldStr,FieldFmt,Whitespace,IsRule(FieldRules,RightJustify));
if FirstCharPress
and (length(FieldStr) <> 0)
and IsRule(FieldRules,EraseDefault) then
begin
P := pos(WhiteSpace,Temp);
if (P = 0) then
WriteAT(X1,Y1,Col[IOEditErase],Temp)
else
begin
if IsRule(FieldRules,RightJustify) then
begin
P := lastpos(WhiteSpace,Temp);
L := length(FieldFmt);
while (P < L) and not (FieldFmt[succ(P)] in FmtChars) do
inc(P);
WriteAT(X1,Y1,Col[IOEditHi],copy(Temp,1,P));
WriteAT(X1+P,Y1,Col[IOEditErase],copy(Temp,succ(P),80));
end else
begin
WriteAT(X1,Y1,Col[IOEditErase],copy(Temp,1,pred(P)));
WriteAT(X1+pred(P),Y1,Col[IOEditHi],copy(Temp,P,80));
end;
end;
end else
WriteAT(X1,Y1,Col[IOEditHi],Temp);
end;
end; { Hilight }
procedure LoLight(FNP:FieldSettingsPtr);
{display cell in dim colors}
var A: byte;
begin
if (FNP <> nil) then
with FNP^ do
with IOVars.Form[IOVars.CurrentForm]^ do
begin
if FNP^.Active = FldOn then
A := Col[IOEditNorm]
else
A := Col[IOEditOff];
WriteAT(X1,Y1,A,PicFormat(FieldStr,FieldFmt,Whitespace,IsRule(FieldRules,RightJustify)));
end;
end; { LoLight }
procedure ComputeStrLocX(LeftX,RightX:byte);
{Determines the value of StrLocX, based upon the value
of CursorX}
var Temp: string;
I,Counter: integer;
begin
Counter := 0;
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
if IsRule(FieldRules,RightJustify) then
begin
if CursorX = LeftX then
StrLocX := 0
else
begin
Temp := copy(FieldFmt,succ(CursorX-X1),255);
for I := 1 to length(Temp) do
if Temp[I] in FmtChars then
inc(Counter);
StrLocX := succ(length(FieldStr)-Counter);
end;
end else
begin
Temp := copy(FieldFmt,1,succ(RightX-LeftX));
for I := 1 to succ(CursorX - X1) do
if Temp[I] in FmtChars then
inc(Counter);
StrLocX := Counter;
end;
end;
end; { ComputeStrLocX }
procedure MouseStretch;
{user has held mouse down - process the held-down key}
var L,C,R: boolean;
LeftX,RightX,
StartCursX,NewCursX,X,Y,P: byte;
Temp:string;
begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
StartCursX := 0;
Temp := PicFormat(FieldStr,FieldFmt,Whitespace,IsRule(FieldRules,RightJustify));
if IsRule(FieldRules,RightJustify) then
begin
P := lastpos(WhiteSpace,Temp);
if P = 0 then
LeftX := X1
else
LeftX := X1 + pred(P);
RightX := X2;
end else
begin
LeftX := X1;
P := pos(WhiteSpace,Temp);
if P = 0 then
RightX := X2
else
RightX := pred(X1 + P);
end;
repeat
MouseStatusWin(L,C,R,X,Y);
if L and (Y = Y1) and (X >= X1) and (X <= X2) then
begin
if (FieldFmt[succ(X - X1)] in FmtChars)
and (X >= LeftX)
and (X <= RightX) then
begin
NewCursX := X;
if StartCursX = 0 then
StartCursX := NewCursX;
gotoxy(NewCursX,Y1);
if (FirstCharPress) {and (NewCursX <> StartCursX)} then
begin {clear the erase default setting}
FirstCharPress := false;
Hilight(ActiveFieldPtr^.FieldInfo);
end;
CursorX := NewCursX;
end;
end;
until not L;
ComputeStrLocX(LeftX,RightX);
end;
end; { MouseStretch }
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function BasicKeyHandler(InKey:word;X,Y:byte):gAction;
{Input handler used by the traditional TTT5 routines}
var K:char;
begin
BasicKeyHandler := none;
K := WordToChar(InKey);
with ActiveForm^ do
if (ActiveFieldPtr^.FieldInfo^.AllowChar <> [#0])
and (not (K in ActiveFieldPtr^.FieldInfo^.AllowChar)) then
begin
if K <> NoChar then
Beep;
exit;
end;
case Inkey of
32..255 : begin
with ActiveForm^ do
with ActiveFieldPtr^.FieldInfo^ do
begin
if FieldFmt[CursorX - X1 + 1] = '!' then
K := upcase(K);
if (
(AllowChar = [#0])
or ((AllowChar <> [#0]) and (K in AllowChar))
)
and
(
(DisAllowChar = [#0])
or ((DisAllowChar <> [#0]) and ((K in DisAllowChar)= false))
)
then
begin
if ((K in ['0'..'9','.','-','e','E']) and (FieldFmt[CursorX - X1 + 1] = '#'))
or (((K in ['a'..'z','A'..'Z',' ',',','.',';',':']) or (K in IntCharacters )) and
(FieldFmt[CursorX - X1 + 1] = '@'))
or (FieldFmt[CursorX - X1 + 1] = '*')
or (FieldFmt[CursorX - X1 + 1] = '!') then
begin
if FirstCharPress then
begin
if IsRule(FieldRules,EraseDefault) then
EraseField(ActiveField);
FirstCharPress := false;
end;
if InsertMode then
InsertCharacter(K)
else
OverTypeCharacter(K);
end else
Beep;
end; {if}
end; {with}
end;
339: DeleteChar;
331: CursorLeft;
333: CursorRight;
338: with ActiveForm^ do
begin
InsertMode := not InsertMode;
InsertProc(InsertMode);
end;
327: CursorHome;
335: with ActiveForm^ do
SetCursor(ActiveFieldPtr^.FieldInfo);
8 : Backspaced;
500: MouseStretch;
600..1000:; {don't beep}
else
Beep;
end; {case}
end; { BasicKeyHandler }
procedure BasicDisplay(FNP:FieldSettingsPtr;Status:gStatus);
{Display routines used by the traditional TTT5 fields}
begin
case Status of
Activate,
HiStatus: begin
HiLight(FNP);
with FNP^ do
GotoXY(CursorX,Y1);
end;
NormStatus: LoLight(FNP);
OffStatus: LoLight(FNP);
end; {case}
if (Status = Activate) and IsRule(FNP^.FieldRules,EraseDefault) then
begin
if IsRule(FNP^.FieldRules,RightJustify) then
SetCursor(FNP)
else
CursorHome;
with FNP^ do
GotoXY(CursorX,Y1);
end;
end; {BasicDisplay}
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
{*******************************************}
{** Basic Field Validation & Suspension **}
{*******************************************}
procedure InvalidMessage;
{Called when a non-numeric/out-of-range value is encountered}
begin
Beep;
PromptOK(IOvars.ValidationMsgTitle,IOvars.ValidationMsgNum);
end; { InvalidMessage }
procedure InvalidDateMessage(DateFormat:gDate);
{Called when an invalid date is entered}
var FmtStr: string[15];
begin
Beep;
case DateFormat of
MMDDYY : FmtStr := 'MM/DD/YY';
MMDDYYYY : FmtStr := 'MM/DD/YYYY';
MMYY : FmtStr := 'MM/YY';
MMYYYY : FmtStr := 'MM/YYYY';
DDMMYY : FmtStr := 'DD/MM/YY';
DDMMYYYY : FmtStr := 'DD/MM/YYYY';
YYMMDD : FmtStr := 'YY/MM/DD';
YYYYMMDD : FmtStr := 'YYYY/MM/DD';
end; {case}
PromptOK(IOvars.ValidationMsgTitle,IOvars.ValidationMsgDate+FmtStr);
end; { InvalidDateMessage }
procedure OutOfRangeMessage(MinS,MaxS:StrScreen);
{Called when a number is entered outside accepForm range}
begin
Beep;
PromptOK(IOvars.ValidationMsgTitle,IOvars.ValidationMsgNumPart1+MinS+IOvars.ValidationMsgNumPart2+MaxS);
end; { OutOfRangeMessage }
procedure CannotBeEmptyMessage;
{}
begin
PromptOK(IOvars.ValidationMsgTitle,IOvars.ValidationMsgEmpty);
end; { CannotBeEmptyMessage }
procedure ValidateField(FNP:FieldNodePtr; var gResult:byte);
{Called when a user switches from one field to another, or when
the form is closed}
var VL: longint;
VR: extended;
ChV: char;
RetCode: integer;
procedure CheckNumber(Min,Max:longint; Len:byte; StrMax:string);
{}
begin
with FNP^.FieldInfo^ do
begin
if (FieldStr = '') and IsRule(FieldRules,SuppressZero) then
begin
VL := 0;
Retcode := 0;
end else
val(FieldStr,VL,Retcode);
if Retcode <> 0 then
begin
InvalidMessage;
gResult := NotValid;
end else
begin
if (VL < Min)
or (VL > Max)
or ((length(FieldStr) > Len) and (FieldStr > StrMax)) then
begin
OutOfRangeMessage(IntToStr(Min),IntToStr(Max));
gResult := NotValid;
end else
gResult := valid;
end;
end;
end; { CheckNumber }
procedure CheckDate;
{}
begin
with FNP^.FieldInfo^ do
begin
if not ValidDateStr(FieldStr,DFormat) then
begin
InvalidDateMessage(DFormat);
gResult := NotValid;
end else
begin
if (DMin <> 0) and (DMax <> 0) then
begin
VL := StrtoJul(FieldStr,DFormat);
if (VL < DMin)
or (VL > DMax) then
begin
OutOfRangeMessage(JultoStr(DMin,DFormat),JultoStr(DMax,DFormat));
gResult := NotValid;
end else
gResult := valid;
end;
end;
end;
end; { Checkdate }
begin
gResult := Valid; {assume alls well}
with FNP^.FieldInfo^ do
begin
if (FieldStr = '') and IsRule(FieldRules,AllowNull) then
exit;
case FieldType of
IOString : if FieldStr = '' then
begin
gResult := NotValid;
CannotBeEmptyMessage;
end;
IOByte : CheckNumber(BMin,BMax,2,'255');
IOWord : CheckNumber(WMin,WMax,4,'65535');
IOInteger : CheckNumber(IMin,IMax,5,'32767');
IOLongInt : CheckNumber(LMin,LMax,11,'2147483647');
IODate : CheckDate;
IOReal : begin
with IOVars.Form[IOVars.CurrentForm]^ do
val(Strip('B',WhiteSpace,
PicFormat(FieldStr,FieldFmt,Whitespace,IsRule(FieldRules,SuppressZero))),
VR,
Retcode);
if Retcode <> 0 then
begin
InvalidMessage;
gResult := NotValid;
end else
begin
if (VR < RMin)
or (VR > RMax) then
begin
OutOfRangeMessage(RealToStr(RMin,RealDP),RealToStr(RMax,RealDP));
gResult := NotValid;
end;
end;
end;
end; {case}
end;
end; { ValidateField }
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function BasicSuspend:boolean;
{Returns true if the input is valid -- used by the
traditional TTT5 routines}
var ValidInput: byte;
begin
ValidateField(ActiveForm^.ActiveFieldPtr,ValidInput);
BasicSuspend := ValidInput = Valid;
end; { BasicSuspend }
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
{$IFDEF TTT5}
procedure Create_Tables(No_Of_Tables:byte);
{}
begin
CreateForms(No_Of_Tables);
end; { Create_Tables }
procedure Activate_Table(Table_No:byte);
{}
begin
ActivateForm(Table_No);
end; { Activate_Table }
procedure Assign_LeaveFieldHook(Proc:MoveFieldProc);
{}
begin
AssignLeaveFieldHook(Proc);
end; { Assign_LeaveFieldHook }
procedure Assign_EnterFieldHook(Proc:MoveFieldProc);
{}
begin
AssignEnterFieldHook(Proc);
end; { Assign_EnterFieldHook }
procedure Assign_InsHook(Proc:InsProc);
{}
begin
AssignInsHook(Proc);
end; { Assign_InsHook }
procedure Create_Fields(No_of_fields:byte);
{}
begin
{abstract}
end; { Create_Fields }
procedure Define_Colors(HiF,HiB,LoF,LoB,MsgF,MsgB:byte);
{}
begin
DefineColors(Cattr(HiF,HiB),Cattr(LoF,LoB),Cattr(MsgF,MsgB));
end; { Define_Colors }
procedure Add_Message(DefID,DefX,DefY:byte;DefString:string);
{}
begin
SetMessage(DefID,DefX,DefY,DefString);
end; { Add_Message }
procedure Add_Field(DefID,DefU,DefD,DefL,DefR,DefX,DefY:byte);
{}
begin
AddField(DefID,DefU,DefD,DefL,DefR,DefX,DefY);
end; { Add_Field }
procedure String_Field(DefID:byte;var Strvar:String;DefFormat:string);
{}
begin
StringField(DefID,Strvar,DefFormat);
end; { String_Field }
procedure Assign_Finish_Char(Ch:char);
{}
var WCh: word;
begin
Wch := ord(Ch);
AssignFinishChar(WCh);
end; { Assign_Finish_Char }
procedure Byte_Field(DefID:byte;var ByteVar:byte;DefFormat:string;Min,Max:byte);
{}
begin
ByteField(DefID,ByteVar,DefFormat,Min,Max);
end; { Byte_Field }
procedure Word_Field(DefID:byte;var Wordvar:Word;DefFormat:string;Min,Max:word);
{}
begin
WordField(DefID,Wordvar,DefFormat,Min,Max);
end; { Word_Field }
procedure Integer_Field(DefID:byte;var Integervar:Integer;DefFormat:string;Min,Max:integer);
{}
begin
IntegerField(DefID,Integervar,DefFormat,Min,Max);
end; { Integer_Field }
procedure LongInt_Field(DefID:byte;var LongIntvar:longint;DefFormat:string;Min,Max:longint);
{}
begin
LongIntField(DefID,LongIntvar,DefFormat,Min,Max);
end; { LongInt_Field }
procedure Date_Field(DefID:byte;var Datevar:Dates;DateFormat:gDate;DefFormat:string;
Min,Max : Dates);
{}
begin
DateField(DefID,Datevar,DateFormat,DefFormat,Min,Max);
end; { Date_Field }
procedure Real_Field(DefID:byte;var Realvar:real;DefFormat:string;Min,Max:real);
{}
begin
RealField(DefID,Realvar,DefFormat,Min,Max);
end; { Real_Field }
procedure Set_Default_Rules(Rules:word);
{}
begin
SetDefaultRules(Rules);
end; { Set_Default_Rules }
procedure Field_Rules(DefID:byte;Rules:word;AChar:IOcharset;DChar:IOcharset);
{}
begin
FieldRules(DefID,Rules,AChar,DChar);
end; { Field_Rules }
procedure Update_Variables;
{}
begin
{abstract}
end; { Update_Variables }
procedure Display_All_Fields;
{}
begin
DisplayAllFields;
end; { Display_All_Fields }
procedure Allow_Esc(OK:boolean);
{}
begin
AllowEsc(OK);
end; { Allow_Esc }
procedure Allow_Beep(OK:boolean);
{}
begin
{abstract}
end; { Allow_Beep }
procedure Init_Insert_Mode(ON:boolean);
{}
begin
{abstract}
end; { Init_Insert_Mode }
procedure Dispose_Fields;
{}
begin
DisposeFields;
end; { Dispose_Fields }
procedure Dispose_Tables;
{}
begin
DisposeForms;
end; { Dispose_Tables }
procedure Process_Input(StartField:byte);
{}
begin
ProcessInput(StartField);
end; { Process_Input }
{$ENDIF}
{*************************}
{** Field Assignments **}
{*************************}
procedure SetBasicHooks(FieldInfo:FieldSettingsPtr;SetCurs:boolean);
{}
begin
if SetCurs then
SetCursor(FieldInfo);
with FieldInfo^ do
begin
ProcessKeyHook := BasicKeyHandler;
SuspendHook := BasicSuspend;
DisplayHook := BasicDisplay;
UpdateVarHook := StrToVar;
RefreshFieldHook := BasicRefresh;
DisposeHook := BasicDisposeHook;
end;
end; { SetBasicHooks }
procedure StringField(FieldID:integer; var Strvar:string; DefFormat:string);
{}
var FNP: FieldNodePtr;
begin
FNP := FieldPtr(FieldID);
if (FNP <> nil) then
with FNP^.FieldInfo^ do
begin
FieldType := IOString;
SPtr := @StrVar;
FieldStr := Sptr^;
FieldFmt := DefFormat;
FieldLen := MaxStringLength(FieldFmt);
X2 := X1 + pred(length(FieldFmt));
SetBasicHooks(FNP^.FieldInfo,true);
end
else
IOSetError(1005); {invalid field ID}
end; { StringField }
procedure ByteField(FieldID:integer;
var Bytevar:Byte;
DefFormat:string;
Min,Max : byte);
{}
var FNP: FieldNodePtr;
begin
FNP := FieldPtr(FieldID);
if (FNP <> nil) then
with FNP^.FieldInfo^ do
begin
FieldType := IOByte;
BPtr := @Bytevar;
if DefFormat = '' then
FieldFmt := '###'
else
FieldFmt := DefFormat;
FieldStr := VarToString(FieldID);
if (Max = 0) or (Max < Min) then
BMax := 255
else
BMax := Max;
if Min > BMax then
BMin := 0
else
BMin := Min;
FieldLen := MaxStringLength(FieldFmt);
X2 := X1 + pred(length(FieldFmt));
SetBasicHooks(FNP^.FieldInfo,true);
end;
end; { ByteField }
procedure WordField(FieldID:integer;
var Wordvar:Word;
DefFormat:string;
Min,Max : word);
{}
var FNP: FieldNodePtr;
begin
FNP := FieldPtr(FieldID);
if (FNP <> nil) then
with FNP^.FieldInfo^ do
begin
FieldType := IOWord;
WPtr := @WordVar;
if DefFormat = '' then
FieldFmt := '#####'
else
FieldFmt := DefFormat;
FieldStr := VartoString(FieldID);
if (Max = 0) or (Max < Min) then
WMax := 65535
else
WMax := Max;
if Min > WMax then
WMin := 0
else
WMin := MIn;
FieldLen := MaxStringLength(FieldFmt);
X2 := X1 + pred(length(FieldFmt));
SetBasicHooks(FNP^.FieldInfo,true);
end;
end; { WordField }
procedure IntegerField(FieldID:integer;
var Integervar:Integer;
DefFormat:string;
Min,Max:Integer);
{}
var FNP: FieldNodePtr;
begin
FNP := FieldPtr(FieldID);
if (FNP <> nil) then
with FNP^.FieldInfo^ do
begin
FieldType := IOInteger;
IPtr := @IntegerVar;
if DefFormat = '' then
FieldFmt := '######'
else
FieldFmt := DefFormat;
FieldStr := VartoString(FieldID);
if (Max = 0) or (Max < Min) then
IMax := 32767
else
IMax := Max;
if ((Min = 0) and (Max = 0)) or (Min > WMax) then
IMin := -32768
else
IMin := Min;
FieldLen := MaxStringLength(FieldFmt);
X2 := X1 + pred(length(FieldFmt));
SetBasicHooks(FNP^.FieldInfo,true);
end;
end; { IntegerField }
procedure LongIntField(FieldID:integer;
var LongIntvar:LongInt;
DefFormat:string;
Min,Max : LongInt);
{}
var FNP: FieldNodePtr;
begin
FNP := FieldPtr(FieldID);
if (FNP <> nil) then
with FNP^.FieldInfo^ do
begin
FieldType := IOLongInt;
LPtr := @LongIntVar;
if DefFormat = '' then
FieldFmt := '###########'
else
FieldFmt := DefFormat;
FieldStr := VartoString(FieldID);
if (max = 0) or (Max < Min) then
LMax := 2147483647
else
LMax := Max;
if ((Min = 0) and (Max = 0)) or (Min > LMax) then
LMin := -2147483647
else
LMin := Min;
FieldLen := MaxStringLength(FieldFmt);
X2 := X1 + pred(length(FieldFmt));
SetBasicHooks(FNP^.FieldInfo,true);
end;
end; { LongIntField }
function GetDateFormatStr(DateFormat:gDate):string;
{}
var FieldFmt: string;
begin
case DateFormat of
DDMMYY,
MMDDYY,
YYMMDD : FieldFmt := '##'+DateVars.dSeparator+'##'+DateVars.dSeparator+'##';
MMYY : FIeldFmt := '##'+DateVars.dSeparator+'##';
MMYYYY : FieldFmt := '##'+DateVars.dSeparator+'####';
DDMMYYYY,
MMDDYYYY : FieldFmt := '##'+DateVars.dSeparator+'##'+DateVars.dSeparator+'####';
YYYYMMDD : FieldFmt := '####'+DateVars.dSeparator+'##'+DateVars.dSeparator+'##';
end; {case}
GetDateFormatStr := FieldFmt;
end; { GetDateFormatStr }
procedure DateField(FieldID:integer;
var Datevar:Dates;
DateFormat:gDate;
DefFormat:string;
Min,Max : Dates);
{}
var FNP: FieldNodePtr;
begin
FNP := FieldPtr(FieldID);
if (FNP <> nil) then
with FNP^.FieldInfo^ do
begin
FieldType := IODate;
SPtr := @DateVar;
if DateVar = 0 then
FieldStr := ''
else
FieldStr := Unformatteddate(JultoStr(DateVar,DateFormat));
if DefFormat = '' then
FieldFmt := GetDateFormatStr(DateFormat)
else
FieldFmt := DefFormat;
if (Max = 0) or (Max < Min) then
DMax := 0
else
DMax := Max;
if Min > WMax then
DMin := 0
else
DMin := Min;
DFormat := DateFormat;
FieldLen := MaxStringLength(FieldFmt);
X2 := X1 + pred(length(FieldFmt));
SetBasicHooks(FNP^.FieldInfo,true);
end;
end; { DateField }
procedure RealField(FieldID:integer;
var Realvar:extended;
DefFormat:string;
Min,Max : extended);
{}
var FNP: FieldNodePtr;
P : byte;
begin
FNP := FieldPtr(FieldID);
if (FNP <> nil) then
with FNP^.FieldInfo^ do
begin
FieldType := IOReal;
RPtr := @RealVar;
if DefFormat = '' then
FieldFmt := '############'
else
FieldFmt := DefFormat;
P := LastPos('.',FieldFmt);
if P = 0 then
RealDP := Floating
else
begin
RealDP := Length(FieldFmt) - P;
if RealDP = 0 then
delete(FieldFmt,P,1); {remove the end decimal place}
end;
RMax := Max;
RMin := Min;
if RealDP <> Floating then
begin
DisAllowChar := ['.'];
if (RealDP <> 0) then
FieldRules := FieldRules and RightJustify; {force right justify}
end;
FieldStr := VartoString(FieldID);
FieldLen := MaxStringLength(FieldFmt);
X2 := X1 + pred(length(FieldFmt));
SetBasicHooks(FNP^.FieldInfo,true);
end;
end; { RealField }
{*********************}
{** Process Input **}
{*********************}
function OnTarget(FNP:FieldNodePtr; X,Y:word):boolean;
{Do the XY coords fall within the specified field}
var Hit: boolean;
XL,L:byte;
begin
if FNP = nil then
Hit := false
else
with FNP^.FieldInfo^ do
begin
Hit := (X >= X1)
and ( ((X <= X2) and (Y >= Y1) and (Y <= Y2))
or ((X <= X2 + IconWidth) and (Y = Y1)));
if not Hit
and (FieldLabel <> '')
and (Y=LabelYCoord(LabY,Y1,FieldLabel)) then
begin
XL := LabelXCoord(LabX,X1,FieldLabel);
L := length(strip('A',Himarker,FieldLabel));
if XL = 0 then
Hit := (X >= 1) and (X <= L)
else
Hit := (X >= XL) and (X < XL + L);
end;
end;
OnTarget := Hit;
end; { OnTarget }
function FieldHit(X,Y:word; CheckActive:boolean):word;
{Determines if the coordinates fall on a specific field - if not
a zero is returned}
var FNP: FieldNodePtr;
Counter: integer;
begin
with ActiveForm^ do
begin
if OnTarget(ActiveFieldPtr,X,Y) then
FieldHit := ActiveField
else
begin
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
Counter := 1;
while FNP <> nil do
begin
if OnTarget(FNP,X,Y)
and (FNP^.FieldInfo^.Visible or (FNP^.FieldInfo^.HotKey = 500))
and ( (CheckActive = false)
or (FNP^.FieldInfo^.Active = FldOn)
) then
begin
FieldHit := Counter;
exit;
end else
begin
FNP := FNP^.NextField;
inc(Counter);
end;
end;
FieldHit := 0;
end;
end;
end; { FieldHit }
procedure DisplayMessage(FSP:FieldSettingsPtr;var Msg:string);
{}
var L: byte;
begin
with ActiveForm^ do
with FSP^ do
begin
if Msg <> '' then
begin
if (MsgX = 0) and (MsgY = 0) then
begin
MsgLastX := ActiveForm^.MsgX;
MsgLastY := ActiveForm^.MsgY;
end else
begin
MsgLastX := MsgX;
MsgLastY := MsgY;
end;
L := length(Msg);
if MsgLastX = 0 then {Center the message}
begin
if L >= VideoTarget.Width then
MsgLastX := 1
else
MsgLastX := (VideoTarget.Width - L) div 2;
end;
if MsgLastX < 1 then
MsgLastX := 1;
if (MsgLastY < 1) or (MsgLastY > HardVars.Depth) then
MsgLastY := HardVars.Depth;
with VideoTarget do
if WindowActive and MsgRestrict then
PartSave(MsgLastX+pred(WX1),MsgLastY+pred(WY1),MsgLastX+pred(WX1)+L,MsgLastY+pred(WY1),OldLine)
else if MsgRestrict or (VideoTarget.TargetType <> WinTarget) then
PartSave(MsgLastX,MsgLastY,MsgLastX+pred(WX1)+L,MsgLastY,OldLine);
if not MsgRestrict and (VideoTarget.TargetType = WinTarget) then
begin
ActivateBackground;
PartSave(MsgLastX,MsgLastY,MsgLastX+L,MsgLastY,OldLine);
WriteAT(MsgLastX,MsgLastY,
IOVars.Form[IOVars.CurrentForm]^.Col[IOMessage],Msg);
WinDrawAll;
ActivateTopWindow;
end else
WriteAT(MsgLastX,MsgLastY,
IOVars.Form[IOVars.CurrentForm]^.Col[IOMessage],Msg);
MsgLastL := L;
end;
end;
end; { DisplayMessage }
procedure RemoveMessage(FSP:FieldSettingsPtr);
var I,LocC: integer;
begin
with ActiveForm^ do
with FSP^ do
if (MsgLastL > 0) then
begin
with VideoTarget do
if WindowActive and MsgRestrict then
PartRestore(MsgLastX+pred(WX1),MsgLastY+pred(WY1),pred(MsgLastX+MsgLastL)+pred(WX1),
MsgLastY+pred(WY1),OldLine)
else if not MsgRestrict and (VideoTarget.TargetType = WinTarget) then
begin
ActivateBackground;
PartRestore(MsgLastX,MsgLastY,pred(MsgLastX+MsgLastL),MsgLastY,OldLine);
WinDrawAll;
ActivateTopWindow;
end else
PartRestore(MsgLastX,MsgLastY,pred(MsgLastX+MsgLastL),MsgLastY,OldLine);
MsgLastL := 0;
end;
end; { RemoveMessage }
procedure CallIOHelp(CField:integer);
{Sets the help record and calls the general help function}
var Helpdata: HelpRecord;
begin
with HelpData do
begin
Context := ContextIO + IOVars.CurrentForm;
ID := CField;
HelpLong := ActiveForm^.PreviousField;
end;
CallForHelp(ContextIO,HelpData);
end; { CallIOHelp }
{************************}
{** Input Management **}
{************************}
procedure CheckRefreshState(Refresh:byte; HiLightActiveFld:boolean);
{}
var FNP: FieldNodePtr;
I: integer;
begin
with ActiveForm^ do
case Refresh of
RefreshNone : ; {do nothing}
RefreshCurrent: begin
ActiveFieldPtr^.FieldInfo^.RefreshFieldHook(ActiveFieldPtr^.FieldInfo);
if ActiveFieldPtr^.FieldInfo^.Active <> FldHidden then
ActiveFieldPtr^.FieldInfo^.DisplayHook(ActiveFieldPtr^.FieldInfo,HiStatus);
end;
RefreshAll: begin
DisplayAllFields;
DisplayAllLabels;
if HiLightActiveFld and (ActiveFieldPtr^.FieldInfo^.Active <> FldHidden) then
ActiveFieldPtr^.FieldInfo^.DisplayHook(ActiveFieldPtr^.FieldInfo,HiStatus);
end;
RefreshOthers: begin
with IOVars.Form[IOVars.CurrentForm]^ do
begin
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
while FNP <> nil do
begin
if FNP^.FieldInfo^.ID <> ActiveField then
begin
FNP^.FieldInfo^.RefreshFieldHook(FNP^.FieldInfo);
case FNP^.FieldInfo^.Active of
FldOff: FNP^.FieldInfo^.DisplayHook(FNP^.FieldInfo,OffStatus);
FldOn: FNP^.FieldInfo^.DisplayHook(FNP^.FieldInfo,NormStatus);
end; {case}
end;
FNP := FNP^.NextField;
end;
Displayed := true;
end; {with}
end;
EndInput : begin
DisplayAllFields;
TInputFinished := true;
ActiveForm^.LastAction := Finished;
end;
end; {case}
end; { CheckRefreshState }
function NextFieldID(Direction:byte): byte;
{Returns the ID of the next *ACTIVE* and *VISIBLE* field in the
direction specified}
var StartFNP,
FNP: FieldNodePtr;
Counter: integer;
begin
with ActiveForm^ do
begin
case Direction of
1: begin
if ActiveFieldPtr^.FieldInfo^.UpField = IDLastField then
FNP := FieldPtr(TotalFields)
else
FNP := FieldPtr(ActiveFieldPtr^.FieldInfo^.UpField);
end;
2: FNP := FieldPtr(ActiveFieldPtr^.FieldInfo^.DownField);
3: begin
if ActiveFieldPtr^.FieldInfo^.LeftField = IDLastField then
FNP := FieldPtr(TotalFields)
else
FNP := FieldPtr(ActiveFieldPtr^.FieldInfo^.LeftField);
end;
4: FNP := FieldPtr(ActiveFieldPtr^.FieldInfo^.RightField);
end;
StartFNP := nil;
Counter := 1;
while (FNP <> nil)
and (FNP <> StartFNP)
and (FNP^.FieldInfo <> nil)
and ( (FNP^.FieldInfo^.Active <> FldOn)
or
(FNP^.FieldInfo^.Visible = false)
)
and (Counter <= 250) do {just in case it might loop forever}
begin
inc(Counter);
if StartFNP = nil then
StartFNP := FNP;
case Direction of
1: FNP := FieldPtr(FNP^.FieldInfo^.UpField);
2: FNP := FieldPtr(FNP^.FieldInfo^.DownField);
3: FNP := FieldPtr(FNP^.FieldInfo^.LeftField);
4: FNP := FieldPtr(FNP^.FieldInfo^.RightField);
end;
end;
if (FNP = nil) or (FNP^.FieldInfo = nil) then
NextFieldID := 1
else
NextFieldID := FNP^.FieldInfo^.ID;
end;
end; { NextFieldID }
procedure ChangeFields(ID:byte; Direction:byte);
{}
var LastField,
CF,
CField: byte;
Refresh: byte;
TempID: integer;
FNP: FieldNodePtr;
begin
with ActiveForm^ do
begin
if (ValState = ValidateByField)
and (not (LastAction in [Cancel1..Escaped])) then
if not ActiveFieldPtr^.FieldInfo^.SuspendHook then
exit; {leave the user in the same field}
ActiveFieldPtr^.FieldInfo^.UpdateVarHook(ActiveFieldPtr^.FieldInfo);
ActiveFieldPtr^.FieldInfo^.DisplayHook(ActiveFieldPtr^.FieldInfo,NormStatus);
DisplayLabel(ActiveFieldPtr,false);
if ActiveFieldPtr^.FieldInfo^.MsgX <= 80 then
RemoveMessage(ActiveFieldPtr^.FieldInfo);
{Now call the "leave field" hook}
CField := FieldNumber(ActiveFieldPtr);
CF := CField;
LastField := CField;
Refresh := RefreshNone;
LeaveFieldHook(CField,Refresh);
if CField = 0 then
ID := CF
else
begin
if (CField <> CF)
and (FieldPtr(CField)^.FieldInfo^.Active = FldOn) then
ID := CField; {user wants to go to a specific field}
ActiveFieldPtr^.FieldInfo^.FirstCharPress := false;
end;
CheckRefreshState(Refresh,false);
if TInputFinished then
exit;
if ID = 0 then
TInputFinished := true
else
begin
CField := ID;
if CField > TotalFields then
CField := TotalFields;
{Enter Field Hook}
repeat
ActiveField := CField;
Refresh := RefreshNone;
EnterFieldHook(CField,Refresh);
if (ActiveField <> CField)
and (FieldPtr(CField)^.FieldInfo^.Active <> FldOn) then {try to change to inactive field}
CField := ActiveField;
CheckRefreshState(Refresh,true);
if TInputFinished then exit;
until CField = ActiveField;
if (ActiveField < 1)
or (ActiveField > TotalFields) then
exit;
ActiveFieldPtr := FieldPtr(ActiveField);
{make sure a hook hasn't disabled the field getting focus}
if (ActiveFieldPtr^.FieldInfo^.Active <> FldOn)
or
(ActiveFieldPtr^.FieldInfo^.Visible = false) then
ActiveFieldPtr := FieldPtr(NextFieldID(Direction));
{time to highlight the field getting focus}
ActiveFieldPtr^.FieldInfo^.FirstCharPress := true;
ActiveFieldPtr^.FieldInfo^.DisplayHook(ActiveFieldPtr^.FieldInfo,Activate);
DisplayLabel(ActiveFieldPtr,true);
if ActiveFieldPtr^.FieldInfo^.MsgX <= 80 then
DisplayMessage(ActiveFieldPtr^.FieldInfo,ActiveFieldPtr^.FieldInfo^.Message);
end; {if}
{set lastfield in case help is pressed}
if LastField <> ActiveField then {a field change occurred}
PreviousField := LastField;
{Now check the default button status}
if (DefaultButtonID <> 0)
and (ActiveFieldPtr^.FieldInfo^.ID <> DefaultButtonID) then
begin
FNP := FieldPtr(DefaultButtonID);
if (FNP <> nil)
and (ActiveFieldPtr^.FieldInfo^.FieldType = IOOther)
and (ActiveFieldPtr^.FieldInfo^.DataSize = ButtonMarker)
and (ActiveFieldPtr^.FieldInfo^.DataPtr = nil) then {another button active}
begin
TempID := DefaultButtonID;
DefaultButtonID := 0; {trick default button into displaying like standard button}
FNP^.FieldInfo^.DisplayHook(FNP^.FieldInfo,NormStatus);
DefaultButtonID := TempID;
end else
FNP^.FieldInfo^.DisplayHook(FNP^.FieldInfo,NormStatus);
end;
end; {with ActiveForm}
end; { ChangeFields }
procedure FinishInput;
{}
var OldActiveField,
FNP: FieldNodePtr;
BadField: byte;
StartingFocus: byte;
begin
with ActiveForm^ do
begin
if ValState = ValidateByField then
begin
if ActiveFieldPtr^.FieldInfo^.SuspendHook then
begin
ActiveFieldPtr^.FieldInfo^.UpdateVarHook(ActiveFieldPtr^.FieldInfo);
TInputFinished := true;
end;
end else {check that all fields have valid data}
begin
OldActiveField := ActiveFieldPtr;
StartingFocus := ActiveField;
FNP := FirstField;
while FNP <> nil do
begin
ActiveFieldPtr := FNP;
ActiveField := FNP^.FieldInfo^.ID;
if (FNP^.FieldInfo^.Active <> FldOn) or (FNP^.FieldInfo^.SuspendHook) then
FNP := FNP^.NextField
else {validation error}
begin
ActiveFieldPtr := OldActiveField;
ActiveField := ActiveFieldPtr^.FieldInfo^.ID;
ChangeFields(FNP^.FieldInfo^.ID,0);
exit;
end;
end;
ActiveField := StartingFocus;
TInputFinished := true;
end;
if TInputFinished then {call user-supplied finish hook}
begin
BadField := FinishedHook;
if BadField <> 0 then
begin
TInputFinished := false;
ChangeFields(BadField,0);
end;
end;
end;
end; { FinishInput }
function HotkeyPressed(var Key:word; var NewFieldID:byte): gAction;
{}
var FNP: FieldNodePtr;
Counter: integer;
RetCode: gAction;
begin
RetCode := None;
{first check if it is a hotkey is the active field -- this
allows radio buttons et al to use the same hotkeys for
similar items in different "fields"}
FNP := IOVars.Form[IOVars.CurrentForm]^.ActiveFieldPtr;
if FNP^.FieldInfo^.HotKeyHook(FNP^.FieldInfo,Key,RetCode) then
NewFieldID := IOVars.Form[IOVars.CurrentForm]^.ActiveField
else
begin
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
Counter := 1;
while FNP <> nil do
begin
if (Counter <> IOVars.Form[IOVars.CurrentForm]^.ActiveField)
and (FNP^.FieldInfo^.Active = FldOn)
and FNP^.FieldInfo^.HotKeyHook(FNP^.FieldInfo,Key,RetCode) then
begin
NewFieldID := Counter;
HotKeyPressed := RetCode;
exit;
end else
begin
FNP := FNP^.NextField;
inc(Counter);
end;
end;
end;
HotKeyPressed := RetCode;
end; { HotkeyPressed }
function ActionKey(WKey:word):boolean;
{}
var FNP: FieldNodePtr;
begin
ActionKey := true;
with ActiveForm^ do
begin
if WKey = ActionChars.FinishChar then
FinishInput
else if (WKey = 13)
and (DefaultButtonID <> 0)
and (ActiveFieldPtr^.FieldInfo^.UsesEnter = false) then
begin
FNP := FieldPtr(DefaultButtonID);
if (FNP = nil) then
ActionKey := false
else
begin
LastAction := gAction(FNP^.FieldInfo^.OMisc);
if LastAction in [Cancel1..Escaped] then
begin
ActiveFieldPtr^.FieldInfo^.UpdateVarHook(ActiveFieldPtr^.FieldInfo);
TInputFinished := true;
end else
FinishInput;
end;
end else
if WKey = ActionChars.EscChar then
begin
TInputFinished := true;
LastAction := Escaped;
end else
if WKey = ActionChars.NextChar then
ChangeFields(NextFieldID(4),4)
else if WKey = ActionChars.PrevChar then
ChangeFields(NextFieldID(3),3)
else if WKey = ActionChars.RightChar then
ChangeFields(NextFieldID(4),4)
else if WKey = ActionChars.LeftChar then
ChangeFields(NextFieldID(3),3)
else if WKey = ActionChars.EraseChar then
EraseField(ActiveField)
else if WKey = KeyVars.HelpKey then
CallIOHelp(ActiveField)
else if not ActiveFieldPtr^.FieldInfo^.UsesCursors
and (WKey = ActionChars.UpChar) then
ChangeFields(NextFieldID(1),1)
else if not ActiveFieldPtr^.FieldInfo^.UsesCursors
and (WKey = ActionChars.DownChar) then
ChangeFields(NextFieldID(2),2)
else
ActionKey := false;
end;
end; { ActionKey }
procedure Activity(Wait:boolean);
{}
var Wkey: word;
K : char;
ReturnStr: string;
PriorCursorX : byte;
ValidInput : byte;
OldField : byte;
CField : byte;
LK:word;
LX,LY:byte;
procedure CheckAction;
{}
begin
with ActiveForm^ do
case LastAction of
Cancel1..
Escaped : TInputFinished := true;
Finished,
Stop1..Stop99 : if ActiveForm^.ValidateOnStop then
FinishInput
else
TInputFinished := true;
Help: CallIOhelp(CField);
NextField: CField := NextFieldID(4);
PrevField: CField := NextFieldID(3);
end; {case}
end; { CheckAction }
begin {Activity}
OldField := ActiveForm^.ActiveField;
if (ActiveForm^.WinNum <> 0) then
WinDrawTop;
if Wait then
GetInput;
with KeyVars do
begin
LK := LastKey;
LX:= LastX;
LY := LastY;
end;
if (ActiveForm^.WinNum <> 0) then
begin
if IsWinKey(LK,LX,LY) then
WinProcessKey(LK,LX,LY)
else
begin
LX := WinLocalX(ActiveForm^.WinNum,LX);
LY := WinLocalY(ActiveForm^.WinNum,LY);
end;
end;
WKey := LK;
{now the character hook}
with ActiveForm^ do
begin
CField := OldField;
TRefresh := RefreshNone;
CharHook(WKey,CField,TRefresh);
CheckRefreshState(TRefresh,true);
if (CField <> ActiveField)
and (FieldPtr(CField)^.FieldInfo^.Active = FldOn) then
ChangeFields(CField,2); {user wants to go to a specific field}
{Check to see if user presses left mouse button on another field}
if WKey = 500 then
begin
CField := FieldHit(LX,LY,true);
if CField = 0 then
begin
if not OnTarget(ActiveForm^.ActiveFieldPtr,LX,LY) then
MouseRelease; {clicked off a field}
end
else if FieldPtr(CField)^.FieldInfo^.HotKey = 500 then {hotspot}
begin
LastAction := gAction(FieldPtr(CField)^.FieldInfo^.OMisc);
WKey := 0;
CheckAction;
end
else if (CField <> ActiveField) then
begin
ChangeFields(CField,2);
(*
MouseRelease;
*)
end;
end else
begin
LastAction := HotKeyPressed(WKey,CField);
CheckAction;
if (CField <> 0)
and (CField <> ActiveField)
and( not (LastAction in [Finished,Stop1..Stop99])
or (TInputFinished <> false)) then
ChangeFields(CField,2);
end;
K := WordToChar(WKey);
if WKey <> 0 then
begin
if not ActionKey(WKey) then
begin
if Wkey = 600 then
begin
if ActiveForm^.AllowEsc then
begin
TInputFinished := true;
ActiveForm^.LastAction := Escaped;
end;
end else
begin
LastAction := ActiveFieldPtr^.FieldInfo^.ProcessKeyHook(WKey,LX,LY);
ActiveFieldPtr^.FieldInfo^.UpdateVarHook(ActiveFieldPtr^.FieldInfo);
CheckAction;
end;
end;
end;
if ActiveFieldPtr^.FieldInfo^.FirstCharPress
and (Wkey < 500)
and (Wkey > 0)
and (ActiveField = OldField) then
ActiveFieldPtr^.FieldInfo^.FirstCharPress := false;
if not TInputFinished then
begin
ActiveFieldPtr^.FieldInfo^.DisplayHook(ActiveFieldPtr^.FieldInfo,HiStatus);
with ActiveFieldPtr^.FieldInfo^ do
begin
if (FirstCharPress = false)
and IsRule(FieldRules,JumpifFull)
and (StrLocX = FieldLen)
and (Length(FieldStr) = FieldLen)
and (InsertMode)
and (K in [#32..#255]) then
ChangeFields(NextFieldID(4),4);
end;
end;
IOVars.IChar := K;
HindHook(ActiveField,TRefresh);
CheckRefreshState(TRefresh,true);
end; {with ActiveForm}
end; { Activity }
procedure CheckFieldTypes;
{Ensures that all added fields have non-zero field types, i.e. each
AddField had a corresponding xxxField}
var FNP: FieldNodePtr;
begin
FNP := IOVars.Form[IOVars.CurrentForm]^.FirstField;
while (FNP <> nil) do
begin
if (FNP^.FieldInfo^.FieldType = 0)
and (FNP^.FieldInfo^.HotKey <> 500) then
begin
clrscr;
writeln('FieldID: ',FNP^.FieldInfo^.ID);
IOSetError(1004);
end;
FNP := FNP^.NextField;
end;
end; { CheckFieldTypes }
procedure PrepareforInput(StartField:byte);
{INTERNAL}
begin
{$IFDEF CHECK}
CheckFieldTypes;
{$ENDIF}
ActiveForm := IOVars.Form[IOVars.CurrentForm];
with ActiveForm^ do
begin
if Displayed = false then
DisplayForm;
if not (StartField in [1..TotalFields]) then
StartField := 1;
ActiveField := StartField;
ActiveFieldPtr := FieldPtr(ActiveField);
ActiveFieldPtr^.FieldInfo^.FirstCharPress := true;
LastAction := none;
{Enter Field Hook}
TSField := StartField;
TInputFinished := false;
repeat
ActiveField := TSField;
TSRefresh := RefreshNone;
EnterFieldHook(TSField,TSRefresh);
CheckRefreshState(TSRefresh,true);
if TInputFinished then
exit;
until TSField = ActiveField;
ActiveFieldPtr := FieldPtr(ActiveField);
ActiveFieldPtr^.FieldInfo^.FirstCharPress := true;
ActiveFieldPtr^.FieldInfo^.DisplayHook(ActiveFieldPtr^.FieldInfo,Activate);
DisplayLabel(ActiveFieldPtr,true);
if ActiveFieldPtr^.FieldInfo^.MsgX <= 80 then
DisplayMessage(ActiveFieldPtr^.FieldInfo,ActiveFieldPtr^.FieldInfo^.Message);
InsertProc(InsertMode);
HindHook(0,TRefresh); {pass a field of zero to indicate first time through}
CheckRefreshState(TRefresh,true);
end;
end; {PrepareforInput}
procedure ProcessInput(StartField:byte);
{}
begin
PrepareforInput(StartField);
ActiveForm := IOVars.Form[IOVars.CurrentForm];
with ActiveForm^ do
begin
if not TInputFinished then
repeat
Activity(true);
until TInputFinished;
if ActiveFieldPtr^.FieldInfo^.MsgX <= 80 then
RemoveMessage(ActiveFieldPtr^.FieldInfo);
end;
end; { ProcessInput }
function EditForm(StartField:byte):gAction;
{}
begin
ProcessInput(StartField);
EditForm := IOVars.Form[IOVars.CurrentForm]^.LastAction;
end; { EditForm }
{************************}
{** Desktop Routines **}
{************************}
function FormWithFocus: byte;
{}
var
TopWinNum: byte;
Temp: WStructurePtr;
I: integer;
begin
Temp := WinPtr(0);
TopWinNum := Temp^.WinNum; {number of the top win}
for I := 1 to MaxForms do
if (IOVars.Form[I] <> nil)
and (IOVars.Form[I]^.WinNum = TopWinNum) then
begin
FormWithFocus := I;
exit;
end;
FormWithFocus := 0;
end; {FormWithFocus}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
procedure IOProcessKeyOnDesktop;
{}
var
TopForm: byte;
begin
{set the active Form}
TopForm := FormWithFocus;
if TopForm <> 0 then
begin
ActivateForm(TopForm);
with ActiveForm^ do
begin
Activity(false);
if TInputFinished then
begin
if ActiveForm^.DeskFormCloseCallBack(FormWithFocus) then
DisposeFormWin
else
TInputFinished := false;
end;
end;
end;
end; { IOProcessKeyOnDesktop }
function FormCloseHandler(Handle: integer):boolean;
{}
var
WinP: WStructurePtr;
begin
WinP := WinPtr(Handle);
FormCloseHandler := ActiveForm^.DeskFormCloseCallBack(FormWithFocus);
DisposeFormWin;
WinDispose(Handle);
end; {FormCloseHandler}
procedure FormFocusHandler(Handle: integer);
{}
var
WinP: WStructurePtr;
begin
WinP := WinPtr(Handle);
ActivateForm(longint(Winp^.UserData));
end; {FormFocusHandler}
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
function LaunchFormInit(X1,Y1,X2,Y2,style:byte;CloseProc:FormCloseProc): byte;
{}
var
OldTopWin,NewTopWin: byte;
WinP: WStructurePtr;
begin
WinFadeTopWin;
OldTopWin := WinWithFocus;
SetFormWindow(X1,Y1,X2,Y2,style);
NewTopWin := IOVars.Form[IOVars.CurrentForm]^.WinNum;
if NewTopWin <> 0 then
begin
WinP := WinPtr(NewTopWin);
WinP^.ProcessKeyProc := IOProcessKeyOnDeskTop;
WinP^.CloseWinProc := FormCloseHandler;
WinP^.ChangeFocusProc := FormFocusHandler;
ActiveForm^.DeskFormCloseCallBack := CloseProc;
longint(WinP^.UserData) := IOVars.CurrentForm;
end;
LaunchFormInit := NewTopWin;
end; {LaunchFormInit}
procedure LaunchForm(StartField:byte);
{}
begin
PrepareforInput(StartField);
end; {LaunchForm}
{*********************************************}
{** U N I T I N I T I A L I Z A T I O N **}
{*********************************************}
procedure IODefaultSettings;
{}
begin
with IOVars do
begin
WhiteSpace := #250;
AllowEsc := true;
FieldFullOn := true;
DefaultRules := AllowNull+EraseDefault;
TotalForms := 0;
UsingPrivateForm := false;
EMsgFunc := IoEMsg;
with ActionChars do
begin
NextChar := 9;
PrevChar := 271;
FinishChar := 324;
EscChar := 27;
UpChar := 328;
DownChar := 336;
LeftChar := 411; {Ctrl-Left}
RightChar := 413; {Ctrl-Right}
EraseChar := 5; {Ctrl-E}
end;
DefaultValidate := ValidatebyField;
ValidationMsgTitle := ' Validation Error ';
ValidationMsgNum := 'Invalid number - make correction!';
ValidationMsgDate := 'Date Error: format is ';
ValidationMsgNumPart1 := 'Error value must be in the range ';
ValidationMsgNumPart2 := ' to ';
ValidationMsgEmpty := 'This field cannot be empty!';
FieldFullTitle := ' Field Full ';
FieldFullMsg := 'The field is full. Press Ins to change to overtype|mode or delete some characters.';
end; {with}
end; { IODefaultSettings }
procedure GoldIOInit;
{}
var I: integer;
begin
with IOVars do
begin
for I := 1 to MaxForms do
IOVars.Form[I] := nil;
IODefaultSettings;
end;
end; { GoldIOInit }
begin
GoldIOInit;
end.