Dec 082017
Formgen is a tool which lets you interactively create a data entry form for use with C software applications. It generates data-entry functions for you and automatically generates the C code needed to compile.
File FORMGENC.ZIP from The Programmer’s Corner in
Category C Source Code
Formgen is a tool which lets you interactively create a data entry form for use with C software applications. It generates data-entry functions for you and automatically generates the C code needed to compile.
File Name File Size Zip Size Zip Type
CAPTURE.COM 17969 12081 deflated
DOSTEST.C 455 266 deflated
DOSTEST.PRJ 32 30 deflated
DOTEST.C 459 262 deflated
DOTEST.PRJ 38 33 deflated
FORMGEN.C 48193 9866 deflated
FORMGEN.PRJ 21 20 deflated
IOED.C 18383 3827 deflated
IOED.H 331 148 deflated
IOLIB.C 18211 4329 deflated
IOLIB.H 2399 765 deflated
READ.ME 26245 8432 deflated
STEST.C 3372 900 deflated
STEST.FRM 1307 460 deflated
TEST.C 3531 866 deflated
TEST.FRM 1306 366 deflated

Download File FORMGENC.ZIP Here

Contents of the READ.ME file

Formgen -- a C language form generator


Formgen is a tool which lets you interactively create a data entry form
for use with C software applications. It generates three C functions for
you automatically:

(1) a display-the-form function
(2) a fill-the-form function
(3) an edit-the-form function (for data entry)

You may then incorporate these functions into your own programs, edit
them, chain them, add special features, etc..

