[Back to KEYBOARD SWAG index] [Back to Main SWAG index] [Original]
UNIT KeyInput;
INTERFACE
USES CRT, {Import Sound function}
CURSOR; {Import ChangeCursor}
CONST
StandardInput = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV'
+'WXYZ1234567890~!@#$%^&*()-+\[]{};:`''".,/<> =_?|';
HighBitInput = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV'
+'WXYZ1234567890~!@#$%^&*()-+\[]{};:`''".,/<> =_?|'
+'€™¡¢£¤¥¦§¨©ª«®'
+'¯°±²³´µº¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞ'
+'ßàáâ
äåæçèéêëìíîïðñòóôõö÷øùúûüýþ';
FilenameInput = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV'
+'WXYZ1234567890~!@#$%^&()-_{}.';
FilespecInput = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV'
+'WXYZ1234567890~!@#$%^&()-_{}.?*';
FilepathInput = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV'
+'WXYZ1234567890~!@#$%^&()-_{}.?*:\';
NumberInput = '123456790.-+';
BackSpace = #8;
Space = ' ';
TYPE
TInput = (Standard,HighBit,Filename,Filespec,Filepath,Number);
VAR
MaskCh: Char; {must be set before using}
PROCEDURE GetInput(VAR InStr; (* Variable being edited *)
WhatWas: String; (* "Old" Value -- being edited *)
InputType: TInput; (* Input type -- from TInput *)
Len, (* Maximum Characters *)
XPos, (* X Start Position *)
YPos, (* Y Start Position *)
Attr, (* Text Attribute while editing *)
HighLightAttr: Byte; (* Attribute of Highlighted Text *)
BackCh: Char; (* Background Character *)
MaskInput, (* Masked Input? -- Set "MaskCh" *)
Caps: Boolean); (* Force CAPS? *)
IMPLEMENTATION
PROCEDURE MY_Delay(MS: Word); Assembler;
(* My Delay procedure, used instead of TP6.0's Delay procedure *)
ASM
MOV Ax, 1000;
MUL MS;
MOV Cx, Dx;
MOV Dx, Ax;
MOV Ah, $86;
INT $15;
END;
PROCEDURE GetInput(VAR InStr;
WhatWas: String;
InputType: TInput;
Len,
XPos,
YPos,
Attr,
HighLightAttr: Byte;
BackCh: Char;
MaskInput,
Caps: Boolean);
TYPE
TInsert = (On,Off); (* Insert On/Off Type *)
VAR
Temp: String; (* Temporary String Holder *)
Ch: Char; (* Reads Characters *)
A, B, U: Byte; (* Counters *)
ValidKey, (* Whether is valid key *)
FirstChar, (* Whether is first char entered *)
InsertOn, (* Insert or overstrike mode *)
NoAdd: Boolean; (* Whether to add key to string *)
NewString: String ABSOLUTE InStr; (* String being edited *)
PROCEDURE Ding;
(* Makes sound to tell user invalid key was pressed *)
BEGIN
Sound(300);
MY_Delay(30);
NoSound;
END;
PROCEDURE ToggleInsert(Ins: TInsert);
(* Toggles Insert/Overstrike Mode via TInsert type *)
BEGIN
IF Ins = On THEN
BEGIN
InsertOn := TRUE;
ChangeCursor(NormCursor);
END
ELSE
BEGIN
InsertOn := FALSE;
ChangeCursor(BlockCursor);
END;
END;
PROCEDURE FlushKBuff;
(* Flush keyboard buffer *)
VAR Flush: Char;
BEGIN
WHILE KeyPressed DO Flush := Readkey;
END;
BEGIN
ChangeCursor(NormCursor); (* Default to normal cursor *)
InsertOn := TRUE; (* Default to Insert Mode *)
FirstChar := TRUE; (* Set to first character being entered *)
NewString := ''; (* Null NewString *)
Temp := ''; (* Null Temporary String *)
GotoXY(XPos,YPos);
TextAttr := Attr;
FOR U := 1 TO Len DO Write(BackCh);
GotoXY(XPos,YPos);
FlushKBuff;
Ch := #0;
TextAttr := HighLightAttr;
NewString := WhatWas;
IF MaskInput THEN FOR U := 1 TO Length(NewString) DO Write(MaskCh)
ELSE Write(NewString);
B := Length(WhatWas);
A := B;
(* "A" Counter = How many characters are in string *)
(* "B" Counter = Current cursor placement in string *)
TextAttr := Attr;
WHILE (Ch <> #13) AND (Ch <> #27) DO
BEGIN
NoAdd := FALSE; (* Default to add key to string *)
ValidKey := FALSE; (* Default to invalid key unless proven valid *)
IF Caps THEN Ch := UpCase(ReadKey)
ELSE Ch := ReadKey;
CASE InputType OF (* Check if Ch is in the input list *)
Standard: IF (POS(Ch,StandardInput) > 0) OR
(Ch IN [#13,#27,#0,#8,#25]) THEN ValidKey := TRUE;
HighBit : IF (POS(Ch,HighBitInput) > 0) OR
(Ch IN [#13,#27,#0,#8,#25]) THEN ValidKey := TRUE;
Filename: IF (POS(Ch,FilenameInput) > 0) OR
(Ch IN [#13,#27,#0,#8,#25]) THEN ValidKey := TRUE;
Filespec: IF (POS(Ch,FilespecInput) > 0) OR
(Ch IN [#13,#27,#0,#8,#25]) THEN ValidKey := TRUE;
Filepath: IF (POS(Ch,FilepathInput) > 0) OR
(Ch IN [#13,#27,#0,#8,#25]) THEN ValidKey := TRUE;
Number : IF (POS(Ch,NumberInput) > 0) OR
(Ch IN [#13,#27,#0,#8,#25]) THEN ValidKey := TRUE;
END;
IF ValidKey THEN
BEGIN
CASE Ch OF
#0 : BEGIN
NoAdd := TRUE;
IF FirstChar THEN
BEGIN
FirstChar := FALSE;
GotoXY(XPos,YPos);
IF MaskInput THEN FOR U := 1 TO Length(NewString) DO Write(MaskCh)
ELSE Write(NewString);
END;
Ch := UpCase(ReadKey);
CASE Ch OF
#77: IF B <= Length(NewString)-1 THEN {Right Arrow}
BEGIN
GotoXY(XPos+B+1,YPos);
Inc(B);
END
ELSE Ding;
#75: IF B >= 1 THEN {Left Arrow}
BEGIN
GotoXY(XPos+B-1,YPos);
Dec(B);
END
ELSE Ding;
#71: BEGIN {Home}
GotoXY(XPos,YPos);
B := 0;
END;
#79: BEGIN {End}
GotoXY(XPos+Length(NewString),YPos);
B := Length(NewString);
END;
#82: IF InsertOn THEN ToggleInsert(Off) {Ins}
ELSE ToggleInsert(On);
#83: BEGIN {Del}
IF (B < Length(NewString)) AND (B >= 0) THEN
BEGIN
Delete(NewString,B+1,1);
FOR U := B TO Length(NewString) DO
IF MaskInput THEN
BEGIN
IF U <> B THEN Temp := Temp + MaskCh
ELSE Temp := '';
END
ELSE
BEGIN
IF U <> B THEN Temp := Temp + NewString[U]
ELSE Temp := '';
END;
GotoXY(XPos+B,YPos);
Write(Temp);
Write(BackCh);
GotoXY(XPos+B,YPos);
Dec(A);
END;
END;
ELSE Ding;
END;
FlushKBuff;
END;
#8 : IF B >= 1 THEN {Backspace}
BEGIN
IF FirstChar THEN
BEGIN
FirstChar := FALSE;
GotoXY(XPos,YPos);
IF MaskInput THEN FOR U := 1 TO Length(NewString) DO Write(MaskCh)
ELSE Write(NewString);
END;
Delete(NewString,B,1);
Write(Backspace,BackCh,Backspace);
Dec(B);
Dec(A);
GotoXY(XPos+B,YPos);
FOR U := B TO Length(NewString) DO
IF MaskInput THEN
BEGIN
IF B <> U THEN Temp := Temp + MaskCh
ELSE Temp := '';
END
ELSE
BEGIN
IF B <> U THEN Temp := Temp + NewString[U]
ELSE Temp := '';
END;
Write(Temp);
FOR U := Length(NewString)+1 TO Len DO Write(BackCh);
GotoXY(XPos+B,YPos);
NoAdd := TRUE;
END
ELSE Ding;
#27: BEGIN {Esc}
NoAdd := TRUE;
NewString := WhatWas;
END;
#25: BEGIN {CTRL+Y}
NoAdd := TRUE;
NewString := '';
GotoXY(XPos,YPos);
FOR U := 1 TO Len DO Write(BackCh);
FirstChar := FALSE;
GotoXY(XPos,YPos);
B := 0;
A := 0;
END;
#13: NoAdd := TRUE;
END;
IF (((A < Len) OR ((A < Len+1) AND NOT(InsertOn))) AND (NoAdd = FALSE)
AND (Ch <> #8)) OR ((FirstChar) AND (NOT(NoAdd)) AND (Ch <> #8)) THEN
BEGIN
IF FirstChar THEN
BEGIN
NewString := '';
GotoXY(XPos,YPos);
B := 0;
A := 0;
FOR U := 1 TO Len Do Write(BackCh);
GotoXY(XPos,YPos);
FirstChar := FALSE;
END;
IF InsertOn THEN
BEGIN
Inc(B);
Inc(A);
Insert(Ch,NewString,B);
FOR U := B TO Length(NewString) DO
IF MaskInput THEN
BEGIN
IF B <> U THEN Temp := Temp + MaskCh
ELSE Temp := '';
END
ELSE
BEGIN
IF B <> U THEN Temp := Temp + NewString[U]
ELSE Temp := '';
END;
GotoXY(XPos+B-1,YPos);
IF MaskInput THEN Write(MaskCh)
ELSE Write(Ch);
Write(Temp);
GotoXY(XPos+B,YPos);
END
ELSE
BEGIN
IF Length(NewString) < Len THEN
BEGIN
IF B >= Length(NewString) THEN Inc(A);
Inc(B);
Delete(NewString,B,1);
Insert(Ch,NewString,B);
IF MaskInput THEN Write(MaskCh)
ELSE Write(Ch);
END
ELSE IF (A = Len) AND (B < Len) THEN
BEGIN
Inc(B);
Delete(NewString,B,1);
Insert(Ch,NewString,B);
IF MaskInput THEN Write(MaskCh)
ELSE Write(Ch);
END;
END;
END;
END
ELSE Ding;
END;
FlushKBuff;
ChangeCursor(NormCursor);
END;
END.
[Back to KEYBOARD SWAG index] [Back to Main SWAG index] [Original]