home *** CD-ROM | disk | FTP | other *** search
- { ** Start of MGPROG.INC **
- Author : Eric H. Snyder
- 1417 Evergreen
- Homewood, IL 60430
-
- Note : The user must declare the number of windows in the program
- as follows;
- Const
- ScreenCount = N; Where N = the # of windows being defined.
- I have set a default number of eight.
- }
-
- Unit MGProg;
-
- Interface
-
- Uses
- Dos,
- Crt;
-
- Type
- MG_Str80 = String[80];
- MG_ExitsTyp = Set of Byte;
- MG_Edits = Set of Char;
- MG_Str255 = String;
- MG_ScreenObjLLPtr = ^MG_ScreenObjLLTyp;
- MG_ScreenObjLLTyp = Record
- LLForward : MG_ScreenObjLLPtr;
- LLWindow : Byte;
- LLTyp : Char;
- LLCol, LLRow, LLAtr, LLlen : Integer;
- LLTxt : MG_Str80;
- End;
-
- Const
- ScreenCount = 20;
- MG_TimeOut : Integer = 300;
-
- Var
- MG_ScreenType : Char;
- UpperByte,LowerByte : Byte; { Used }
- UpperInt,LowerInt : Integer; { in range }
- UpperReal,LowerReal : Real; { checking }
- UserEditSet : Set of Char; { User declared char set }
- UserExitSet : MG_ExitsTyp;
- MG_RiteFlag : Array[1..ScreenCount] of Boolean;
- MG_ScreenLLBase : MG_ScreenObjLLPtr;
- MG_ScreenObjLL : MG_ScreenObjLLPtr;
- RightShift,LeftShift : Boolean;
- AltKey,CtrlKey : Boolean;
-
- Procedure Rite(S:MG_Str80;Col,Row:Integer;Attr:Byte);
- Procedure WinRite(S:MG_Str80;X,Y:Byte;Attr:Integer);
- Procedure DefineScreen(Ind,dfX1,dfY1,dfX2,dfY2,dfBgCol,dfFrameTyp,dfFrCol:Byte);
- Procedure OpenWindow(Ind:Byte);
- Procedure CloseWindow;
- Procedure CloseAllWindows;
- Procedure TerminateScreens;
- Procedure MaxLimits;
- Procedure CharOut(ScrOfs,Ch:Integer;Attr:Byte);
-
- Function EnterChar(Var Value : Char;
- GoodChars : MG_Edits;
- Exits : MG_ExitsTyp) : Integer;
-
- Function EnterData(Var Variable; { Variable being entered }
- VarTyp : Char; { Indicated Variable type }
- XLoc,YLoc, { X & Y Co-ordinates }
- Len, { Length of field }
- Decs, { No. of decimal places }
- FieldAttr,
- CursorAttr : Byte;
- Exits : MG_ExitsTyp):Integer;
- {Exits in addition to }
- { -1 : Param error }
- { 0 : Typing out }
- { 13 : Carriage Return }
- {-13 : ^M }
- Function Menu( Window : Byte;
- S : MG_Str255;
- Selections,NormAttr,ReverseAttr
- : Byte;
- Exits : MG_ExitsTyp) : Byte;
-
- Implementation
-
- Type
- MG_CharPtr = ^Char;
- MG_ScreenImage = array[1..25,1..80] of integer;
- MG_ScreenDef = Record
- X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol : Byte;
- End;
-
- MG_SavedScreen = ^MG_SavedScreenRec;
- MG_SavedScreenRec = Record
- BackLink : MG_SavedScreen;
- XLoc,Yloc : Integer;
- ScreenStats : MG_ScreenDef;
- MG_SavedWindow : MG_CharPtr;
- End;
-
- MG_FrameChars = Record
- TL,TR,BL,BR,HC,VC : Char;
- End;
-
- Const { Delete unused frame character constant records }
- MG_LastOpened : MG_ScreenDef = (X1:0;Y1:0;X2:81;Y2:26;BgCol:0;FrameTyp:0;FrCol:0);
- MG_FirstScreen : Boolean = True;
-
- Var
- MG_PhysicalScreen : MG_CharPtr;
- MG_CurrentScreen,
- MG_NewScreen : MG_SavedScreen;
- MG_DefinedScreens : Array[1..ScreenCount] of MG_ScreenDef;
- MG_Registers : Registers;
-
-
- Procedure CharOut;
- Begin
- Mem[Seg(MG_PhysicalScreen^):(Ofs(MG_PhysicalScreen^) + ScrOfs)] := Ch;
- Mem[Seg(MG_PhysicalScreen^):(Ofs(MG_PhysicalScreen^) + ScrOfs + 1)] := Attr;
- End; {CharOut}
-
- Procedure Rite;
- Var
- I,ScrOfs : Integer;
- Begin
- Row := (Row - 1) * 160;
- For I := 1 to Length(S) do
- Begin
- ScrOfs := Row + ((Col + I - 2) * 2);
- CharOut(ScrOfs,Ord(S[I]),Attr);
- End;
- End; {Rite}
-
- Procedure WinRite;
- Begin
- With MG_LastOpened do
- Begin
- X := X + X1;
- Y := Y + Y1;
- End;
- Rite(S,X,Y,Attr);
- End; {WinRite}
-
- Procedure DefineScreen;
- Begin
- With MG_DefinedScreens[Ind] do
- Begin
- X1 := dfX1;
- Y1 := dfY1;
- X2 := dfX2;
- Y2 := dfY2;
- BgCol := dfBgCol;
- FrameTyp := dfFrameTyp;
- FrCol := dfFrCol;
- End;
- End;
-
- Procedure MakeFrame(X1,Y1,X2,Y2,BgCol,Border,LinAttr : Integer);
- Type
- BorderCharacters = Array[1..8] of Integer;
- Const
- BorderTypes : Array[1..8] of BorderCharacters =
- (
- (218,196,191,179,179,192,196,217),
- (201,205,187,186,186,200,205,188),
- (213,205,184,179,179,212,205,190),
- (214,196,183,186,186,211,196,189),
- (194,196,194,179,179,192,196,217),
- (203,205,203,186,186,200,205,188),
- (209,205,209,179,179,212,205,190),
- (210,196,210,186,186,211,196,189)
- );
- Var
- LLHoriz,LLVert : Integer;
- TLCorner : Integer;
- THLine : Integer;
- TRCorner : Integer;
- LVLine : Integer;
- RVLine : Integer;
- BLCorner : Integer;
- BHLine : Integer;
- BRCorner : Integer;
-
- Procedure BorderLine(Row,Col,Num,Ch,Direction,Attr : Integer);
- Var
- I,ScrOfs : Integer;
- Begin
- ScrOfs := ((Row - 1) * 160) + ((Col - 1) * 2);
- For I := 1 to Num do
- Begin
- CharOut(ScrOfs,Ch,Attr);
- If Direction = 0 then
- ScrOfs := ScrOfs + 160
- Else
- ScrOfs := ScrOfs + 2;
- End;
- End; {BorderLine}
-
- Begin
- Window(X1,Y1,X2,Y2);
- TextBackground(BgCol);
- ClrScr;
- LLHoriz := X2 - X1 + 1;
- LLVert := Y2 - Y1 + 1;
- TLCorner := BorderTypes[Border,1];
- THLine := BorderTypes[Border,2];
- TRCorner := BorderTypes[Border,3];
- LVLine := BorderTypes[Border,4];
- RVLine := BorderTypes[Border,5];
- BLCorner := BorderTypes[Border,6];
- BHLine := BorderTypes[Border,7];
- BRCorner := BorderTypes[Border,8];
- CharOut( (((Y1 - 1) * 160) + ((X1 - 1) * 2)),TLCorner,LinAttr);
- BorderLine(Y1,(X1 + 1),(LLHoriz - 2),THLine,1,LinAttr);
- CharOut( (((Y1 - 1) * 160) + ((X2 - 1) * 2)),TRCorner,LinAttr);
- BorderLine((Y1 + 1),X1,(LLVert - 2),LVLine,0,LinAttr);
- BorderLine((Y1 + 1),X2,(LLVert - 2),RVLine,0,LinAttr);
- CharOut( (((Y2 - 1) * 160) + ((X1 - 1) * 2)),BLCorner,LinAttr);
- BorderLine(Y2,(X1 + 1),(LLHoriz - 2),BHLine,1,LinAttr);
- CharOut( (((Y2 - 1) * 160) + ((X2 - 1) * 2)),BRCorner,LinAttr);
- Window((X1 + 1),(Y1 + 1),(X2 - 1),(Y2 - 1));
- GotoXY(1,1);
- End; {MakeFrame}
-
- Procedure OpenWindow;
-
- Var
- SD : MG_ScreenDef;
- LLObj : MG_ScreenObjLLPtr;
- WorkStr : MG_Str80;
- I,J : Integer;
-
- Function SaveWindowContents(X1,Y1,X2,Y2 : Integer):MG_CharPtr;
-
- Var
- I,J : Integer;
- LLHoriz,LLVert : Integer;
- Width : Integer;
- MovePtr : MG_CharPtr;
-
- Begin
- LLHoriz := X2 - X1 + 1;
- LLVert := Y2 - Y1 + 1;
- Width := LLHoriz * 2;
- j := ((Y1 - 1) * 160) + ((X1 - 1) * 2);
- GetMem(MovePtr,((LLHoriz * LLVert) * 2));
- SaveWindowContents := MovePtr;
- For I := 1 to LLVert do
- Begin
- Move(Mem[Seg(MG_PhysicalScreen^):(Ofs(MG_PhysicalScreen^) + J)],MovePtr^,Width);
- J := J + 160;
- MovePtr := Ptr(Seg(MovePtr^),(Ofs(MovePtr^) + Width));
- End;
- End; {SaveWindowContents}
-
- Begin
- SD := MG_DefinedScreens[Ind];
- New(MG_NewScreen);
- With MG_NewScreen^ do
- Begin
- XLoc := WhereX;
- YLoc := WhereY;
- With SD do
- MG_SavedWindow := SaveWindowContents(X1,Y1,X2,Y2);
- ScreenStats := MG_LastOpened;
- If MG_FirstScreen then
- Begin
- BackLink := nil;
- MG_FirstScreen := False;
- End
- Else
- BackLink := MG_CurrentScreen;
- MG_CurrentScreen := MG_NewScreen
- End;
- With SD do
- MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol);
- MG_LastOpened := SD;
- If not MG_RiteFlag[Ind] then
- Exit;
- LLObj := MG_ScreenLLBase;
- While (LLObj^.LLforward <> Nil) and
- (LLObj^.LLWindow <> Ind) do
- LLObj := LLObj^.LLForward;
- If LLObj^.LLForward = Nil then
- Exit;
- While (LLObj <> Nil) and
- (LLObj^.LLWindow = Ind) do
- Begin
- With LLObj^ do
- Case LLTyp of
- 'T','H' : WinRite(LLTxt,LLCol,LLRow,LLAtr);
- 'F' : Begin
- FillChar(WorkStr[1],LLlen,' ');
- WorkStr[0] := Chr(Ord(LLlen));
- WinRite(WorkStr,LLCol,LLRow,LLAtr);
- End;
- 'V' : Begin
- J := ((LLRow - 1) * 160) + ((LLCol - 1) * 2);
- For I := 1 to Length(LLTxt) do
- Begin
- CharOut(J,Ord(LLTxt[I]),LLAtr);
- J := J + 160;
- End;
- End;
- End; {case}
- LLObj := LLObj^.LLForward;
- End;
- End; {OpenWindow}
-
- Procedure CloseWindow;
-
- Procedure ReDisplayWindowContents(X1,Y1,X2,Y2 : Integer;
- MovePtr : MG_CharPtr);
- Var
- I,J : Integer;
- LLHoriz,LLVert : Integer;
- Width : Integer;
- P : MG_CharPtr;
-
- Begin
- P := MovePtr;
- LLHoriz := X2 - X1 + 1;
- LLVert := Y2 - Y1 + 1;
- Width := LLHoriz * 2;
- J := ((Y1 - 1) * 160) + ((X1 - 1) * 2);
- For i := 1 to LLVert do
- Begin
- Move(MovePtr^,Mem[Seg(MG_PhysicalScreen^):(Ofs(MG_PhysicalScreen^) + J)],Width);
- J := J + 160;
- MovePtr := Ptr(Seg(MovePtr^),(Ofs(MovePtr^) + Width));
- End;
- FreeMem(P,((LLHoriz * LLVert)*2));
- End; {ReDisplayWindowContents}
-
- Begin
- MG_NewScreen := MG_CurrentScreen;
- With MG_NewScreen^ do
- Begin
- With MG_LastOpened do
- ReDisplayWindowContents(X1,Y1,X2,Y2,MG_SavedWindow);
- With ScreenStats do
- Window(X1+1,Y1+1,X2-1,Y2-1);
- GotoXY(XLoc,YLoc);
- MG_LastOpened := ScreenStats;
- MG_CurrentScreen := BackLink;
- End;
- Dispose(MG_NewScreen);
- End; {CloseWindow}
-
- Procedure CloseAllWindows;
- Begin
- While MG_CurrentScreen <> nil do
- CloseWindow;
- End; {CloseAllWindows}
-
- Procedure TerminateScreens;
- Var
- LLBase,LLDispose : MG_ScreenObjLLPtr;
- Begin
- If Not MG_FirstSCreen then
- CloseAllWindows;
- LLBase := MG_ScreenLLBase;
- While LLBase <> nil do
- Begin
- LLDispose := LLBase;
- LLBase := LLBase^.LLForward;
- Dispose(LLDispose);
- End;
- End; {TerminateScreens}
-
- {*******************************************************************}
- {** End of windowing routines **}{** Start of data entry routines **}
- {*******************************************************************}
-
- Procedure MaxLimits;
- Begin
- LowerByte := 0; UpperByte := 255;
- LowerInt := -32767; UpperInt := MaxInt;
- LowerReal := 1E-38; UpperReal := 1E+37;
- End; {MaxLimits}
-
- Procedure ScreenSaver(TimeOut:Integer);
-
- Const
- CrtModePort : array[0..1] of Integer = ($03B8,$03D8);
- Var
- StartTime,EndTime : Integer;
- ScreenBlanked : Boolean;
- Ch : Char;
- CrtModeByte : Byte absolute $0040:$0065;
- DisplayAdapter : Integer;
- Hour,Minute,Second,Sec100 : Word;
-
- Begin
- Case MG_ScreenType of
- 'M' : DisplayAdapter := 0;
- 'C' : DisplayAdapter := 1;
- End;
- Repeat
- ScreenBlanked := False;
- GetTime(Hour,Minute,Second,Sec100);
- StartTime := (Minute * 60) + Second;
- While not KeyPressed do
- If not ScreenBlanked then
- Begin
- GetTime(Hour,Minute,Second,Sec100);
- EndTime := (Minute * 60) + Second;
- If EndTime < StartTime then
- EndTime := EndTime + 3600;
- If ((EndTime - StartTime) >= TimeOut) then
- Begin
- ScreenBlanked := True;
- Port[CrtModePort[DisplayAdapter]] := CrtModeByte and $F7;
- End;
- End;
- If ScreenBlanked then
- Begin
- ScreenBlanked := False;
- Port[CrtModePort[DisplayAdapter]] := CrtModeByte or $08;
- While KeyPressed do
- Ch := ReadKey;
- End;
- Until KeyPressed and not ScreenBlanked;
- End; {ScreenSaver}
-
- Procedure GetShiftStatus;
- Var
- Regs : Registers;
- StatusByte : Byte;
- Begin
- RightShift := False;
- LeftShift := False;
- AltKey := False;
- CtrlKey := False;
- Regs.AH := 2;
- Intr($16,Regs);
- StatusByte := Regs.AL;
- If ((StatusByte and $08) = 8) then
- AltKey := True;
- If ((StatusByte and $04) = 4) then
- CtrlKey := True;
- If ((StatusByte and $02) = 2) then
- LeftShift := True;
- If ((StatusByte and $01) = 1) then
- RightShift := True;
- End; {GetShiftStatus}
-
- Function EnterChar;
-
- Var
- Ch : Char;
- Order : Byte;
- Done : Boolean;
-
- Begin
- Done := False;
- EnterChar := 0;
- Repeat
- ScreenSaver(MG_TimeOut);
- Ch := ReadKey;
- GetShiftStatus;
- Order := Ord(Ch);
- If (Ch = #00) then
- Begin
- Order := Ord(ReadKey);
- If (Order in Exits) then
- Begin
- EnterChar := Order;
- Done := True;
- End;
- End
- Else
- If (Order in Exits) then
- Begin
- EnterChar := Order;
- Done := True;
- End
- Else
- If (Ch in GoodChars) then
- Begin
- Value := Ch;
- Done := True;
- End;
- Until Done;
- End; {EnterChar}
-
- Function EnterData;
-
- Const
- BytIntEdits : MG_Edits = ['0'..'9','+','-',' ']; {Pre-defined edit types}
- RealEdits : MG_Edits = ['0'..'9','+','-','.','E',' '];
- StrEditsAll : MG_Edits = [' '..'}'];
- Alpha : MG_Edits = ['A'..'Z','a'..'z',' '];
- UpperCase : MG_Edits = ['A'..'Z',' '];
- LowerCase : MG_Edits = ['a'..'z',' '];
- Numeric : MG_Edits = ['0'..'9'];
- Anything : MG_Edits = [#32..#254];
- Date : MG_Edits = ['0'..'9','/'];
- ClickOn : Boolean = False;
- InsertOn : Boolean = False;
-
- Var
- BytVar : Byte absolute Variable;
- IntVar : Integer absolute Variable;
- RealVar : Real absolute Variable;
- StrgVar : MG_Str80 absolute Variable;
- WorkStr : MG_Str80;
- OrigStr : MG_Str80;
- ValidChars : MG_Edits;
- Done : Boolean;
- Converted : Boolean;
- CtrlEmm : Boolean;
- CharIn : Char;
- Position : Byte;
-
- Procedure Beep;
- Begin
- Sound(800);
- Delay(50);
- Nosound;
- End; {Beep}
-
- Procedure MakeClickNoise;
- Begin
- Sound(2000);
- Delay(5);
- NoSound;
- End; {ClickNoise}
-
- Procedure RefreshDisplay;
- Var
- TempStr : MG_Str80;
- WrkLen,I : Integer;
- Tail : Char;
-
- Begin
- TempStr := WorkStr;
- Tail := #95;
- If Done then
- Tail := #32;
- For I := Length(WorkStr) + 1 to Len do
- TempStr := Concat(TempStr,Tail);
- Rite (TempStr,XLoc,YLoc,FieldAttr);
- If not Converted then
- CharOut(((YLoc-1)*160+(XLoc+Position-2)*2),Ord(TempStr[Position]),CursorAttr);
- End; {RefreshDisplay}
-
- Procedure QueryExits;
- Var
- StatusByte : Byte;
- Begin
- If CharIn = #13 then { CR always exits }
- Begin
- Done := True;
- EnterData := 13;
- With MG_Registers do
- Begin
- AX := 2 shl 8;
- Intr($16,MG_Registers);
- StatusByte := Lo(AX);
- If (StatusByte and $04 > 0) then
- Begin
- EnterData := -13;
- CtrlEmm := True;
- End;
- End
- End
- Else
- If (Ord(CharIn) in Exits) then
- Begin
- Done := True;
- EnterData := Ord(CharIn);
- End
- Else
- Begin
- Beep;
- CharIn := #255;
- End;
- End;
-
- Procedure CursorRight;
- Var
- NewPos : Byte;
- Begin
- If ((Position = Len) and (Length(WorkStr) = Len)) then
- Begin
- Beep;
- Exit;
- End;
- NewPos := Position + 1;
- If NewPos <= (Length(WorkStr)+1) then
- Position := NewPos
- Else
- Beep;
- End; {CursorRight}
-
- Procedure CursorLeft;
- Var
- NewPos : Byte;
- Begin
- NewPos := Position - 1;
- If NewPos >= 1 then
- Position := NewPos
- Else
- Beep;
- End; {CursorLeft}
-
- Procedure JumpRightWord;
- Var
- I,WrkLen : Integer;
- Begin
- WrkLen := Length(WorkStr);
- If (not (VarTyp in ['B','I','R'])) then
- If (Position < WrkLen) then
- Begin
- I := Position;
- If (WorkStr[I] <> ' ') then
- While ((I < WrkLen) and (WorkStr[I] <> ' ')) do
- I := I + 1;
- While ((I < WrkLen) and (WorkStr[I] = ' ')) do
- I := I + 1;
- Position := I;
- End
- Else
- Beep
- Else
- Beep;
- End; {JumpRightWord}
-
- Procedure JumpLeftWord;
- Var
- I,WrkLen : Integer;
- Begin
- If (not (VarTyp in ['B','I','R'])) then
- If (Position > 1) then
- Begin
- I := Position - 1;
- If (WorkStr[I] = ' ') then
- While ((I > 1) and (WorkStr[I] = ' ')) do
- I := I -1;
- While (I > 1) and (WorkStr[I] <> ' ') do
- I := I - 1;
- Position := I;
- If (I > 1) then
- Position := I + 1;
- End
- Else
- Beep;
- End; {JumpLeftWord}
-
- Procedure JumpRightField;
- Begin
- If Length(WorkStr) = Len then
- If Position = Len then
- Beep
- Else
- Position := Len
- Else
- If Position = Length(WorkStr) + 1 then
- Beep
- Else
- Position := Length(WorkStr) + 1;
- End;
-
- Procedure RightJustify;
- Var
- StatusByte : Byte;
- Begin
- With MG_Registers do
- Begin
- AX := 2 shl 8;
- Intr($16,MG_Registers);
- StatusByte := Lo(AX);
- If (StatusByte and $04 > 0) then
- Begin
- QueryExits;
- Exit;
- End;
- End;
- If (VarTyp in ['B','I','R']) or (Length(WorkStr) = 0) then
- Beep
- Else
- If (Length(WorkStr) < Len) then
- Begin
- Position := 1;
- While WorkStr[Length(WorkStr)] = ' ' do
- Delete(WorkStr,Length(WorkStr),1);
- While Length(WorkStr) < Len do
- Begin
- WorkStr := Concat(' ',WorkStr);
- Position := Position + 1;
- End;
- End;
- End; {RightJustify}
-
- Procedure LeftJustify;
- Begin
- If (VarTyp in ['B','I','R']) or (Length(WorkStr) = 0) then
- Beep
- Else
- Begin
- While WorkStr[1] = ' ' do
- Delete(WorkStr,1,1);
- Position := 1;
- End;
- End; {LeftJustify}
-
- Procedure Change2UpperCase;
- Var
- I : Integer;
- Begin
- If not (VarTyp in ['S','A']) then
- Beep
- Else
- For I := 1 to Length(WorkStr) do
- If WorkStr[I] in ['a'..'z'] then
- WorkStr[I] := Chr(Ord(WorkStr[I])-32);
- End; {Change2UpperCase}
-
- Procedure Change2LowerCase;
- Var
- I : Integer;
- Begin
- If not (VarTyp in ['S','A']) then
- Beep
- Else
- For I := 1 to Length(WorkStr) do
- If WorkStr[I] in ['A'..'Z'] then
- WorkStr[I] := Chr(Ord(WorkStr[I])+32);
- End; {Change2LowerCase}
-
- Procedure AddACharacter;
- Var
- NewPos : Integer;
- Begin
- If Position < Len then
- NewPos := Position + 1
- Else
- If Length(WorkStr) <> Len then
- NewPos := Position
- Else
- Begin
- Beep;
- Exit;
- End;
- If NewPos <= Len then
- Begin
- WorkStr := Concat(WorkStr,CharIn);
- If Position < Len then
- Position := Position + 1;
- If (VarTyp in ['S','A','U','L','N','D','X']) and
- (Length(WorkStr) = Len) then
- Begin
- Done := True;
- EnterData := 0;
- End;
- End;
- End; {AddACharacter}
-
- Procedure ChangeACharacter;
- Begin
- WorkStr[Position] := CharIn;
- If (Position < Len) then
- Position := Position + 1;
- End;
-
- Procedure InsertACharacter;
- Begin
- If (Length(WorkStr) + 1) <= Len then
- Begin
- Insert(CharIn,WorkStr,Position);
- Position := Position + 1;
- End
- Else
- Beep;
- End; {InsertACharacter}
-
- Procedure DeleteACharacter;
- Begin
- If Length(WorkStr) > 0 then
- Delete(WorkStr,Position,1)
- Else
- Beep;
- End; {DeleteACharacter}
-
- Procedure DestructiveBackspace;
- Begin
- If (Length(WorkStr) > 0) and
- (Position > 1) then
- Begin
- Position := Position - 1;
- Delete(WorkStr,Position,1);
- End
- Else
- Beep;
- End;
-
- Function Initialized : Boolean;
- Begin
- Initialized := False;
- If VarTyp in ['B','I','R'] then
- Begin
- Case VarTyp of
- 'B' : Str(BytVar,WorkStr);
- 'I' : Str(IntVar,WorkStr);
- 'R' : Begin
- Str(RealVar:Len:Decs,WorkStr);
- While WorkStr[1] = ' ' do
- Delete(WorkStr,1,1);
- End;
- End;
- If Length(WorkStr) <= Len then
- Begin
- Initialized := True;
- OrigStr := WorkStr;
- RefreshDisplay;
- End;
- End
- Else
- If VarTyp in ['S','A','U','L','N','D','X'] then
- Begin
- WorkStr := StrgVar;
- Initialized := True;
- OrigStr := WorkStr;
- RefreshDisplay;
- End;
- End; {Initialized}
-
- Procedure AssignValues;
- Var
- RetnCode,WrkLen,TempInt : Integer;
- TempReal : Real;
- ConvertStr : MG_Str80;
-
- Function Clean(NumericString:MG_Str80):MG_Str80;
- Begin
- While (Length(NumericString) > 0) and
- (NumericString[1] = ' ') do
- Delete(NumericString,1,1);
- While (Length(NumericString) > 0) and
- (NumericString[Length(NumericString)] = ' ') do
- Delete(NumericString,Length(NumericString),1);
- If (Length(NumericString) = 0) then
- NumericString := ' ';
- Clean := NumericString;
- End; {Clean}
-
- Procedure NumericFormat;
- Var
- I,PLoc : Integer;
- Begin
- ConvertStr := Clean(ConvertStr);
- If (Pos('E',ConvertStr) > 0) then
- Begin
- While (Length(ConvertStr) < Len) do
- ConvertStr := Concat(' ',ConvertStr);
- WorkStr := ConvertStr;
- RefreshDisplay;
- Exit;
- End;
- PLoc := Pos('.',ConvertStr);
- If PLoc = 0 then
- I := Length(ConvertStr) + 1
- Else
- I := PLoc;
- While I > 1 do
- Begin
- I := I - 3;
- If I > 1 then
- Insert(',',ConvertStr,I);
- End;
- If Length(ConvertStr) <= Len then
- Begin
- While Length(ConvertStr) < Len do
- ConvertStr := Concat(' ',ConvertStr);
- WorkStr := ConvertStr;
- RefreshDisplay;
- End
- Else
- Begin
- While Length(WorkStr) < Len do
- WorkStr := Concat(' ',WorkStr);
- RefreshDisplay;
- End;
- End; {NumericFormat}
-
- Begin
- If ((Ord(CharIn) in Exits) or CtrlEmm) then
- If (not (Ord(CharIn) in UserExitSet)) or CtrlEmm then
- Begin
- Converted := True;
- WorkStr := OrigStr;
- RefreshDisplay;
- Exit;
- End;
- If VarTyp in ['B','I','R'] then
- Begin
- ConvertStr := WorkStr;
- Case VarTyp of
- 'B' : Val(Clean(ConvertStr),TempInt,RetnCode);
- 'I' : Val(Clean(ConvertStr),TempInt,RetnCode);
- 'R' : Val(Clean(ConvertStr),TempReal,RetnCode);
- End; {case}
- If RetnCode = 0 then
- Begin
- Case VarTyp of
- 'B' : If (TempInt >= LowerByte) and (TempInt <= UpperByte) then
- Begin
- BytVar := TempInt;
- Converted := True;
- End;
- 'I' : If (TempInt >= LowerInt) and (TempInt <= UpperInt) then
- Begin
- IntVar := TempInt;
- Converted := True;
- End;
- 'R' : If (TempReal >= LowerReal) and (TempReal <= UpperReal) then
- Begin
- RealVar := TempReal;
- Converted := True;
- End;
- End; {case}
- If Converted then
- NumericFormat
- Else
- Begin
- Done := False;
- Position := 1;
- RefreshDisplay;
- Beep;
- End;
- End
- Else
- Begin
- Done := False;
- Position := RetnCode;
- RefreshDisplay;
- Beep;
- End;
- End
- Else
- Begin
- StrgVar := WorkStr;
- Converted := True;
- RefreshDisplay;
- End;
- End; {AssignValues}
-
- Begin
- Done := False;
- Converted := False;
- CtrlEmm := False;
- Position := 1;
- Case VarTyp of
- 'B','I'
- : ValidChars := BytIntEdits;
- 'R' : ValidChars := RealEdits;
- 'S' : ValidChars := StrEditsAll;
- 'A' : ValidChars := Alpha;
- 'U' : ValidChars := UpperCase;
- 'L' : ValidChars := LowerCase;
- 'N' : ValidChars := Numeric;
- 'D' : ValidChars := Date;
- 'X' : ValidChars := Anything;
- 'M' : Begin
- ValidChars := UserEditSet;
- VarTyp := 'X';
- End;
- Else
- Begin
- EnterData := -1;
- Exit;
- End;
- End; {case}
- With MG_LastOpened do
- Begin
- XLoc := XLoc + X1;
- YLoc := YLoc + Y1;
- End;
- If not Initialized then
- Begin
- EnterData := -1;
- Exit;
- End;
- Repeat {Data Conversion Loop}
- Repeat {Data Entry Loop}
- ScreenSaver(MG_TimeOut);
- CharIn := ReadKey;
- GetShiftStatus;
- If ClickOn then
- MakeClickNoise;
- If (CharIn = #00) then
- Begin
- CharIn := ReadKey;{ If you are processing an extended scan code, then }
- Case CharIn of { translate is as a commands }
- #77 : CharIn := ^D; { Unshft RArr }
- #75 : CharIn := ^S; { Unshft LArr }
- #116: CharIn := ^F; { Ctrl'd RArr }
- #115: CharIn := ^A; { Ctrl'd LArr }
- #82,#165
- : CharIn := ^V; { Ins : Unshft, Ctrl'd }
- #83,#166
- : CharIn := ^G; { Del : Unshft, Ctrl'd }
- #71 : Begin
- If Position = 1 then
- Beep
- Else
- Position := 1;
- CharIn := #255;
- End;
- #79 : Begin { UnShft End }
- JumpRightField;
- CharIn := #255;
- End;
- #15 : Begin
- LeftJustify;
- CharIn := #255;
- End;
- { or process it as an exit - delete unused exits }
- #59..#68, #84..#93,
- #94..#103, #104..#113 { All function keys }
- : QueryExits;
- #119, { Ctrl'd Home }
- #117, { End : Ctrl'd }
- #73,#132, { PgUp : Unshft, Ctrl'd }
- #81,#118 { PgDn : Unshft, Ctrl'd }
- : QueryExits;
- #72,#80 { UArr, DArr : Unshft }
- : QueryExits;
- #3,#114, { Ctrl'd 2, Ctrl'd * }
- #120..#131 { Alt'd 1..9,0,-,= }
- : QueryExits;
- #30,#48,#46,#32,#18,#33,#34,#35,#23,#36,#37,#38,#50,
- #49,#24,#25,#16,#19,#31,#20,#22,#47,#17,#45,#21,#44
- : QueryExits; { Alt'd alphabetica, A..Z }
- Else { or declare it to be invalid. }
- CharIn := #00;
- End; {case}
- End;
-
- If CharIn in [#27,#13,#10] then { other exits }
- QueryExits;
-
- If not Done then { If an exit has not been entered, }
- Begin
- Case VarTyp of
- 'U' : If CharIn in ['a'..'z'] then
- CharIn := Chr(Ord(CharIn)-32);
- 'L' : If CharIn in ['A'..'Z'] then
- CharIn := Chr(Ord(CharIn)+32);
- End;
- Case CharIn of { Process CharIn as a command }
- ^D : CursorRight;
- ^S : CursorLeft;
- ^A : JumpLeftWord;
- ^F : JumpRightWord;
- #09 : RightJustify; { Tab = #15 = ^I }
- ^G : DeleteACharacter;
- ^H,#127
- : DestructiveBackspace;
- ^B : ClickOn := not ClickOn;
- ^U : Change2UpperCase;
- ^L : Change2LowerCase;
- ^V : InsertOn := not InsertOn;
- ^E : WorkStr := Copy(WorkStr,1,(Position-1));
- ^X : Begin
- WorkStr := '';
- Position := 1;
- End;
- ^C,^K,^N,^O,^P,^Q,^R,^T,^W,^Y,^Z
- : QueryExits;
- Else { or as a normal character. }
- If (not (CharIn in ValidChars)) then
- If (CharIn <> #255) then
- Beep
- Else
- Else
- If InsertOn then
- If Position <= Length(WorkStr) then
- InsertACharacter
- Else
- AddACharacter
- Else
- If Position <= Length(WorkStr) then
- ChangeACharacter
- Else
- AddACharacter;
- End; {case}
- RefreshDisplay;
- End;
- Until Done;
- AssignValues;
- Until Converted;
- End; {EnterData}
-
- {*******************************************************************}
-
-
- Function Menu;
- Var
- XLoc,YLoc,Block,Width : Integer;
- Ch : Char;
-
- Procedure WriteSelections(XLoc,YLoc:Byte);
- Var
- InitialAttr : Byte;
- I : Integer;
- Begin
- For I := 1 to Selections do
- Begin
- InitialAttr := NormAttr;
- If I = 1 then
- InitialAttr := ReverseAttr;
- Rite(Copy(S,1,(Pos('\',S)-1)),XLoc,(YLoc+I-1),InitialAttr);
- Delete(S,1,Pos('\',S));
- End;
- End; {WriteSelections}
-
- Procedure ReverseBG(X,Y:Byte;Attr:Integer);
- Var
- Loc,I : Integer;
- Begin
- Attr := Attr shl 8;
- For I := 1 to Width do
- Begin
- Loc := (Y-1)*160+(X+I-2)*2;
- MemW[Seg(MG_PhysicalScreen^):Loc] := Attr or Lo(MemW[Seg(MG_PhysicalScreen^):Loc]);
- End;
- End; {ReverseBG}
-
- Procedure MakeSelections;
- Begin
- Block := 1;
- Repeat
- ScreenSaver(MG_TimeOut);
- Ch := ReadKey;
- GetShiftStatus;
- If KeyPressed then
- Begin
- Ch := ReadKey;
- If (Ord(Ch) = 72) and (Block > 1) then
- Begin { 72 : Unshft Up Arrow }
- ReverseBg(XLoc,(YLoc+Block-1),NormAttr);
- Block := Block - 1;
- ReverseBG(XLoc,(YLoc+Block-1),ReverseAttr);
- End
- Else
- If (Ord(Ch) = 80) and (Block < (Selections)) then
- Begin { 80 : Unshft Down Arrow }
- ReverseBg(XLoc,(YLoc+Block-1),NormAttr);
- Block := Block + 1;
- ReverseBG(XLoc,(YLoc+Block-1),ReverseAttr);
- End;
- End;
- Until (Ord(Ch) in [13,27]) or (Ord(Ch) in Exits);
- If Ord(Ch) = 27 then
- Menu := 0
- Else
- If Ord(Ch) in Exits then
- Menu := Ord(Ch)
- Else
- Menu := Block;
- End; {MakeSelections}
-
- Begin
- OpenWindow(Window);
- With MG_LastOpened do
- Begin
- XLoc := X1 + 1;
- YLoc := Y1 + 1;
- Width := X2 - X1 -1;
- End;
- If not MG_RiteFlag[Window] then
- WriteSelections(XLoc,YLoc);
- MakeSelections;
- CloseWindow;
- End; {Menu}
-
- Var
- Init_I : Integer;
-
- Begin
- MG_ScreenLLBase := Nil;
- UserEditSet := [];
- UserExitSet := [];
- For Init_I := 1 to ScreenCount do
- MG_RiteFlag[Init_I] := False;
- MaxLimits;
- Intr($11,MG_Registers);
- If (Lo(MG_Registers.AX) and $30 = $30) then
- Begin
- MG_PhysicalScreen := Ptr($B000,$0000);
- MG_ScreenType := 'M';
- End
- Else
- Begin
- MG_PhysicalScreen := Ptr($B800,$0000);
- MG_ScreenType := 'C';
- End;
- End. {MGProg}