FIELD Data Structure and Functions

The FIELD data structure is used to represent a single field on an edit screen. A field represents the following items:

 Item  Description
 Row  Row coordinate, to display field at *
 Col  Column coordinate, to display field at *
 Length  Length of input for field (maximum size) *
 Option  Options, that will be passed to GetStr for editing *
 Dest  Pointer to data storage for the field *
 Label  Pointer to text describing the field

*These values will be passed of to GetStr, in the EditData routine.

This structure is to be implemented as:

typedef struct _tagFIELD {
	int Row, Col, Length, Option;
	char *Dest, *Label;

You must write the following functions, and add their prototypes, and the FIELD struct above, to your MYIO.H file. Please make note of the fact that the Row and Col parameters indicate a relative coordinate for field positioning.

void DrawLabels( FIELD *Fields, int Row, int Col, int Color);
Draws each Label from the Fields array, at the field's row and column, relative to Row and Col, in the specified Color.

void DrawData( FIELD *Fields, int FRow, int FCol, int Color);
Draws the data for a field (Dest) at it's own Row and Column, but relative to FRow and FCol. If a label is present (Label), then the data is printed position after that label. This formula can be expressed as:

int FieldRow, FieldCol;
FieldRow = FRow + Fields[x].Row;
FieldCol = FCol + Fields[x].Col;
if( Fields[x].Label != NULL )
	FieldCol += strlen(Fields[x]+1; 

int EditData( FIELD *Fields, int Row, int Col, int EditColor, int RegColor);
Note:This function may be provided for you. Unlike the other two which should be roughly only 10 lines of code, this function may be about 30 lines or so.
This function enters a loop, calling the GetStr function for each field. Pressing TAB or SHIFT-TAB will move you from field to field. Row and Col represent a relative coordinate for cursor positioning. The EditColor and RegColor parameters are passed off to GetStr.

Working with an Array of FIELDs
One of the primary uses of the FIELD structure is to implement a method to iterate through fields like an array, when they are really part of a struct. In order to do this, we will setup a struct that represents a single record (your program will only have one PERSON struct in memory at a time. Then, we will setup an array of FIELD structures, and each Dest item will point to a specific data member of the PERSON struct.

The array of FIELD structures will be terminated with a sentinel structure that has NULL in both it's Label and Dest members. For example:

typedef struct _tagPERSON
	char First[21];
	char Last[21];
	char Age[3];

PERSON Person;

FIELD FieldList [] = {
  { 1, 1, sizeof( Person.First )-1, 0, Person.First, "First name:" },
  { 1, 35, sizeof( Person.Last )-1, 0, Person.Last, "Last name:" },
  { 2, 1, sizeof( Person.Age )-1, 0, Person.Age, "Age:" },
  { -1, -1, -1, 0, NULL, NULL}

· sizeof a data member is used for the Length member
· 0 is used for the options. This may change
· The Dest member is set with the name of an array (a pointer)
· The Label is a constant string
· All 'fields', including Age, are strings

With the above code, you can iterate through the FieldList array, like:

strcpy( Person.First, "Toni" );
strcpy( Person.Last, "Braxton" );
strcpy( Person.Age, "25" );

int Loop;
for( Loop=0; FieldList[ Loop ].Dest!=NULL || FieldList[ Loop].Label!=NULL; Loop++ )
	printf( "%s: %s\n", 
		FieldList[Loop].Label ? FieldList[Loop].Label : "", 
		FieldList[Loop].Dest ? FieldList[Loop].Destl : "" );

The example code above, would output:

First name: Toni
Last name: Braxton
Age: 25

Since the FIELDS structure contains pointers into the Person structure, if you were to place new values into the Person structure (from the keyboard, or reading the struct from a file), then calling the above code would print that new person just loaded.