DOSCREENDOCDOSCREENPASmSAMPLE PASŠSAMPLE SCR ˙ ˙ ˙ ------------------DOSCREEN.PAS------------------------ by Steve Cohen 2/11/85 DOSCREEN.PAS is a turbo-pascal program that does the most primitive part of screen generation. It produces two output files 1> a .PAS file which contains two procedures that will be a big part of Full-Screen IO programs. Their syntax and names match those of Borland's B-TREE.Pas sample program that was distributed with Turbo-Toolbox. These procedures are: -- OutForm: Prints the prompts that will appear on the screen in their proper locations. -- ClearForm: Erases anything written in the entry fields, but leaves the prompts intact. This may seem trivial, but the co-ordinates of the gotoxy statements contained here will be the coordinates to start whateve input routines you write. -- Also included in this .pas file is a "main program" which will compile under Turbo, and serve as a test of the outform procedure. You'll almost certainly want to throw the "main program" away once you've incorporated the routines into your program. 2> A .SCR file which contains the screen in the same format as DOSCREEN stores it in memory which makes it accessible for further editing. it too can be thrown away when no longer needed. DOSCREEN Editing Commands - Basically follow Wordstar except: Fixed 8 space tabs only. Going beyond the a border of the screen takes you to the other side. i.e. Exceeding the right margin takes you to the left side of the next line; Exceeding the bottom margin takes you to the top and vice versa. There may be one or two other exceptions. You can have fun expanding or changing these. SYNTAX: Field tags can contain any character except '_'. They may contain up to two consecutive spaces. Changing the procedure FormStrings can change any of this. Field Data Entry Blanks should contain only '_' characters -- even if you intend to use others as in date fields. (e.g. __/__/__ should be handled in Doscreen as ________ When you write you input routines you can change them). The only purpose of these '_' as far as DOSCREEN is concerned is to count the number of spaces to blank out. ----------------------------------------------------------------- GETTING STARTED: You may get a 'whiff' of this program's capabilities by doing the following: 1> RUN the file SAMPLE.PAS 2> Compile Doscreen.pas under turbo to a .COM file. 3> RUN Doscreen: Immediately press Ctrl-F. This will bring up the sample screen for editing. It should look Identical to the one you just saw when you ran sample, except for the lines of '-' at the top and bottom of the screen. 4> Now edit the screen however you like, saving it to whatever file you like. If you call it 'SAMPLE', however, the original sample will be lost. ________________________________________________________________ As you can see, this program may serve as one building block in a DataBase type program using the Turbo ToolBox. That was my intention. I'd like to see any questions or improvements anyone wants to make in it. Send them to Steve Cohen 3655 N. Hermitage Chicago, IL 60613 PROGRAM DOSCREEN; {Version 2.0 by Steve Cohen 2/13/85} {Released to Public Domain } {To be compiled under Turbo-Pascal } {I USED THE CP/M VERSION, BUT OFFHAND, I CAN'T } {SEE WHY IT SHOULDN'T WORK WITH MS-DOS AS WELL } {$C-,V-} const { Change these if you don't have a 24x80 screen or if you } { wish to change the number of usable input lines. } { Configuration below mimics the format of BTREE.PAS included} { in the Turbo-ToolBox } Top = 4; Bottom = 21; Right = 80; Left = 1; HV = #27#40; { these are the codes that generate normal } LV = #27#41; { intensity and reduced intensity characters on } { my Advent System Kaypro video add-on board. } { Omit if you can't do reduced intensity. } type XAxis =0..81; YAxis =0..25; AnyStr = String[255]; Str80 = String[80]; FullScreen = array[Top..Bottom,Left..Right] of char; DisplayField = record XBegin : XAxis; YBegin : YAxis; Contents : String[80]; END; Var Screen:FullScreen; FieldTag,FieldBlank : Array[1..50] of DisplayField; PasFile : Text; ScrFile:File of FullScreen; NoOfBlanks,NoOfTags : Integer; FileName : String[10]; FUNCTION ConstStr(c:Char;N:Integer):AnyStr; Var S: AnyStr; BEGIN S[0] := Chr(N); FillChar(s[1],N,C); ConstStr := S; END; PROCEDURE MKSCREEN (var Screen:FullScreen); VAR Ins : Boolean; X : XAxis; Y : YAxis; C,Ch,Done : Char; Buffer : str80; PROCEDURE Display(VAR Screen: Fullscreen); VAR I: XAxis; J: YAxis; BEGIN For J := Top to Bottom do BEGIN GotoXY(Left,J); For I := Left to Right do Write(Screen[J,I]); END; GotoXY(70,2); If Ins then Write(HV,'INSERT') Else Clreol; GotoXY(1,23); Clreol; Write('Type ^F to get screen from file, ^C when finished',LV); X:=Left; Y := Top; GotoXY(X,Y); END; PROCEDURE GETSCREEN (Var Screen:FullScreen); VAR FileName : String[10]; NScreen : FullScreen; ScrFile : File of Fullscreen; C: Char; BEGIN GotoXY(1,23); Clreol; Write('Name of File to get: '); Readln(FileName); FileName := FileName + '.SCR'; Assign(ScrFile,FileName); {$I-} Reset(ScrFile); If IOResult <> 0 then BEGIN GotoXY(1,23); Clreol; Write(^G,'FILE ',FILENAME,' NOT FOUND. TYPE ANY KEY TO CONTINUE.'); READ(KBD,C); END ELSE BEGIN Read(ScrFile,NScreen); If IOResult <> 0 then BEGIN GotoXY(1,23); Clreol; Write('BAD FILE. Can''t Read. Type any key to continue.'); Read(Kbd,C); END ELSE Screen := NScreen; END; Display(Screen); END; {AddChar adds characters to the screen in the non-insert mode } PROCEDURE AddChar(C:Char); BEGIN Write(C); Screen[Y,X] := C; X := Succ(X); If X > Right Then BEGIN X := Left; Y := Succ(Y); If Y > Bottom Then Y := Top; GotoXY(X,Y); END; {If} END;{AddChar} { InsChar inserts characters into the screen display in the } { insert mode. } PROCEDURE InsChar(C:Char); VAR Buffer : Str80; I : Integer; BEGIN If X < Right then BEGIN Move(Screen[Y,X],Buffer[1],Right - X); Buffer[0] := Chr(Right - X); Insert(C,Buffer,1); Move(Buffer[1],Screen[Y,X],Right - Pred(x)); I := Succ(Length(Buffer)); REPEAT I := Pred(I); If Buffer[I] = ' ' then Delete(Buffer,I,1) UNTIL (Buffer[I] <> ' ') or (I <= 1); Write(Buffer); X := Succ(X); If X > Right then BEGIN X := Left; Y := Succ(Y); If Y > Bottom then Y := Top; END; GotoXY(X,Y); END else AddChar(C); END; { MoveCursor handles those control codes which simply move the } { cursor around the screen display. } PROCEDURE MoveCursor(C:Char); BEGIN Case C of #24,#10 : Y := Succ(Y); #19,#8 : X := Pred(X); #4,#12 : X := Succ(X); #5,#11 : Y := Pred(Y); #13 : BEGIN Y := Succ(Y); X := Left; END;{13} END;{Case} If X < Left then BEGIN X := Right; Y := Pred(Y); END;{If} If X > Right then BEGIN X := Left; Y := Succ(Y); END;{If} If Y < Top then Y := Bottom; If Y > Bottom then Y := Top; GotoXY(X,Y); END;{MoveCursor} { Delchar deletes a character both from the screen and from } { its proper place in memory. } PROCEDURE Delchar; BEGIN Move(Screen[Y,X],Buffer[1],Right-Pred(X)); Buffer[0] := Chr(Right - Pred(X)); Delete(Buffer,1,1); Buffer := Buffer + ' '; Write(Buffer); Move(Buffer[1],Screen[Y,X],Length(Buffer)); GotoXY(X,Y); END; {TabOver implements an 8-character fixed tab } PROCEDURE TabOver(Var XPos: XAxis; Var YPos: YAxis); BEGIN If X <= 72 then XPos := Succ(8 * (Succ(Pred(XPos) div 8))) Else BEGIN XPos := 1; YPos := Succ(YPos); If YPos > Bottom then YPos := Top; END; GotoXY(XPos,YPos); END; BEGIN {MkScreen} Ins := True; Done := ' '; Clrscr; { the following four lines produce the bordering effect I } { chose for the screens I wish to generate. Modify or omit } { if you wish. If you do change these you may also wish to } { change the 'Top' and 'Bottom' constants declared at the } { start of this program. } GotoXY(1,1);Write(LV,ConstStr('-',79)); GotoXY(1,3);Write(ConstStr('-',79)); GotoXY(1,22);Write(ConstStr('-',79)); GotoXY(1,24);Write(ConstStr('-',79)); Ins := True; Display(Screen); REPEAT Read(Kbd,Ch); Case Ch of #32 .. #126 : If Ins then InsChar(Ch) else AddChar(Ch); ^D,^E,^H,^J, ^K,^L,^M,^S, ^X : MoveCursor(Ch); ^I : TabOver(X,Y); ^G : Delchar; #127 : BEGIN MoveCursor(^H); Delchar; END; ^N : {Code to insert a line} BEGIN Move(Screen[Y,1],Screen[Succ(Y),1], (Right-Pred(Left)) * (Bottom - Y)); FillChar(Screen[Y,1],Right - Pred(Left),' '); GotoXY(1,Bottom);DelLine; GotoXY(1,Y);InsLine; END; ^Y : {Code to delete a line} BEGIN If Y < Bottom then Move(Screen[Succ(Y),1],Screen[Y,1], (Right - Pred(Left)) * (Bottom - Y)); FillChar(Screen[Bottom,1],Right - Pred(Left),' '); DelLine; GotoXY(1,Bottom);InsLine; GotoXY(X,Y); END; ^V : BEGIN Ins := Not Ins; GotoXY(70,2); If Ins then Write('INSERT') else Clreol; GotoXY(X,Y); END; ^C : BEGIN GotoXY(1,23);Clreol; Write('Sure you want to stop now (Y/N)?'); REPEAT Read(Kbd,Done); Done := UpCase(Done); If Not (Done in ['Y','N']) then Write(^G); UNTIL (Done in ['Y','N']); GotoXY(1,23);Clreol; If Done = 'N' then GotoXY(X,Y); END; ^F : GetScreen(Screen); END;{Case} UNTIL Done = 'Y'; END; { FormStrings concatenates the various characters entered } { under Mkscreen into strings -- either strings of solid } { underscores (data entry blanks) -- or prompt strings. } PROCEDURE FormStrings(Screen:FullScreen); TYPE Action = (Skip,Tag,Blank); VAR Y : Top..Bottom; X,X1 : Left..Right; I,J : Integer; S : String[80]; Mode : Action; Spaces : Integer; { Terminate stops the string formation process when a } { string is completed, and reinitializes the process of } { formation for the next string } PROCEDURE Terminate(Var Stg : Str80); BEGIN Case Mode of Tag : BEGIN REPEAT If Stg[Length(Stg)] = ' ' then Delete(Stg,Length(Stg),1); UNTIL (Stg[Length(Stg)] <> ' ') or (Length(Stg) = 0); I := Succ(I); With FieldTag[I] do BEGIN XBegin := X1; YBegin := Y; Contents := Stg; END; END; Blank : BEGIN J := Succ(J); With FieldBlank[J] do BEGIN XBegin := X1; YBegin := Y; Contents := Stg; END; END; END; {Case} Stg := ''; X1 := X; END;{Terminate} BEGIN {Formstrings} I := 0; J := 0; For Y := Top to Bottom Do BEGIN S := ''; Spaces := 0; Mode := Skip; For X := Left to Right Do BEGIN CASE Mode Of Skip : If Screen[Y,X] <> ' ' then BEGIN If Screen[Y,X] = '_' then Mode := Blank else Mode := Tag; S := S + Screen[Y,X]; X1 := X; END; Tag : BEGIN If Screen[Y,X] = ' ' then BEGIN Spaces := Succ(Spaces); If Spaces > 2 then BEGIN Terminate(S); Mode := Skip; END else S := S + Screen[Y,X]; END else If Screen[Y,X] = '_' then BEGIN Spaces := 0; Terminate(S); S := '_'; Mode := Blank; END else BEGIN S := S + Screen[Y,X]; Spaces := 0; If Screen[Y,X] = #39 then S := S + #39; END; END; Blank: If Screen[Y,X] = '_' then S := S + '_' else BEGIN Terminate(S); If Screen[Y,X] <> ' ' then BEGIN S := S + Screen[Y,X]; Mode := Tag; END else Mode := Skip; END; END;{case} END;{For X} If Mode <> Skip then Terminate(S); END;{FOR Y} NoOfTags := I; NoOfBlanks := J; END;{FormStrings} { WriteFiles writes two files } { 1> a Turbo-Pascal source code Procedure file with type '.PAS' } { containing the following: } { 'Outform' - a procedure which will put the prompts that have } { been input onto the screen in their proper places. } { 'ClearForm' - a procedure that will clear any characters } { from the screen in the places which you have designated } { (by '_') as data-entry places. Use the ClearForm } { coordinates as the starting locations for your input } { routines. } { The 'Main Program which is simply to test Outform - once } { tested, you'll want to throw it away. } { 2> A screen File for later access by screendo with Type '.SCR'} PROCEDURE WriteFiles; Const S2 = ' '; S4 = ' '; S6 = ' '; G = 'GotoXY('; W = 'Write('''; Var I : Integer; BEGIN GotoXY(1,23);Clreol; Write('Enter File Name: '); Readln(FileName); Assign(PasFile,FileName + '.PAS'); ReWrite(PasFile); Writeln(PasFile,'PROCEDURE OutForm;'); Writeln(PasFile,'BEGIN'); For I := 1 to NoOfTags do With FieldTag[I] do BEGIN Write(PasFile,S2,G,XBegin,',',YBegin,'); '); Writeln(PasFile,W,Contents,''');'); END; Writeln(PasFile,'END;'); Writeln(PasFile); Writeln(PasFile,'PROCEDURE ClearForm;'); Writeln(PasFile,'BEGIN'); For I := 1 to NoOfBlanks do With FieldBlank[I] do BEGIN Write(PasFile,S2,G,XBegin,',',YBegin,'); '); Writeln(PasFile,W,'''',':',Length(Contents),');'); END; Writeln(PasFile,'END;'); Writeln(PasFile); Writeln(PasFile,'BEGIN'); Writeln(PasFile,S2,'ClrScr;'); Writeln(PasFile,S2,'OutForm;'); Writeln(PasFile,'END.'); Close(PasFile); Assign(ScrFile,FileName + '.SCR'); ReWrite(ScrFile); Write(ScrFile,Screen); Close(ScrFile); END; BEGIN FillChar(FileName,SizeOf(FileName),0); FillChar(Screen,SizeOf(Screen),' '); FillChar(FieldTag,SizeOf(FieldTag),0); FillChar(FieldBlank,SizeOf(FieldBlank),0); MkScreen(Screen); FormStrings(Screen); WriteFiles; END. PROCEDURE OutForm; BEGIN GotoXY(1,4); Write('SAMPLE SCREEN TO TEST Steve Cohen''s DOSCREEN Program:'); GotoXY(1,6); Write('How do you like this program so far?'); GotoXY(1,8); Write('Ain''t it great (Y/N)'); GotoXY(1,13); Write('NAME'); GotoXY(1,15); Write('DATE'); GotoXY(1,17); Write('ADDRESS'); GotoXY(1,18); Write('CITY'); GotoXY(24,18); Write('STATE'); GotoXY(33,18); Write('ZIP'); END; PROCEDURE ClearForm; BEGIN GotoXY(38,6); Write('':29); GotoXY(22,8); Write('':1); GotoXY(6,13); Write('':22); GotoXY(6,15); Write('':8); GotoXY(9,17); Write('':32); GotoXY(6,18); Write('':17); GotoXY(30,18); Write('':2); GotoXY(37,18); Write('':5); END; BEGIN ClrScr; OutForm; END.  SAMPLE SCREEN TO TEST Steve Cohen's DOSCREEN Program: How do you like this program so far? _____________________________ Ain't it great (Y/N) _ NAME ______________________ DATE ________ ADDRESS ________________________________ CITY _________________ STATE __ ZIP _____