To help convert "old" screens to C, a simple screen capture program has
been included ( This is a pop-up utility (written in
Pascal--source available) which allows you to run another program and
"capture" its screens to a text file. You can then edit the text file and
isolate the individual screens. If you feed Formgen a text file
containing a captured screen (limit: 20 lines), it will accept that as its
working form and allow you to add fields, etc.. (saving time and effort!)

Note that Formgen's work files are simple ASCII text files, which permits
you to edit them yourself (or feed Formgen a captured screen, as described
above). Beware, however-- if you edit a form which contains field
information, you must not disturb the line sequence. The first 20 lines,
for example, represent the text of the form itself. This is followed by
color, parameter, and field variable information. Take a look at the
"saveform" function in Formgen for a rundown of the actual sequence the
data file must adhere to. Position is important!


Formgen and its associated support files (iolib and ioed) have been
contributed to the PUBLIC DOMAIN by their author (John Queern -- that's
me). You may use them for whatever you like. But please don't sell them
to others, since they're free. This is also an excuse for not doing a
better job documenting the programs. Oh, well. Figuring out what you can
get away with is half the fun, right?

Files Included

The archive or diskette which you have received should contain the
following files:

CAPTURE.COM - the screen capture utility

DOSTEST.C - a "short" demo screen (uses iolib, but not ioed)

DOTEST.C - a slightly longer demo screen (same as STEST, but
DOTEST.PRJ adds an ioed edit box--which costs another 9K);
illustrates one example of each standard data type (char,
int, float, string, and ed)

FORMGEN.C - formgen source (also uses iolib and ioed)

IOED.C - ioed source (the "editor-in-a-box" add-on to iolib)

IOLIB.C - iolib source (the "get" functions, buffered screen
IOLIB.H routines, etc. -- more later...)

STEST.C - STEST screen generated by Formgen
STEST.FRM - STEST Formgen work file (try "formgen stest" to play
with it yourself)

TEST.C - TEST screen code generated by Formgen
TEST.FRM - TEST Formgen work file

Compiling Formgen

To compile Formgen, use the Turbo C project file included. This will
cause iolib and ioed to be linked into the Formgen executable. If you
wish to use another C compiler (no guarantees...) just be sure to link
with iolib and ioed, since they are required by Formgen. This version of
Formgen is rather PC-specific (for performance reasons), but could be
fairly easily modified (or watered down?) for other systems.

Support File Assumptions

The functions which Formgen creates assume the use of iolib.obj for simple
data entry routines and screen buffering, and ioed.obj for the
"editor-in-a-box" (if used). It should be relatively easy to change the
program to use your choice of libraries (if you don't like mine). The
public domain distribution file includes source for all three modules
(formgen, iolib and ioed) so that you can customize them as you wish.
TEST and STEST illustrate simple forms, and DOTEST/DOSTEST illustrate
simple programs which use the forms.

Full Screen Editor

Formgen's built-in editor lets you compose your form by moving the cursor
around the screen using PC cursor keys and WordStar-like commands (this
is actually the "editor-in-a-box", which is included in the "ioed"
module, and which you can include as a data field on your own forms):

F1 - show this help screen
Home - goto line 1, column 1
^e PgUp, ^r - goto top
PgDn, ^c - goto bottom
^ End, ^w - save changes, exit
| Ins, ^v - toggle insert mode
| Del, ^g - delete one character
^s <----o----> ^d Tab, ^i - goto next tab position
| ^y - delete line
| ^z - blank everything
v ^t - delete word right
^a/^f - advance word left/right
^x ^qs/^qd - goto beginning/end of line
^n - insert line
Cursor Movement ^b/^u, F7/F8 - generate/erase a box
(or use cursor keys) F6 - change box character set
F9/F10 - horiz/vert line draw/erase
Note: ^ = hold Ctrl

Function Keys

Function keys F1 through F10 also perform specific tasks, as outlined at
the bottom of your entry screen:

F1 F2 F3 F4 F5 F6 F7 F8 F9 F10
===== ===== ====== ====== ====== ===== ===== ===== ===== =====
Help | Field| Color | Parms | DONE | SelBx | MkBox | ClrBx | HLine | VLin

F1 - will display the editor help screen (shown above)

F2 - will (a) create a data field at the current cursor position, or
(b) edit the data field that's already at that position

You will be presented with a pop-up form (created by Formgen,
incidentally) to fill in the field specifics:

Variable Name: customer_name
Field Width: 30 Decimals:
Data Type: s
Display Command: gotoxy(#X,#Y); cprintf(\"%-#Ws\",#N);
Entry Command(*): rcode = getstring(#X,#Y,&col,#N,#W);

(*) leave blank if no entry allowed
Special Sequences: #X, #Y -- insert screen row, column
#N -- insert variable name
#W, #D -- insert width, decimals

Standard data types included are:

c - char
i - int
f - float
s - string
ed - edit buffer (the editor-in-a-box)

You can add your own standard data types in Formgen, or simply enter
them as you create your forms. If a data type is standard (or
already used on this form), Formgen will automatically fill in the
Display and Entry command templates for you. Otherwise, you'll have
to enter them yourself (more later..)

F3 - will bring up a "color selection" form. Formgen's color capabilities
are somewhat primitive (in an effort to make more compact screens).
You may choose a background color (or NOCLEAR, indicating that this
form should "pop up" over the existing screen as an additional
"window"), a form color (assuming you have a box around your form--
otherwise, this may not look good), and color combos for fill and
edit (normally the same). The color selection form looks like this
(and was also created using a (previous) version of Formgen):

SCREEN (for initial screen clear, or NOCLEAR to avoid clearing)
Foreground: NOCLEAR Background:

Foreground: WHITE Background: BLUE

Foreground: BLUE Background: LIGHTGRAY

Foreground: Background: LIGHTGRAY
NOTE: use CAPITAL LETTERS for color names

You can use any of the color names which are declared in Borland's
conio.h header file. Notice that all color names are upper case
(since they represent constant definitions). Also: don't try to use
"light" colors for the background, since that will cause blinking.

F4 - will bring up a "parameter" form. This is where you specify the
names of the three C functions which will be generated, and their
header information. You will also specify the video buffer number
to use (0..9), in case you want to reserve a specific buffer for
this screen so that you can avoid rewriting it over and over (talk
about fast-- once the screen is loaded, just use restorescreen(n),
and in a split second it'll be there...)

(omit parameter list for Display fncn, (void) will be assumed)
Display: displayme
Fill: fillme(struct MYREC *m)
Edit: editme(struct MYREC *m)

Screen Buffer to use:
(0-9) 0

EXTRA LINES (added to top and/or bottom of fill and edit functions)

EXTRA LINES (added to the end of the display function)

F5 - DONE. (You may also use End or ctrl-W for this). Formgen will ask
you whether you wish to generate code now (with options to send the
output to the Screen, Printer or File), allow you to resume editing
if you wish, or quit and save your workfile.

F6 - Select Box Type. This lets you choose which set of box characters
to use when drawing boxes and lines. You can mix different kinds
of boxes if you like. Your box selection will remain current for
this session only--or until you change it by pressing F6 again:

Box Character Selection:

a. single
b. double
c. sing/doub
d. doub/sing +---+
e. ascii |
f. half1 +
g. half2
h. half3
i. solid

Selection (a-i)?

F7 - Make box. (Ctrl-B can also be used) This command will draw boxes
for you, using the box char set selected via F6 (which defaults to
single line boxes). To draw a box, move the cursor to the upper

left hand corner position and press F7. An "" flag should
appear on the status line (toward the bottom of the screen). Now
move the cursor to the lower right hand corner position and press
F7 again. Formgen should draw a box using the corners you have
specified. Note that this is a "dumb" box, and will not worry
about making pretty intersections with other lines or boxes.

F8 - Clear box. (Ctrl-U can also be used). Use this when you don't like
the box produced above. Once again, move the cursor to the upper
left hand corner and press F8 (or ctrl-U). Now move the cursor to
the lower right hand corner and press F8 again. The box will be
replaced with blanks so that you can try again.

F9 - Horizontal line. I borrowed this idea from an old public domain
CP/M dBase utility called Zip (remember that?) Move your cursor
to the leftmost position of a horizontal line which you'd like to
draw, and press F9. Formgen will draw a line, and (hopefully) make
the appropriate intersections with existing boxes and lines. Want
to cut the line short? Position the cursor to the leftmost position
that you want to clear, and press F9 again. Formgen should erase
everything from this position to the right, and fix up any
connections needed.

F10 - Vertical line. This works like F9, but does a vertical line. Move
the cursor to the top of a desired line and press F10. To clip the
line off at some point, move the cursor to the first position to be
removed and press F10 again.

Experiment with F7-F10 a bit, and you'll quickly learn how to
create complex box forms (anything like complex life forms?) to
your liking. You may also find some combinations that don't work
right. If so, drop me a line (try CompuServe 70120,107 or call my
humble local BBS at 618-277-1162), and I'll try to fix 'em.

More About Data Fields

Data entry "field" types have been generalized so that you can add new
field types easily. A data field description structure is used to describe
each "standard" data format and provide default "get" and "say" command
templates for the display and edit screens:

struct FIELDTYPE {
char descr[20]; e.g., "i" for integer
char *saycommand; default display command template
char *getcommand; default edit command template

Special codes which may be used in "say" and "get" command templates:

#X, #Y - insert screen coordinates here
#N - insert variable name here
#W - insert width here
#D - insert decimals here

Note: X and Y are integer values which are automatically generated for
you based on screen position. The rest are all strings, and may actually
be used for anything useful. For example, our "ed" field type (the
editor-in-a-box) uses #D to represent the number of lines in the edit

Sample "standard" data types with their default "say" and "get"

"c", "gotoxy(#X,#Y); cprintf(\"%c\",#N);", /* char */
"rcode = getachar(#X,#Y,&#N);",

"s", "gotoxy(#X,#Y); cprintf(\"%-#Ws\",#N);", /* string */
"rcode = getstring(#X,#Y,&col,#N,#W);",

"i", "gotoxy(#X,#Y); cprintf(\"%#Wd\",#N);", /* integer */
"rcode = getint(#X,#Y,&#N,#W);",

"f", "gotoxy(#X,#Y); cprintf(\"%#W.#Dd\",#N);", /* float */
"rcode = getfloat(#X,#Y,&#N,#W,#D);",

"ed", "redraw((char *)#N,#X,#Y,#W,#D);", /* box editor */

When you create an actual entry field on a screen, formgen keeps track of
it in a VARTYPE record (which you will fill in when you create the

struct VARTYPE {
char type[21]; data type (may match FIELDTYPE entry)
char name[31]; name of this one
char width[7]; width of field
char decimals[7]; decimals (or lines, if "ed")
char saycomm[46]; actual say command for this var
char getcomm[46]; actual get command for this var
int x,y; position on screen (where token placed)
int flagnum; flag number on screen

The presence of a data entry field is marked on the form using a graphic
icon which signifies the anchor point for the entry field (normally, the
left side or upper left hand corner), followed by the field table index
value for the entry. The field table is kept updated to reflect current
screen positions.

APPENDIX: Functions included in iolib and ioed:

iolib.c -- library of i/o functions for use from Turbo C

char *strdel(char st[],int start,int count);
Deletes characters beginning at position in st.

int nonblank (char *st);
Returns TRUE if st is not empty or blank, FALSE otherwise.

void stub(void);
Makes a sound (warble) to indicate error or missing function (stub).

void binit(int buff);
Initializes video buffers 0-buff. Buff identifies how many buffers to
allocate (maximum currently 10). This will be called automatically by
the other iolib functions if needed.

void savescreen(int i);
Copy the current (actual) screen contents to buffer i. Each screen is
saved as a 4000-character block consisting of attribute bytes and
character information in the same format as they appear on the physical
(CGA) screen.

void restorescreen(int i);
Copy the contents of buffer i to the physical screen. If you have saved
a previous screen, this will restore it. Or if you have built a form
in buffer i (using Formgen-generated code), this will display it

void copyscreen(int i,int j);
Copy a screen image from buffer i to buffer j.

void bclear(int b);
Clear buffer b in preparation for a sequence of bwrite statements. This
will set all of the attribute bytes to the current bfore and bback
(foreground and background) colors, and blank all of the character

void bwrite(int b,int x,int y,char st[]);
Write string st[] to buffer b, starting at position (x,y).

void border(int color);
Set CGA border color (this is a holdover from the old days).

void pad(char st[],int len);
Pad string st with blanks until its length matches . This is used
to expand entry fields to their full width before displaying them on
the form.

void trim(char st[]);
Trim trailing blanks (and \n's) off of string st. This is the inverse
of pad. It's also useful when reading string information using fgets.

void lcase(char st[]);
Convert all characters in string st to lower case.

int getstring(int x,int y,int *c,char st[],int len);
This is the generic "get a string" function, which includes internal
WordStar-like line editing commands, etc.. Positions the cursor in
a field which begins at coordinates (x,y) on the screen, but in column
c. If c=0, the cursor will be positioned at the beginning of the field.
Getstring updates the value of c so that the calling program knows what
column the user was in when exiting (this allows ioed to build a
full-screen editor around calls to getstring). String st[] is the
buffer which contains any initial value--and in which to return any
changes. len defines the allowable width of the entry field.

int getint(int x,int y,int *i,int w);
Integer entry routine. Calls getstring, but converts the result to an
integer. The entry field should begin at coordinates (x,y), the initial
value should be in *i (which will also receive the returned value), and
the field width should be in w.

int getachar(int x,int y,char *ch);
This routine gets a single character.

int getfloat(int x,int y,float *f,int w,int d);
This routine gets a float using a format of %w.df

/* iolib public definitions and declarations */

#define TRUE 1
#define FALSE 0

typedef unsigned char vscreen[4000];
typedef vscreen *vptr;

extern vptr sbuff[10]; /* screen buffers */
extern char monochrome; /* mono/cga flag */
extern char insert; /* insert/overwrite mode flag */
extern int insertx,inserty; /* location of insert/overwrite message */
extern int colx,coly; /* location of column info, if present */
extern int trimblanks; /* make true for getstring to trim blanks */
extern int colons; /* make true for getstring to use colons */
extern int nobeep; /* make true to suppress end-field beep */
extern int bfore,bback; /* buffer foreground, background colors */

Return Values

The following return values are used by each of the "get" routines,
and (to some extent) by edit(). They are based on the keystroke which the
user employed to exit the get function:

0: CR, original entry changed
1: CR, original entry unchanged
2: Esc
3: up arrow, ctrl-e
4: left arrow, ctrl-s
5: right arrow, ctrl-d
6: down arrow, ctrl-x
7: ctrl-w
8: End
9: PgUp, ctrl-r
10: PgDn, ctrl-c
11-20: F1..F10
21: ctrl-y
22: ctrl-z
23: ctrl-n
24: Home
25: ctrl-b
26: ctrl-u

ioed.c -- the "editor in a box" addition to iolib

void do_help (void);

This routine displays the help screen illustrated above.

void redraw (char *edscreen,int sx,int sy, int wid, int lines);

This routine redraws the edit buffer--or displays it initially.
edscreen should be a pointer to your buffer, (sx,sy) are the screen
coordinates of the upper left hand corner of the edit box, wid is the
width of the box, and lines is the number of lines in the box.
Be sure your buffer contains at least (wid+1)*lines bytes.

int edit (char *edscreen,int sx,int sy, int *px, int *py, int wid,
int lines);

This is the editor-in-a-box. Parameters are the same as redraw,
except for the addition of px and py, which identify the current
relative position (x,y) within the edit box. These values are updated
and returned to the calling program, allowing you to process special
keys outside of edit(), then return to the same position to continue
editing. Formgen uses this capability in main().


That's about it. At least enough to get you started. If you have any
neat ideas for improving this tool, let me know. And if you enhance it
yourself, please keep it in the public domain.

Interested in other free tools? I am. Let's exchange info. I'm working
on a template-driven code generator and a Jackson-style front end as
part of another project (we have a working version, but are trying to
make it better). Your ideas are welcome!

John Queern, Belleville IL
CIS 70120,107
BBS: 618-277-1162

 December 8, 2017  Add comments

Leave a Reply