home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MINIGEN.ZIP / MGPROG.INC < prev    next >
Encoding:
Text File  |  1988-01-07  |  23.3 KB  |  934 lines

  1. {** Start of EHSPROG.INC Copyright (c) 1987 Eric H. Snyder **}
  2.  
  3. { Must declare a Const ScreenCount = the # of windows being defined !!!! }
  4.  
  5. Type
  6.   Exitstyp       =  Set of Byte;
  7.   Str80          =  String[80];
  8.   WorkScreenPtr  = ^ScreenImage;
  9.   ScreenImage    =  array[1..25,1..80] of integer;
  10.   ScreenDef      =  Record
  11.                     X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol : Byte;
  12.                     End;
  13.   SavedScreen    = ^SavedScreenRec;
  14.   SavedScreenRec =  Record
  15.                     BackLink        : SavedScreen;
  16.                     XLoc,Yloc       : Integer;
  17.                     ScreenStats     : ScreenDef;
  18.                     SavedScreen     : ScreenImage;
  19.                     End;
  20.   SG_Regs    = Record
  21.                AX,BX,CX,DX,BP,DI,SI,DS,ES,Flags : Integer;
  22.                End;
  23.   FrameChars = Record
  24.                TL,TR,BL,BR,HC,VC : Char;
  25.                End;
  26.  
  27. Const           { Delete unused frame character constant records }
  28.   SingleBar   : FrameChars = (TL:#218;TR:#191;BL:#192;BR:#217;HC:#196;VC:#179);
  29.   DoubleBar   : FrameChars = (TL:#201;TR:#187;BL:#200;BR:#188;HC:#205;VC:#186);
  30.   Horiz2Vert1 : FrameChars = (TL:#213;TR:#184;BL:#212;BR:#190;HC:#205;VC:#179);
  31.   Vert2Horiz1 : FrameChars = (TL:#214;TR:#183;BL:#211;BR:#189;HC:#196;VC:#186);
  32.   {**}
  33.   TopSingle   : FrameChars = (TL:#194;TR:#194;BL:#192;BR:#217;HC:#196;VC:#179);
  34.   TopDouble   : FrameChars = (TL:#203;TR:#203;BL:#200;BR:#188;HC:#205;VC:#186);
  35.   TopH2V1     : FrameChars = (TL:#209;TR:#209;BL:#212;BR:#190;HC:#205;VC:#179);
  36.   TopV2H1     : FrameChars = (TL:#210;TR:#210;BL:#211;BR:#189;HC:#196;VC:#186);
  37.   {**}
  38.   LastOpened  : ScreenDef  = (X1:0;Y1:0;X2:81;Y2:26;BgCol:0;FrameTyp:0;FrCol:0);
  39.   FirstScreen : Boolean    = True;
  40.  
  41. Var
  42.   PhysicalScreen      : ^Char;
  43.   WorkScreen          :  WorkScreenPtr;
  44.   CurrentScreen,
  45.   NewScreen           :  SavedScreen;
  46.   DefinedScreens      :  Array[1..ScreenCount] of ScreenDef;
  47.   TestInt             : Integer;
  48.   TestByte            : Byte;
  49.   TestReal            : Real;
  50.   TestStr             : String[80];
  51.   Result              : Integer;
  52.   UpperByte,LowerByte : Byte;                   { Used                    }
  53.   UpperInt,LowerInt   : Integer;                {      in range           }
  54.   UpperReal,LowerReal : Real;                   {               checking  }
  55.   SG_Registers        : SG_Regs;
  56.   ScreenType          : Char;
  57.  
  58. Procedure InitializeScreens;
  59. Begin
  60. New(WorkScreen);
  61. If Mem[$0040:$0049] = 7 then
  62.   Begin
  63.   PhysicalSCreen := Ptr($B000,$0000);
  64.   ScreenType     := 'M';
  65.   End
  66. Else
  67.   Begin
  68.   PhysicalScreen := Ptr($B800,$0000);
  69.   ScreenType     := 'C';
  70.   End;
  71. End; {InitScreen}
  72.  
  73. Procedure DefineScreen(Ind,dfX1,dfY1,dfX2,dfY2,dfBgCol,dfFrameTyp,dfFrCol:Byte);
  74. Begin
  75. With DefinedScreens[Ind] do
  76.   Begin
  77.   X1       := dfX1;
  78.   Y1       := dfY1;
  79.   X2       := dfX2;
  80.   Y2       := dfY2;
  81.   BgCol    := dfBgCol;
  82.   FrameTyp := dfFrameTyp;
  83.   FrCol    := dfFrCol;
  84.   End;
  85. End;
  86.  
  87. Procedure MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol : Byte;
  88.                                                Frame : FrameChars);
  89. Var
  90.   TopLine,BodyLine,BottomLine : Str80;
  91.   I : Integer;
  92.  
  93. Procedure Rite(S:Str80;X,Y:Byte;Attr:Integer);
  94. Var
  95.   I  : Integer;
  96. Begin
  97. Attr := Attr shl 8;
  98. For I := 1 to Length(S) do
  99.   MemW[Seg(WorkScreen^):(Y-1)*160+(X+I-2)*2] := Attr or Ord(S[I]);
  100. End; {Rite}
  101.  
  102. Begin
  103. With Frame do
  104.   Begin
  105.   {**}                                {Make the top line}
  106.   TopLine[1] := TL;
  107.   FillChar(TopLine[2],((X2-X1)-1),HC);
  108.   TopLine[((X2-X1)+1)] := TR;
  109.   TopLine[0] := Chr(Ord((X2-X1)+1));
  110.   {**}                                {Make the body line}
  111.   BodyLine[1] := VC;
  112.   FillChar(BodyLine[2],((X2-X1)-1),' ');
  113.   BodyLine[((X2-X1)+1)] := VC;
  114.   BodyLine[0] := Chr(Ord((X2-X1)+1));
  115.   {**}                                {Make the bottom line}
  116.   BottomLine[1] := BL;
  117.   FillChar(BottomLine[2],((X2-X1)-1),HC);
  118.   BottomLine[((X2-X1)+1)] := BR;
  119.   BottomLine[0] := Chr(Ord((X2-X1)+1));
  120.   End;
  121. Window(X1,Y1,X2,Y2);
  122. Move(PhysicalScreen^,WorkScreen^,4000);
  123. Rite(TopLine,X1,Y1,FrCol);
  124. For I := (Y1+1) to (Y2-1) do
  125.   Rite(BodyLine,X1,I,FrCol);
  126. Rite(BottomLine,X1,Y2,FrCol);
  127. Move(WorkScreen^,PhysicalScreen^,4000);
  128. Window(X1+1,Y1+1,X2-1,Y2-1);
  129. TextBackground(BgCol);
  130. ClrScr;
  131. End; {MakeFrame}
  132.  
  133. Procedure OpenWindow(Ind:Byte);
  134. Var
  135.   SD : ScreenDef;
  136. Begin
  137. New(NewSCreen);
  138. With NewScreen^ do
  139.   Begin
  140.   XLoc := WhereX;
  141.   YLoc := WhereY;
  142.   Move(PhysicalScreen^,SavedScreen,4000);
  143.   ScreenStats := LastOpened;
  144.   If FirstScreen then
  145.     Begin
  146.     BackLink      := nil;
  147.     FirstScreen   := False;
  148.     End
  149.   Else
  150.     BackLink      := CurrentScreen;
  151.   CurrentScreen := NewScreen
  152.   End;
  153. SD := DefinedScreens[Ind];
  154. With SD do
  155.   Begin
  156.   Case SD.FrameTyp of
  157.     1 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,SingleBar);
  158.     2 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,DoubleBar);
  159.     3 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,Horiz2Vert1);
  160.     4 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,Vert2Horiz1);
  161.     5 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,TopSingle);
  162.     6 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,TopDouble);
  163.     7 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,TopH2V1);
  164.     8 : MakeFrame(X1,Y1,X2,Y2,BgCol,FrameTyp,FrCol,TopV2H1);
  165.     End;
  166.   End;
  167. LastOpened := SD;
  168. End; {OpenWindow}
  169.  
  170. Procedure CloseWindow;
  171. Begin
  172. NewScreen := CurrentScreen;
  173. With NewScreen^ do
  174.   Begin
  175.   Move(SavedScreen,PhysicalScreen^,4000);
  176.   With ScreenStats do
  177.     Window(X1+1,Y1+1,X2-1,Y2-1);
  178.   GotoXY(XLoc,YLoc);
  179.   LastOpened := ScreenStats;
  180.   If BackLink <> Nil then
  181.     CurrentScreen := BackLink;
  182.   End;
  183. Dispose(NewScreen);
  184. End; {CloseWindow}
  185.  
  186. Procedure CloseAllWindows;
  187. Begin
  188. While CurrentScreen^.BackLink <> nil do
  189.   CloseWindow;
  190. End; {CloseAllWindows}
  191.  
  192. Procedure TerminateScreens;
  193. Begin
  194. Dispose(CurrentScreen);
  195. Dispose(WorkScreen);
  196. End; {TerminateScreens}
  197.  
  198. {*******************************************************************}
  199. {** End of windowing routines **}{** Start of data entry routines **}
  200. {*******************************************************************}
  201.  
  202. Procedure MaxLimits;
  203. Begin
  204. LowerByte := 0;         UpperByte := 255;
  205. LowerInt  := -32767;    UpperInt  := MaxInt;
  206. LowerReal := 1E-38;     UpperReal := 1E+37;
  207. End; {MaxLimits}
  208.  
  209. Function EnterData(Var Variable;                { Variable being entered  }
  210.                          VarTyp     : Char;     { Indicated Variable type }
  211.                          XLoc,YLoc,             { X & Y Co-ordinates      }
  212.                          Len,                   { Length of field         }
  213.                          Decs,                  { No. of decimal places   }
  214.                          FieldAttr,
  215.                          CursorAttr : Byte;
  216.                          Exits      : ExitsTyp):Integer; {Exits in addition to }
  217. Type                                                     { -1 : Param error    }
  218.   Edits = Set of Char;                                   {  0 : Typing out     }
  219.                                                          { 13 : Carriage Return}
  220.                                                          {-13 : ^M             }
  221. Const
  222.   BytIntEdits : Edits = ['0'..'9','+','-',' '];        {Pre-defined edit types}
  223.   RealEdits   : Edits = ['0'..'9','+','-','.','E',' '];
  224.   StrEditsAll : Edits = [' '..'}'];
  225.   Alpha       : Edits = ['A'..'Z','a'..'z',' '];
  226.   UpperCase   : Edits = ['A'..'Z',' '];
  227.   LowerCase   : Edits = ['a'..'z',' '];
  228.   Numeric     : Edits = ['0'..'9'];
  229.   Date        : Edits = ['0'..'9','/'];
  230.   ClickOn     : Boolean = False;
  231.   InsertOn    : Boolean = False;
  232.  
  233. Var
  234.   BytVar     : Byte     absolute Variable;
  235.   IntVar     : Integer  absolute Variable;
  236.   RealVar    : Real     absolute Variable;
  237.   StrgVar    : Str80    absolute Variable;
  238.   WorkStr    : Str80;
  239.   OrigStr    : Str80;
  240.   ValidChars : Edits;
  241.   Done       : Boolean;
  242.   Converted  : Boolean;
  243.   CtrlEmm    : Boolean;
  244.   CharIn     : Char;
  245.   Position   : Byte;
  246.  
  247. Procedure Beep;
  248. Begin
  249. Sound(800);
  250. Delay(50);
  251. Nosound;
  252. End; {Beep}
  253.  
  254. Procedure MakeClickNoise;
  255. Begin
  256. Sound(2000);
  257. Delay(5);
  258. NoSound;
  259. End; {ClickNoise}
  260.  
  261. Procedure RefreshDisplay;
  262. Var
  263.   TempStr   : Str80;
  264.   WrkLen,I  : Integer;
  265.  
  266. Procedure RefreshRite(S:Str80;X,Y:Byte);
  267. Var
  268.   I,Attr  : Integer;
  269. Begin
  270. For I := 1 to Length(S) do
  271.   Begin
  272.   Attr := FieldAttr shl 8;
  273.   If (I = Position) and (not Converted) then
  274.     Attr := CursorAttr shl 8;
  275.   MemW[Seg(PhysicalScreen^):(Y-1)*160+(X+I-2)*2] := Attr or Ord(S[I]);
  276.   End;
  277. End; {RefreshRite}
  278.  
  279. Begin
  280. TempStr := WorkStr;
  281. For I := Length(WorkStr) + 1 to Len do
  282.   TempStr := Concat(TempStr,#95);
  283. RefreshRite(TempStr,XLoc,YLoc);
  284. End; {RefreshDisplay}
  285.  
  286. Procedure QueryExits;
  287. Var
  288.   StatusByte : Byte;
  289. Begin
  290. If CharIn = #13 then                { CR always exits }
  291.   Begin
  292.   Done      := True;
  293.   EnterData := 13;
  294.   With SG_Registers do
  295.     Begin
  296.     AX := 2 shl 8;
  297.     Intr($16,SG_Registers);
  298.     StatusByte := Lo(AX);
  299.     If (StatusByte and $04 > 0) then
  300.       Begin
  301.       EnterData := -13;
  302.       CtrlEmm   := True;
  303.       End;
  304.     End
  305.   End
  306. Else
  307.   If (Ord(CharIn) in Exits) then
  308.     Begin
  309.     Done      := True;
  310.     EnterData := Ord(CharIn);
  311.     End
  312.   Else
  313.     Begin
  314.     Beep;
  315.     CharIn := #255;
  316.     End;
  317. End;
  318.  
  319. Procedure CursorRight;
  320. Var
  321.   NewPos : Byte;
  322. Begin
  323. If ((Position = Len) and (Length(WorkStr) = Len)) then
  324.   Begin
  325.   Beep;
  326.   Exit;
  327.   End;
  328. NewPos := Position + 1;
  329. If NewPos <= (Length(WorkStr)+1) then
  330.   Position := NewPos
  331. Else
  332.   Beep;
  333. End; {CursorRight}
  334.  
  335. Procedure CursorLeft;
  336. Var
  337.   NewPos : Byte;
  338. Begin
  339. NewPos := Position - 1;
  340. If NewPos >= 1 then
  341.   Position := NewPos
  342. Else
  343.   Beep;
  344. End; {CursorLeft}
  345.  
  346. Procedure JumpRightWord;
  347. Var
  348.   I,WrkLen : Integer;
  349. Begin
  350. WrkLen := Length(WorkStr);
  351. If (not (VarTyp in ['B','I','R'])) then
  352.   If (Position < WrkLen) then
  353.     Begin
  354.     I := Position;
  355.     If (WorkStr[I] <> ' ') then
  356.       While ((I < WrkLen) and (WorkStr[I] <> ' ')) do
  357.         I := I + 1;
  358.     While ((I < WrkLen) and (WorkStr[I] = ' ')) do
  359.       I := I + 1;
  360.     Position := I;
  361.     End
  362.   Else
  363.     Beep
  364. Else
  365.   Beep;
  366. End; {JumpRightWord}
  367.  
  368. Procedure JumpLeftWord;
  369. Var
  370.   I,WrkLen : Integer;
  371. Begin
  372. If (not (VarTyp in ['B','I','R'])) then
  373.   If (Position > 1) then
  374.     Begin
  375.     I := Position - 1;
  376.     If (WorkStr[I] = ' ') then
  377.       While ((I > 1) and (WorkStr[I] = ' ')) do
  378.         I := I -1;
  379.     While (I > 1) and (WorkStr[I] <> ' ') do
  380.       I := I - 1;
  381.     Position := I;
  382.     If (I > 1) then
  383.       Position := I + 1;
  384.     End
  385. Else
  386.   Beep;
  387. End; {JumpLeftWord}
  388.  
  389. Procedure JumpRightField;
  390. Begin
  391. If Length(WorkStr) = Len then
  392.   If Position = Len then
  393.     Beep
  394.   Else
  395.     Position := Len
  396. Else
  397.   If Position = Length(WorkStr) + 1 then
  398.     Beep
  399.   Else
  400.     Position := Length(WorkStr) + 1;
  401. End;
  402.  
  403. Procedure RightJustify;
  404. Var
  405.   StatusByte : Byte;
  406. Begin
  407. With SG_Registers do
  408.   Begin
  409.   AX := 2 shl 8;
  410.   Intr($16,SG_Registers);
  411.   StatusByte := Lo(AX);
  412.   If (StatusByte and $04 > 0) then
  413.     Begin
  414.     QueryExits;
  415.     Exit;
  416.     End;
  417.   End;
  418. If (VarTyp in ['B','I','R']) then
  419.   Beep
  420. Else
  421.   If (Length(WorkStr) < Len) then
  422.     Begin
  423.     Position := 1;
  424.     While WorkStr[Length(WorkStr)] = ' ' do
  425.       Delete(WorkStr,Length(WorkStr),1);
  426.     While Length(WorkStr) < Len do
  427.       Begin
  428.       WorkStr  := Concat(' ',WorkStr);
  429.       Position := Position + 1;
  430.       End;
  431.     End;
  432. End; {RightJustify}
  433.  
  434. Procedure LeftJustify;
  435. Begin
  436. If (VarTyp in ['B','I','R']) then
  437.   Beep
  438. Else
  439.   Begin
  440.   While WorkStr[1] = ' ' do
  441.     Delete(WorkStr,1,1);
  442.   Position := 1;
  443.   End;
  444. End; {LeftJustify}
  445.  
  446. Procedure Change2UpperCase;
  447. Var
  448.   I : Integer;
  449. Begin
  450. If not (VarTyp in ['S','A']) then
  451.   Beep
  452. Else
  453.   For I := 1 to Length(WorkStr) do
  454.     If WorkStr[I] in ['a'..'z'] then
  455.       WorkStr[I] := Chr(Ord(WorkStr[I])-32);
  456. End; {Change2UpperCase}
  457.  
  458. Procedure Change2LowerCase;
  459. Var
  460.   I : Integer;
  461. Begin
  462. If not (VarTyp in ['S','A']) then
  463.   Beep
  464. Else
  465.   For I := 1 to Length(WorkStr) do
  466.     If WorkStr[I] in ['A'..'Z'] then
  467.       WorkStr[I] := Chr(Ord(WorkStr[I])+32);
  468. End; {Change2LowerCase}
  469.  
  470. Procedure AddACharacter;
  471. Var
  472.   NewPos : Integer;
  473. Begin
  474. If Position < Len then
  475.   NewPos := Position + 1
  476. Else
  477.   If Length(WorkStr) <> Len then
  478.     NewPos := Position
  479.   Else
  480.    Begin
  481.    Beep;
  482.    Exit;
  483.    End;
  484. If NewPos <= Len then
  485.   Begin
  486.   WorkStr  := Concat(WorkStr,CharIn);
  487.   If Position < Len then
  488.     Position := Position + 1;
  489.   If (VarTyp in ['S','A','U','L','N','D'])  and
  490.      (Length(WorkStr) = Len)  then
  491.        Begin
  492.        Done      := True;
  493.        EnterData := 0;
  494.        End;
  495.   End;
  496. End; {AddACharacter}
  497.  
  498. Procedure ChangeACharacter;
  499. Begin
  500. WorkStr[Position] := CharIn;
  501. If (Position < Len) then
  502.   Position := Position + 1;
  503. End;
  504.  
  505. Procedure InsertACharacter;
  506. Begin
  507. If (Length(WorkStr) + 1) <= Len then
  508.   Begin
  509.   Insert(CharIn,WorkStr,Position);
  510.   Position := Position + 1;
  511.   End
  512. Else
  513.   Beep;
  514. End; {InsertACharacter}
  515.  
  516. Procedure DeleteACharacter;
  517. Begin
  518. If Length(WorkStr) > 0 then
  519.   Delete(WorkStr,Position,1)
  520. Else
  521.   Beep;
  522. End; {DeleteACharacter}
  523.  
  524. Procedure DestructiveBackspace;
  525. Begin
  526. If (Length(WorkStr) > 0)  and
  527.    (Position > 1)         then
  528.   Begin
  529.   Position := Position - 1;
  530.   Delete(WorkStr,Position,1);
  531.   End
  532. Else
  533.   Beep;
  534. End;
  535.  
  536. Function Initialized : Boolean;
  537. Begin
  538. Initialized := False;
  539. If VarTyp in ['B','I','R'] then
  540.   Begin
  541.   Case VarTyp of
  542.     'B' : Str(BytVar,WorkStr);
  543.     'I' : Str(IntVar,WorkStr);
  544.     'R' : Begin
  545.           Str(RealVar:Len:Decs,WorkStr);
  546.           While WorkStr[1] = ' ' do
  547.             Delete(WorkStr,1,1);
  548.           End;
  549.     End;
  550.   If Length(WorkStr) <= Len then
  551.     Begin
  552.     Initialized := True;
  553.     OrigStr     := WorkStr;
  554.     RefreshDisplay;
  555.     End;
  556.   End
  557. Else
  558.   If VarTyp in ['S','A','U','L','N','D'] then
  559.     Begin
  560.     WorkStr     := StrgVar;
  561.     Initialized := True;
  562.     OrigStr     := WorkStr;
  563.     RefreshDisplay;
  564.     End;
  565. End; {Initialized}
  566.  
  567. Procedure AssignValues;
  568. Var
  569.   RetnCode,WrkLen,TempInt  : Integer;
  570.   TempReal                 : Real;
  571.   ConvertStr               : Str80;
  572.  
  573. Function Clean(NumericString:Str80):Str80;
  574. Begin
  575. While (Length(NumericString) > 0) and
  576.       (NumericString[1] = ' ') do
  577.   Delete(NumericString,1,1);
  578. While (Length(NumericString) > 0) and
  579.       (NumericString[Length(NumericString)] = ' ') do
  580.   Delete(NumericString,Length(NumericString),1);
  581. If (Length(NumericString) = 0) then
  582.   NumericString := ' ';
  583. Clean := NumericString;
  584. End; {Clean}
  585.  
  586. Procedure NumericFormat;
  587. Var
  588.   I,PLoc : Integer;
  589. Begin
  590. ConvertStr := Clean(ConvertStr);
  591. If (Pos('E',ConvertStr) > 0) then
  592.   Begin
  593.   While (Length(ConvertStr) < Len) do
  594.     ConvertStr := Concat(' ',ConvertStr);
  595.   WorkStr := ConvertStr;
  596.   RefreshDisplay;
  597.   Exit;
  598.   End;
  599. PLoc := Pos('.',ConvertStr);
  600. If PLoc = 0 then
  601.   I := Length(ConvertStr) + 1
  602. Else
  603.   I := PLoc;
  604. While I > 1 do
  605.   Begin
  606.   I := I - 3;
  607.   If I > 1 then
  608.     Insert(',',ConvertStr,I);
  609.   End;
  610. If Length(ConvertStr) <= Len then
  611.   Begin
  612.   While Length(ConvertStr) < Len do
  613.     ConvertStr := Concat(' ',ConvertStr);
  614.   WorkStr := ConvertStr;
  615.   RefreshDisplay;
  616.   End
  617. Else
  618.   Begin
  619.   While Length(WorkStr) < Len do
  620.     WorkStr := Concat(' ',WorkStr);
  621.   RefreshDisplay;
  622.   End;
  623. End; {NumericFormat}
  624.  
  625. Begin
  626. If ((Ord(CharIn) in Exits) or CtrlEmm) then
  627.   Begin
  628.   Converted := True;
  629.   WorkStr   := OrigStr;
  630.   RefreshDisplay;
  631.   Exit;
  632.   End;
  633. If VarTyp in ['B','I','R'] then
  634.   Begin
  635.   ConvertStr := WorkStr;
  636.   Case VarTyp of
  637.     'B' : Val(Clean(ConvertStr),TempInt,RetnCode);
  638.     'I' : Val(Clean(ConvertStr),TempInt,RetnCode);
  639.     'R' : Val(Clean(ConvertStr),TempReal,RetnCode);
  640.     End; {case}
  641.   If RetnCode = 0 then
  642.     Begin
  643.     Case VarTyp of
  644.       'B' : If (TempInt >= LowerByte) and (TempInt <= UpperByte) then
  645.               Begin
  646.               BytVar    := TempInt;
  647.               Converted := True;
  648.               End;
  649.       'I' : If (TempInt >= LowerInt) and (TempInt <= UpperInt) then
  650.               Begin
  651.               IntVar    := TempInt;
  652.               Converted := True;
  653.               End;
  654.       'R' : If (TempReal >= LowerReal) and (TempReal <= UpperReal) then
  655.               Begin
  656.               RealVar   := TempReal;
  657.               Converted := True;
  658.               End;
  659.       End; {case}
  660.     If Converted then
  661.       NumericFormat
  662.     Else
  663.       Begin
  664.       Done     := False;
  665.       Position := 1;
  666.       RefreshDisplay;
  667.       Beep;
  668.       End;
  669.     End
  670.   Else
  671.     Begin
  672.     Done     := False;
  673.     Position := RetnCode;
  674.     RefreshDisplay;
  675.     Beep;
  676.     End;
  677.   End
  678. Else
  679.   Begin
  680.   StrgVar   := WorkStr;
  681.   Converted := True;
  682.   RefreshDisplay;
  683.   End;
  684. End; {AssignValues}
  685.  
  686. Begin
  687. Done      := False;
  688. Converted := False;
  689. CtrlEmm   := False;
  690. Position  := 1;
  691. Case VarTyp of
  692.   'B','I'
  693.       : ValidChars := BytIntEdits;
  694.   'R' : ValidChars := RealEdits;
  695.   'S' : ValidChars := StrEditsAll;
  696.   'A' : ValidChars := Alpha;
  697.   'U' : ValidChars := UpperCase;
  698.   'L' : ValidChars := LowerCase;
  699.   'N' : ValidChars := Numeric;
  700.   'D' : ValidChars := Date;
  701. Else
  702.   Begin
  703.   EnterData := -1;
  704.   Exit;
  705.   End;
  706. End; {case}
  707. If Len > 78 then
  708.   Begin
  709.   EnterData := -1;
  710.   Exit;
  711.   End;
  712. With LastOpened do
  713.   Begin
  714.   XLoc := XLoc + X1;
  715.   YLoc := YLoc + Y1;
  716.   End;
  717. If not Initialized then
  718.   Begin
  719.   EnterData := -1;
  720.   Exit;
  721.   End;
  722. Repeat  {Data Conversion Loop}
  723.   Repeat  {Data Entry Loop}
  724.     Reset(kbd);
  725.     Read(kbd,CharIn);
  726.     If ClickOn then
  727.       MakeClickNoise;
  728.     If (CharIn = #27) and KeyPressed then
  729.       Begin
  730.       Read(kbd,CharIn); { If you are processing an extended scan code, then }
  731.       Case CharIn of          { translate is as a commands }
  732.         #77 : CharIn := ^D;      { Unshft RArr }
  733.         #75 : CharIn := ^S;      { Unshft LArr }
  734.         #116: CharIn := ^F;      { Ctrl'd RArr }
  735.         #115: CharIn := ^A;      { Ctrl'd LArr }
  736.         #82,#165
  737.             : CharIn := ^V;      { Ins : Unshft, Ctrl'd }
  738.         #83,#166
  739.             : CharIn := ^G;      { Del : Unshft, Ctrl'd }
  740.         #71 : Begin
  741.               If Position = 1 then
  742.                 Beep
  743.               Else
  744.                 Position := 1;
  745.               CharIn := #255;
  746.               End;
  747.         #79 : Begin              { UnShft End }
  748.               JumpRightField;
  749.               CharIn := #255;
  750.               End;
  751.         #15 : Begin
  752.               LeftJustify;
  753.               CharIn := #255;
  754.               End;
  755.                               { or process it as an exit - delete unused exits }
  756.         #59..#68,  #84..#93,
  757.         #94..#103, #104..#113    { All function keys }
  758.             : QueryExits;
  759.         #119,                    { Ctrl'd Home }
  760.         #117,                    { End  : Ctrl'd }
  761.         #73,#132,                { PgUp : Unshft, Ctrl'd }
  762.         #81,#118                 { PgDn : Unshft, Ctrl'd }
  763.             : QueryExits;
  764.         #72,#80                  { UArr, DArr : Unshft }
  765.             : QueryExits;
  766.         #3,#114,                 { Ctrl'd 2, Ctrl'd * }
  767.         #120..#131               { Alt'd 1..9,0,-,= }
  768.             : QueryExits;
  769.         #30,#48,#46,#32,#18,#33,#34,#35,#23,#36,#37,#38,#50,
  770.         #49,#24,#25,#16,#19,#31,#20,#22,#47,#17,#45,#21,#44
  771.             : QueryExits;        { Alt'd alphabetica, A..Z }
  772.       Else                    { or declare it to be invalid. }
  773.               CharIn := #00;
  774.         End; {case}
  775.       End;
  776.  
  777.     If CharIn in [#27,#13,#10] then  { other exits }
  778.       QueryExits;
  779.  
  780.     If not Done then      { If an exit has not been entered, }
  781.       Begin
  782.       Case VarTyp of
  783.         'U' : If CharIn in ['a'..'z'] then
  784.                 CharIn := Chr(Ord(CharIn)-32);
  785.         'L' : If CharIn in ['A'..'Z'] then
  786.                 CharIn := Chr(Ord(CharIn)+32);
  787.         End;
  788.       Case CharIn of                { Process CharIn as a command  }
  789.         ^D : CursorRight;
  790.         ^S : CursorLeft;
  791.         ^A : JumpLeftWord;
  792.         ^F : JumpRightWord;
  793.        #09 : RightJustify;          { Tab = #15 = ^I }
  794.         ^G : DeleteACharacter;
  795.         ^H,#127
  796.            : DestructiveBackspace;
  797.         ^B : ClickOn  := not ClickOn;
  798.         ^U : Change2UpperCase;
  799.         ^L : Change2LowerCase;
  800.         ^V : InsertOn := not InsertOn;
  801.         ^E : WorkStr  := Copy(WorkStr,1,(Position-1));
  802.         ^X : Begin
  803.              WorkStr  := '';
  804.              Position := 1;
  805.              End;
  806.         ^C,^K,^N,^O,^P,^Q,^R,^T,^W,^Y,^Z
  807.            : QueryExits;
  808.       Else                    { or as a normal character. }
  809.         If (not (CharIn in ValidChars)) then
  810.           If (CharIn <> #255) then
  811.             Beep
  812.           Else
  813.         Else
  814.           If InsertOn then
  815.             If Position <= Length(WorkStr) then
  816.               InsertACharacter
  817.             Else
  818.               AddACharacter
  819.           Else
  820.             If Position <= Length(WorkStr) then
  821.               ChangeACharacter
  822.             Else
  823.               AddACharacter;
  824.       End; {case}
  825.     RefreshDisplay;
  826.     End;
  827.   Until Done;
  828. AssignValues;
  829. Until Converted;
  830. End; {EnterData}
  831.  
  832. Type
  833.   Str255 = String[255];
  834.  
  835. Procedure Rite(S:Str80;X,Y:Byte;Attr:Integer);
  836. Var
  837.   I,Loc  : Integer;
  838. Begin
  839. Attr := Attr shl 8;
  840. For I := 1 to Length(S) do
  841.   MemW[Seg(PhysicalScreen^):(Y-1)*160+(X+I-2)*2] := Attr or Ord(S[I]);
  842. End; {Rite}
  843.  
  844. Procedure WinRite(S:Str80;X,Y:Byte;Attr:Integer);
  845. Begin
  846. With LastOpened do
  847.   Begin
  848.   X := X + X1;
  849.   Y := Y + Y1;
  850.   End;
  851. Rite(S,X,Y,Attr);
  852. End; {WinRite}
  853.  
  854. Function Menu(Window  : Byte;
  855.                    S  : Str255;
  856.           Selections,NormAttr,ReverseAttr
  857.                       : Byte;
  858.                Exits  : ExitsTyp) : Byte;
  859. Var
  860.   I,XLoc,YLoc,Block,Width : Integer;
  861.                        Ch : Char;
  862.  
  863. Procedure WriteSelections(XLoc,YLoc:Byte);
  864. Var
  865.   InitialAttr : Byte;
  866. Begin
  867. For I := 1 to Selections do
  868.   Begin
  869.   InitialAttr := NormAttr;
  870.   If I = 1 then
  871.     InitialAttr := ReverseAttr;
  872.   Rite(Copy(S,1,(Pos('\',S)-1)),XLoc,(YLoc+I-1),InitialAttr);
  873.   Delete(S,1,Pos('\',S));
  874.   End;
  875. End; {WriteSelections}
  876.  
  877. Procedure ReverseBG(X,Y:Byte;Attr:Integer);
  878. Var
  879.   Loc : Integer;
  880. Begin
  881. Attr := Attr shl 8;
  882. For I := 1 to Width do
  883.   Begin
  884.   Loc := (Y-1)*160+(X+I-2)*2;
  885.   MemW[Seg(PhysicalScreen^):Loc] := Attr or Lo(MemW[Seg(PhysicalScreen^):Loc]);
  886.   End;
  887. End; {ReverseBG}
  888.  
  889. Procedure MakeSelections;
  890. Begin
  891. Block := 1;
  892. Repeat
  893.   Read(kbd,Ch);
  894.   If KeyPressed then
  895.     Begin
  896.     Read(kbd,Ch);
  897.     If (Ord(Ch) = 72) and (Block > 1) then
  898.       Begin                                      { 72 : Unshft Up Arrow }
  899.       ReverseBg(XLoc,(YLoc+Block-1),NormAttr);
  900.       Block := Block - 1;
  901.       ReverseBG(XLoc,(YLoc+Block-1),ReverseAttr);
  902.       End
  903.     Else
  904.       If (Ord(Ch) = 80) and (Block < (Selections)) then
  905.         Begin                                    { 80 : Unshft Down Arrow }
  906.         ReverseBg(XLoc,(YLoc+Block-1),NormAttr);
  907.         Block := Block + 1;
  908.         ReverseBG(XLoc,(YLoc+Block-1),ReverseAttr);
  909.         End;
  910.     End;
  911. Until (Ord(Ch) in [13,27]) or (Ord(Ch) in Exits);
  912. If Ord(Ch) = 27 then
  913.   Menu := 0
  914. Else
  915.   If Ord(Ch) in Exits then
  916.     Menu := Ord(Ch)
  917.   Else
  918.     Menu := Block;
  919. End; {MakeSelections}
  920.  
  921. Begin
  922. OpenWindow(Window);
  923. With LastOpened do
  924.   Begin
  925.   XLoc  := X1 + 1;
  926.   YLoc  := Y1 + 1;
  927.   Width := X2 - X1 -1;
  928.   End;
  929. WriteSelections(XLoc,YLoc);
  930. MakeSelections;
  931. CloseWindow;
  932. End; {Menu}
  933.  
  934. {** End of MGPROG.INC **}{**********************************************}