home *** CD-ROM | disk | FTP | other *** search
- {
- --------------------------------------------------------------------------
- F i l e I n f o r m a t i o n
-
- * DESCRIPTION
- File used with FM.PAS.
-
- * ASSOCIATED FILES
- FM.PAS
- FM.DOC
- FM.EXE
- FM.TPU
- FMFILE.PAS
- FMINPUT.PAS
- FMSCREEN.PAS
- FMUTEST.EXE
- FMUTEST.PAS
- FMVIEW.PAS
-
- ==========================================================================
- }
- {$R-} { Range checking off } { Unit: FMInput.PAS }
- {$S-} { Stack checking off } { Program: FM.PAS }
- {$V+} { Strict String parameter checking on } { Author: Jim Zwick }
- {$I-} { I/O checking off } { Version: 1.0 }
- {$B-} { Boolean short-circuit evaluation on } { Date: 03-04-88 }
-
- UNIT FMInput;
-
- INTERFACE
-
- USES
- Crt,
- FMScreen;
-
-
- TYPE
- Str80 = STRING[80];
-
- CONST
- Up = #200;
- Down = #208;
- PgUp = #201;
- PgDn = #209;
- Home = #199;
- EndKey = #207;
- Left = #203;
- Right = #205;
- F1 = #187;
-
-
- FUNCTION PadR(St : Str80; Ch : CHAR; FW: BYTE) : Str80;
- FUNCTION GetKey(KeyList : Str80; UpperCase : BOOLEAN) : CHAR;
- PROCEDURE ReadStr(X, Y, Len : BYTE; VAR S : Str80);
- PROCEDURE WritePrompt(X, Y : BYTE; Msg : Str80);
-
-
- IMPLEMENTATION
-
- FUNCTION PadR(St : Str80; Ch : CHAR; FW: BYTE) : Str80;
- VAR
- TS : Str80;
- BEGIN
- IF (LENGTH(St) >= FW) THEN PadR := COPY(St, 1, FW) { Reduce to FW }
- ELSE
- BEGIN
- FILLCHAR(TS, SIZEOF(TS), Ch); { Pad St with Ch to fill FW }
- TS[0] := CHR(FW - LENGTH(St));
- PadR := St + TS;
- END;
- END;
- { ------------------------------------------------------------------------- }
-
- FUNCTION GetKey(KeyList : Str80; UpperCase : BOOLEAN) : CHAR;
- VAR
- Ch, Ch2 : CHAR; { Retrieves keystroke, converts to upper case }
- BEGIN { if requested, converts extended scan codes }
- REPEAT { by adding 128 so they can be interpreted by }
- KbdStatus; { single IF or CASE statements }
- Ch := ReadKey;
- IF UpperCase THEN Ch := UPCASE(Ch);
- GetKey := Ch;
- IF (Ch = #0) AND KEYPRESSED THEN
- BEGIN
- Ch2 := ReadKey;
- IF (ORD(Ch2) < 128) THEN Ch2 := CHR(ORD(Ch2) + 128);
- GetKey := Ch2;
- END;
- IF (LENGTH(KeyList) = 0) THEN EXIT;
- UNTIL POS(Ch, KeyList) > 0;
- END;
- { ------------------------------------------------------------------------- }
-
- PROCEDURE ReadFld(X, Y, Len : BYTE; St : Str80; VAR OutStr : Str80);
- CONST
- BS = ^H; { Line editor with implementation of many standard }
- BackSp = #8; { editing functions. Others can be easily added }
- CR = #13; { by expanding options in CASE statement. It }
- Esc = #27; { returns OutStr from position 1 to cursor position }
- CtrlLeft = #243;
- CtrlRight = #244;
- CtrlEnd = #245;
- DelKey = #211;
-
- VAR
- P, TempP : INTEGER;
- Ch : CHAR;
- EndLine : BOOLEAN;
-
- { ------------------ }
-
- BEGIN
- P := 1;
- EndLine := FALSE;
- GotoXY(X, Y); WRITE(St);
- REPEAT
- St := PadR(St, '_', Len); { Maintains marked field width be adding }
- GotoXY(X+P-1, Y); { directly to work string, then returns }
- CursorOn(TRUE); { OutStr only to cursor position }
- Ch := GetKey('', TRUE);
- CursorOn(FALSE);
- CASE Ch OF
- #32..#126 : IF (P <= Len) THEN
- BEGIN
- IF (InsKeyOn) THEN { Insert }
- BEGIN
- DELETE(St, Len, 1);
- INSERT(Ch, St, P);
- WRITE(COPY(St, P, Len));
- END
- ELSE
- BEGIN
- WRITE(Ch); { Overwrite }
- St[P] := Ch;
- END;
- Inc(P);
- END;
- CR : EndLine := TRUE;
- Home : P := 1;
- EndKey : BEGIN
- P := Len;
- WHILE (St[P] = '_') AND (P > 1) DO Dec(P);
- IF (St[P] <> '_') THEN Inc(P);
- END;
- Left : IF (P > 1) THEN Dec(P);
- Right : IF (P <= Len) THEN Inc(P);
- CtrlLeft : BEGIN { Move left one word }
- WHILE (P > 1) AND (St[P-1] = '_') DO Dec(P);
- WHILE (P > 1) AND (St[P-1] = ' ') DO Dec(P);
- WHILE (P > 1) AND (St[P-1] <> ' ') DO Dec(P);
- END;
- CtrlRight : BEGIN { Move right one word }
- WHILE (P <= Len) AND (St[P-1] = ' ') DO Inc(P);
- WHILE (P <= Len) AND (St[P-1] <> ' ') DO Inc(P);
- WHILE (P > 1) AND (St[P-1] = '_') DO Dec(P);
- END;
- BackSp : IF (P > 1) THEN
- BEGIN
- Dec(P);
- DELETE(St, P, 1);
- WRITE(BS, COPY(St, P, Len), '_');
- END;
- DelKey : IF (P >= 1) THEN
- BEGIN
- DELETE(St, P, 1);
- WRITE(COPY(St, P, Len), '_');
- END;
- Esc : BEGIN
- St := '';
- IF (P = 1) THEN EndLine := TRUE { If cursor at start of }
- ELSE { field then exit, ELSE }
- BEGIN { delete field and move }
- GotoXY(X, Y); { cursor to start of }
- WRITE(PadR(St, '_', Len)); { field }
- P := 1;
- END;
- END;
- CtrlEnd : BEGIN { Delete from cursor to end of field }
- St := PadR(COPY(St, 1, P - 1), '_', Len);
- GotoXY(X, Y);
- WRITE(St);
- END;
- END;
- UNTIL EndLine;
- CursorOn(TRUE);
- OutStr := COPY(St, 1, P-1)
- END;
- { ------------------------------------------------------------------------- }
-
- PROCEDURE ReadStr(X, Y, Len : BYTE; VAR S : Str80);
- VAR
- NewStr : Str80; { Reads string with ReadFld, returns changed String }
- BEGIN { only if NULL string not returned from ReadFld }
- NewStr[0] := #0;
- ReadFld(X, Y, Len, PadR(S, '_', Len), NewStr);
- IF NewStr[0] <> #0 THEN S := NewStr;
- GotoXY(X, Y);
- WRITE(PadR(S, ' ', Len));
- END;
- { ------------------------------------------------------------------------- }
-
- PROCEDURE WritePrompt(X, Y : BYTE; Msg : Str80);
- VAR
- Reply : CHAR;
- BEGIN
- HIGHVIDEO;
- ClrLn(X, Y); WRITE(Msg, ' -- Press Any Key');
- LOWVIDEO;
- Reply := GetKey('', FALSE);
- ClrLn(X, Y);
- END;
- { ------------------------------------------------------------------------- }
-
- END.
-