home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 19
/
CD_ASCQ_19_010295.iso
/
dos
/
prg
/
c
/
cwl30
/
cwl3docs
/
form.doc
next >
Wrap
Text File
|
1994-10-15
|
227KB
|
6,212 lines
THE C WINDOW LIBRARY - DATA FORMS
(c) Copyright P. A. McKenzie 1990, 1991, 1992, 1993
All Rights Reserved
Version 1.5
T A B L E O F C O N T E N T S
INPUT FORMS.................................................. 1
Form Manager ........................................ 1
INITIALIZING THE FORM LIBRARY ............................... 2
FormInitializeSystem() .............................. 2
FormInitializeFloat() ............................... 2
CREATING FIELD ENTRIES IN A FORM ............................ 3
The FIELD_ENTRY structure ................................... 3
Field Types ......................................... 4
Field Row and Column ................................ 5
Field Mask .......................................... 6
Field Fill Character ................................ 6
Field Minimum Characters............................. 6
Field Maximum Width ................................. 6
Field Options ....................................... 6
Field Starting Input Position ....................... 9
Field Attributes .................................... 9
Field Regular Expression ............................ 9
Alternate Methods of Creating FIELD_ENTRY's ......... 10
FormInitialize() ............................................ 13
Form Options ........................................ 13
Field Errors ........................................ 16
Setting Number of Decimal Places in a field with
FormSetFieldDecimal() ....................................... 16
SPECIAL DATA TYPES .......................................... 19
The CWL_LIST special field .......................... 19
Retrieving the list selection .................. 21
The CWL_TOGGLE special field ........................ 21
Retrieving the toggle selection ................ 23
The CWL_SUBFORM and CWL_VSUBFORM special fields ..... 23
CWL_BUTTON fields ................................... 25
CWL_RADIO Fields and the RADIO_ENTRY structure ...... 30
Deactivating and Activating Radio Entries....... 32
Retrieving the Radio selection ................. 33
CWL_CHECKBOX Fields and the CHECKBOX_ENTRY structure. 34
Deactivating and Activating Checkbox Entries ... 37
Retrieving the checkbox selection .............. 38
GETTING INPUT FROM A FORM ................................... 40
FormGetInput() ...................................... 41
Virtual Form Scrolling .............................. 42
Editing Input ....................................... 42
Changing the Editing Key definitions globally using the
CWLform_edit_key table .............................. 45
Page i The C Window Library Page i
T A B L E O F C O N T E N T S
Changing the Editing Key definitions using
FormAssignFieldKeys() ............................... 45
Traversing fields and the FORM_HIGHLIGHT option .... 47
ASSIGNING VALUES TO AND RETRIEVING VALUES FROM A FORM ....... 48
FormSetFieldVariable() .............................. 48
Placing input with FormPutFieldData() ............... 49
Retrieving Input with FormGetFieldData() ............ 50
Pre-filling a form with default data ................ 51
Setting up array of strings using Allocate2DArray() . 51
Freeing a two dimensional array using Free2DArray() . 53
Using FormInitializeFieldData() ..................... 53
SETTING FIELD OPTIONS ....................................... 56
FormSetFieldOptions() ............................... 56
SETTING FORM OPTIONS ........................................ 58
FormSetOptions() .................................... 58
WRITING VALUES TO THE FIELD BUFFER .......................... 60
FormWriteFieldValue() ............................... 60
SETTING FIELD PRE-FUNCTIONS ................................. 61
Defining global pre-functions ....................... 61
Defining field specific pre-functions ............... 61
Return Values To The Form manager ................... 62
SETTING FIELD POST-FUNCTIONS ................................ 66
Defining global post-functions ...................... 66
Defining field specific post-functions .............. 66
Return Values To The Form manager ................... 66
UNDEFINED KEYSTROKE PROCESSING .............................. 69
CWLform_undef_fkey_func and CWLform_undef_akey_func
function pointers ................................ 69
Specifying when to call an undefined key function is a
Regular Expression ............................... 70
Return Values To The Form Manager ................... 70
PROCESSING EDITING ERRORS ................................... 73
Minimum Number of Characters Checking ............... 73
Overriding Error Checking for Minimum Number
of Characters ..................................... 73
Checking if Field Characters Match Regular Expression 74
Calling a User Written Function when errors occur ... 75
Return Values for User Written Function ............. 75
Page ii The C Window Library Page ii
T A B L E O F C O N T E N T S
USER DEFINED ERROR CHECKING ................................. 78
FormSetFieldValidateFunction() ...................... 78
Return Values for the user defined error function ... 78
FormCheckFieldRange() ............................... 80
CLEARING A FORM ............................................. 83
FormClear() ......................................... 83
EXITING A FORM .............................................. 84
FormSetExitFunction() ............................... 84
DISPOSING OF A FORM ......................................... 88
FormClose() ......................................... 88
USING A MOUSE ............................................... 89
MISCELLANEOUS FORM FUNCTIONS ................................ 89
FormGetFieldString() ................................ 89
FormGetFieldRowCol() ................................ 89
FORM MACROS ................................................. 90
INDEX ....................................................... 97
Page iii The C Window Library Page iii
INPUT FORMS
-----------
A data entry form can be defined as a collection of input fields
that are combined in a window. By using data entry forms, it
makes it easier to collect input. Without data entry forms, the
only way to get input is to call a series of WindowGet...()
functions. Although this is possible, it can be very cumbersome
to manage these fields if they are not in some way logically
tied together, even though each field is independent of each
other. For example, if you want to advance to the next field by
using the down arrow key on the keyboard, you would have to set
up an undefined keystroke function that tests for the down
arrow, and then tell the input manager to terminate the input.
You would then tell your program to advance to the next field
and start the input process over again for the new field.
By using forms, The C Data Forms library makes it much easier
for the programmer to set up a data entry form, without worrying
about the details of traversing from field to field, as the
above example has detailed.
The forms in The C Window Library also allow other options.
Here are a few of them:
* You can have simple windowed forms or have forms that are
larger than the physical screen (virtual forms).
* You have pre and post functions on the field level as well as
the global level (pre-post function is called for all
fields).
* Fields can have a user defined error function tied to them.
* Fields can be highlighted as the input cursor is moved from
field to field, or can remain the same color regardless of
where the input cursor is.
* Automatic conversion of a field to the right data type, and
then the converted value can be assigned to any variable you
choose.
* Choice lists, toggle fields, subforms, radio, button, and
checkbox fields are supported.
* You can retrieve or update a field at any time, even when the
form is not the current input form.
The above are just some of the features of The C Data Forms
Library's form functions.
Form Manager
------------
The form manager is the set of functions internal in The C Data
Forms Library that handle the grunt work of processing a form.
Page 1 The C Window Library Page 1
INITIALIZING THE FORM LIBRARY
-----------------------------
This section defines the preliminaries when setting up your
program to handle forms.
FormInitializeSystem()
----------------------
Before you call any form functions, you must call the
FormInitializeSystem() function. This function sets up global
variables used by the form manager. If this function is not
called, the form manager may act unpredictably, leading to
undesired effects. Here is the prototype:
void FormInitializeSystem(void)
There are no arguments or a return value. This function MUST be
called after WindowInitializeSystem() to take effect.
#include "cwlwin.h" /* This include is needed for form
functions */
main()
{
WindowInitializeSystem();
FormInitializeSystem(); /* Note how FormInitializeSystem() is
called after
WindowInitializeSystem() */
}
FormInitializeFloat()
---------------------
If you are using any floating point values in your form i.e.
double and float data types, you must call the
FormInitializeFloat() function after you call
FormInitializeSystem(). This function allows the floating point
library to be loaded into your program when the program is
linked. The C Window Library will not use any floating point
functions unless FormInitializeFloat() is called. Here is the
prototype and a small example:
Prototype:
void FormInitializeFloat(void);
Example:
#include "cwlwin.h"
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat(); /* Now C Data Forms knows to use
floating point routines */
}
Page 2 The C Window Library Page 2
CREATING FIELD ENTRIES IN A FORM
--------------------------------
The FIELD_ENTRY structure
-------------------------
The most important thing to learn when creating a form is how to
set up the array of FIELD_ENTRY's. These FIELD_ENTRY's define
each field of the form, the field size, location, options,
regular expression, mask, minimum visible width of the field
(this allows left and right scrolling of long fields).
Here is the description of a FIELD_ENTRY structure:
int type -- This defines the fields data type (integer,
double, etc.)
unsigned row -- This defines the row in the window (or
virtual window) of where the field is
located.
unsigned col -- This defines the column in the window (or
virtual window) of where the field is
located.
char *mask -- This is the input mask to use for the field.
This mask is the same as the masks defined in
the WindowGet...() family of functions.
int fillchar -- This is the character to use for unfilled
input positions in the field.
int minchars -- This is the minimum number of characters to
accept in a field.
int maxwidth -- This is the visible width of the field. If
the input goes beyond the right edge of the
visible width of the field, the input is
scrolled.
unsigned long options -- These are the field options described
for the field.
int startpos -- This is the starting position in the field
to place the input cursor. Usually this is
position 1.
int attr -- Color attribute to use for the field.
char *regexp -- Regular expression used for the input field.
An array of these FIELD_ENTRY's is needed to build the form.
The order of the array elements determine the order of
processing for each field. Here is a simple way of creating an
array of FIELD_ENTRY's:
Page 3 The C Window Library Page 3
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
FIELD_ENTRY field_array[] =
/* define first field entry */
{CWL_INTEGER, /* field type */
0, /* field row in window (or virtual window) */
20, /* field column in window (or virtual window) */
"___", /* field mask */
'_', /* fill character to use */
1, /* minimum characters to accept */
3, /* maximum field width */
FIELD_RJUSTIFY, /* field option to use */
0, /* starting position */
NORM, /* field attribute */
"3[0-9]", /* regular expression to use */
/* Now define other field entries */
CWL_STRING, 1, 19, "__________", '_', 0, 10,
NO_FIELD_OPTIONS,0,NORM, "10.",
CWL_INTEGER,2, 19, "__", '_', 2, 2, NO_FIELD_OPTIONS, 0,NORM,
"2[0-9]",
CWL_DOUBLE,3, 19, "_______",'_',1,7,
FIELD_COMMA | FIELD_LJUSTIFY,0, NORM,"7[0-9/.]",
CWL_CHAR, 4, 19, "_", '_', 1, 1, FIELD_UPPERCASE, 0,
NORM, "[YyNn]",
/* Now terminate the field array */
FIELDEND};
The above example creates an array of FIELD_ENTRY's called
field_array. There are five field entries in the field_array
array. Note that the array is terminated with a FIELDEND field
type. The above method of initializing an array of
FIELD_ENTRY's globally is just one way to create the array of
FIELD_ENTRY's. There are other ways of creating an array of
FIELD_ENTRY's by making use of function calls. These methods
will be discussed later.
Field Types
-----------
The first member in the first entry is the constant CWL_INTEGER.
This denotes the type of the data that will be entered in this
field. This also tells the form manager what type of conversion
will be required when converting the input. When the user
enters the input, the input is in string form, so conversion is
necessary. A list of the constants used here and their
definitions is as follows:
Page 4 The C Window Library Page 4
Integer data types:
C language
Constant data type
-------- ----------
CWL_INTEGER int
CWL_UINTEGER unsigned int
CWL_LINTEGER long
CWL_ULINTEGER unsigned long
CWL_CHAR char
String data types:
C language
Constant data type
-------- ------------
CWL_STRING char array[]
Floating point data types:
C language
Constant data type
-------- ----------
CWL_DOUBLE double
CWL_FLOAT float
Special data type:
Constant
--------
FIELDEND
CWL_LIST
CWL_SUBFORM
CWL_VSUBFORM
CWL_TOGGLE
CWL_RADIO
CWL_CHECKBOX
CWL_BUTTON
The special data type FIELDEND is used to terminate the array of
fields. You MUST use this constant as the last field type, or
the form manager will not know where the last field is. The
other special data types will be discussed later in this
section.
Field Row and Column
--------------------
The second and third members of the first entry is the row and
column position number of where to place the field. Remember
that this position can either be in a window or a virtual
window.
Page 5 The C Window Library Page 5
Field Mask
----------
The fourth member is the field mask to use for the field. This
mask follows the same rules as input masks for the
WindowGetMask...() family of functions. The maximum number of
characters in a mask string is 255 characters. This includes
input and non-input positions in the mask. If you want to
increase this number, you will have to change the constant
MAXFIELDSIZE defined in cwlwin.h to whatever number you desire
plus 1 (the extra character is for the null terminator). Then
you must recompile The C Window Library using this new value.
Field Fill Character
--------------------
The fifth member is the fill character to use for empty input
positions in the field. In our example the fill character is
the underscore ('_').
Field Minimum Characters
------------------------
The sixth member is the minimum number of characters to accept
for this field. Our example says you must enter at least 1
character in the first field. You can override the field
minimum by using the FIELD_OVERRIDE_FORWARD and the
FIELD_OVERRIDE_BACKWARD field options defined below.
Field Maximum Width
-------------------
The seventh member tells us the maximum visible width of the
field. Our example shows that the visible width should be 3
characters.
Field Options
-------------
The eighth member are the field options used on the field. Here
are a list of the field options available:
FIELD_UPPERCASE - Characters entered in the field are
automatically converted to upper case if lower
case characters are entered.
FIELD_LOWERCASE - Characters entered in the field are
automatically converted to lower case if upper
case characters are entered.
Page 6 The C Window Library Page 6
FIELD_ENHANCEDKEY - Field can recognize and distinguish between
extra keys on extended keyboard (i.e. F11,
F12, dedicated cursor keys, etc.) and the
normal keys.
FIELD_CHECKREGEXP - Each character in the field will be checked
against the field's regular expression.
This check is done when the user wants to
accept the input.
FIELD_CHECKSPACES - Spaces will be counted as valid characters
when the form manager checks if the minimum
number of characters has been entered.
FIELD_AUTORETURN - The field is automatically accepted when the
last input position is filled with a
character.
FIELD_CHECKREGEXP_IGNORECASE - Same as FIELD_CHECKREGEXP except
that case is ignored for
alphabetic characters.
FIELD_FLUSHBUFFER - Keyboard is flushed before entering the
field. This will override whatever the
FLUSH_KEYBOARD() macro is set to.
FIELD_HOMECURSOR - Input field will be scrolled back to the
first character when the field is accepted.
This is good for fields that have scrolled
to the right.
FIELD_PROTECT - The input field will not be edited. It will be
skipped over by the form manager.
FIELD_COMMA - This option is only used for numeric field types
(CWL_INTEGER, CWL_UINTEGER, LONG, ULONG,
CWL_DOUBLE and CWL_FLOAT types). Commas are
placed in the input when it is accepted. While
inputting in the field, the form manager deletes
the commas. To make sure that the comma formatted
string will fit in the field, the field maximum
width should be at least as long as the comma
formatted number.
FIELD_LJUSTIFY - The input field will be left justified when it
is accepted.
FIELD_RJUSTIFY - The input field will be right justified when it
is accepted.
FIELD_ZSUPPRESS1 - This option is used only for numeric field
types. The input will suppress all leading
zeros when the field is accepted.
Page 7 The C Window Library Page 7
FIELD_ZSUPPRESS2 - This option does the same as FIELD_ZSUPPRESS1
except that if the string entered is all
zeros, leading zeros except for the last zero
is suppressed. For example, if the user
enters "00000" the resulting string after
suppressing will be "0".
FIELD_PASSWORD - This is a password field. When inputting into
this field, only the password character
(default is the asterisk '*') is displayed.
FIELD_CLEARFIELD - Clears the input field if the first key
pressed is recognized by the regular expression
as a valid input key. If a cursor movement
key is pressed first, the field is not
cleared if any subsequent input keys are
pressed.
FIELD_CHECK - When this option is chosen the field is checked to
make sure that the minimum number of characters
have been entered when the user wants to exit the
form.
FIELD_OVERRIDE_FORWARD - You can go to the next field (go toward
the last field) from the input field
without checking to see if the minimum
number of characters has been entered.
However, you cannot go to a previous
field (go toward the first field) if
the minimum number of characters is not
met.
FIELD_OVERRIDE_BACKWARD - Same as FIELD_OVERRIDE_FORWARD except
that you cannot go forward (toward the
last input field) without meeting the
requirements of entering the minimum
number of characters expected.
NO_FIELD_OPTIONS - The above options described are turned
off.
You can combine options with a bitwise OR (|). For example, if
you want a numeric field zero suppressed, comma formatted, and
left justified you would do the following:
FIELD_ZSUPPRESS1 | FIELD_COMMA | FIELD_LJUSTIFY
If both FIELD_ZSUPPRESS1 and FIELD_ZSUPPRESS2 are used as
options, FIELD_ZSUPPRESS1 overrides FIELD_ZSUPPRESS2.
FIELD_LJUSTIFY overrides FIELD_RJUSTIFY if both options are
chosen.
If both FIELD_OVERRIDE_FORWARD and FIELD_OVERRIDE_BACKWARD are
chosen, you can exit a field in any direction without checking
the regular expression.
NO_FIELD_OPTIONS must not be combined with any other options.
Page 8 The C Window Library Page 8
You can also turn off and turn on field options at run time and
during processing of a form by using the FormSetFieldOptions()
function defined later in the manual.
Field Starting Input Position
-----------------------------
This value tells the form manager where to place the cursor when
input is started. The position numbers range from 0 to the
highest field position in the input field, less one. Usually
the starting position for the field is 0, but you can start the
input anywhere in a field.
Field Attributes
----------------
The tenth member of the FIELD_ENTRY structure is the field
attribute. This attribute will be the color of the field
characters that are inputted. Note that in the example above,
the constants BLACK_ and WHITE_ are used instead of the usual
lower case global variables, black and white. This is done
because the lower case color variables do not have a value until
WindowInitializeSystem() is called, while the capitalized
constants have a value that is predefined. We need to use the
predefined constants because we are initializing an array
outside of the main() function.
Field Regular Expression
------------------------
The last member of the FIELD_ENTRY is the regular expression to
use. It is wise to use the proper regular expression for a
given field type. For example, use a [0-9] type regular
expression for integer data. Here are a list of sample regular
expressions to use for a given data type:
Constant Simple Reg.
Data Type Expression
--------- ----------
CWL_INTEGER or CWL_LINTEGER [0-9], [0-9/-+]
CWL_UINTEGER or CWL_ULINTEGER [0-9]
CWL_STRING Any regular expression.
CWL_CHAR Any one character regular
expression.
CWL_DOUBLE or CWL_FLOAT [0-9], [0-9/-+], [0-9/.],
[0-9/.eE]
Page 9 The C Window Library Page 9
Except for the CWL_CHAR data type, you can use multiplying
factors or complex regular expressions composed of the above
regular expressions. The regular expressions defined above are
just examples of what you should use.
The total length of the number of characters in the regular
expression must not exceed the maximum number of characters in a
field. The current maximum number of characters allowed in a
field is 255. If you want to change this, you must modify the
source code and change the constant MAXFIELDSIZE to whatever
value you choose. Of course, you would have to recompile the
source code.
Alternate Methods of Creating FIELD_ENTRY's
------------------------------------------
Another method of creating the FIELD_ENTRY's is to create them
dynamically. Here is an example:
#include "cwlwin.h"
#define NUMFIELDS 5
#define NORM CREATE_VIDEO_ATTRIBUTE(black,white)
FIELD_ENTRY_PTR field_array; /* Notice that we have a pointer
to what will be an array of
FIELD_ENTRY's */
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
/* Initialize with at least number of total fields */
field_array = FieldAllocate(NUMFIELDS);
/* Call function to create fields in field_array sequentially*/
FieldCreate(field_array, /* FIELD_ENTRY pointer */
0, /* field number */
/* The rest of the arguments are just like the first example */
CWL_INTEGER, /* field type */
0, /* field row */
19, /* field column */
"___", /* field mask */
'_', /* fill character */
1, /* minimum characters */
3, /* maximum field width */
FIELD_RJUSTIFY, /* field options */
0, /* starting position */
NORM, /* attribute */
"3[0-9]"); /* regular expression */
FieldCreate(field_array,1,CWL_STRING,1,19,"__________",'_',
0,10, NO_FIELD_OPTIONS,0,NORM,"10.");
Page 10 The C Window Library Page 10
FieldCreate(field_array,2,CWL_INTEGER,2,19,"__",'_',2,2,
NO_FIELD_OPTIONS,0,NORM,"2[0-9]");
FieldCreate(field_array,3,CWL_DOUBLE,3,19, "_______",'_',1,7,
FIELD_COMMA | FIELD_LJUSTIFY,0,NORM,"7[0-9/.]");
FieldCreate(field_array,4,CWL_CHAR,4,19,"_",'_',1,1,
FIELD_UPPERCASE,0,NORM,"[YyNn]");
/* Terminate fields with FieldEnd */
FieldEnd(field_array,NUMFIELDS);
/*
some other stuff
*/
/* Dispose of Field entries created */
FieldDeallocate(field_array);
}
The difference between the above method and the method used to
globally initialize an array are the following:
1) The variable type for field_array is FIELD_ENTRY_PTR, not
FIELD_ENTRY as the previous examples so far have illustrated.
2) You must call the FieldAllocate() function to allocate space
for the number of fields desired. If you do not call field
allocate, you will surely get a memory overwrite error. The
return value to FieldAllocate() must be assigned to a
FIELD_ENTRY_PTR, as the above example shows.
The array of fields are allocated from the heap at runtime, as
opposed to the static method which sets up the memory scheme at
link time.
3) The next thing you must do is to fill in the field
information by calling the FieldCreate() function. The first
argument to the FieldCreate() function is the FIELD_ENTRY_PTR.
The second argument is the field number to assign this
information to. The rest of the arguments are the same order as
the first example i.e. field type, row, column, mask, etc.
FieldCreate() is called for each field desired.
4) The FieldEnd() function must be called to terminate the list
of fields. The first argument is the FIELD_ENTRY_PTR, and the
second argument is the total number of fields defined.
5) After you have called FormClose() (discussed later) and no
longer need the array of fields anymore, you should call
FieldDeallocate() to free the memory assigned to the array of
fields. The only argument to FieldDeallocate() is the
FIELD_ENTRY_PTR.
Page 11 The C Window Library Page 11
All of these functions except for FieldAllocate() have no return
values. The FieldAllocate() function returns a FIELD_ENTRY_PTR
if successful, and a FIELD_ENTRY_NULL_PTR if unsuccessful.
The advantages of using the above method over the first method
is that FIELD_ENTRY's are dynamically allocated rather than
statically declared at compile time. This allows the programmer
to create loops to set up fields, read field information from a
file and assign this info to a FIELD_ENTRY, etc.
The disadvantages of this method is that you have to call
several functions to accomplish creating an array of fields,
while the static method does not call any functions. Function
overhead is saved in the static method.
Here is another method of using statically defined data and
function calls:
#include "cwlwin.h"
#define NUMFIELDS 5
#define NORM CREATE_VIDEO_ATTRIBUTE(black,white)
FIELD_ENTRY field_array[NUMFIELDS+1]; /* Notice that we have an
array of FIELD_ENTRY's. 1
is added for FIELDEND
entry */
main()
{
WindowInitializeSystem();
FormInitializeSystem();
/* Call function to create fields in field_array sequentially */
FieldCreate(field_array,0,CWL_INTEGER,0,19,"___",'_',1,3,
FIELD_RJUSTIFY,0,NORM,"3[0-9]");
FieldCreate(field_array,1,CWL_STRING,1,19,"__________",'_',
0,10,NO_FIELD_OPTIONS,0,NORM,"10.");
FieldCreate(field_array,2,CWL_INTEGER,2,19,"__",'_',2,2,
NO_FIELD_OPTIONS,0,NORM,"2[0-9]");
FieldCreate(field_array,3,CWL_DOUBLE,3,19, "_______",'_',1,7,
FIELD_COMMA | FIELD_LJUSTIFY,0,NORM,"7[0-9/.]");
FieldCreate(field_array,4,CWL_CHAR,4,19,"_",'_',1,1,
FIELD_UPPERCASE,0,NORM,"[YyNn]");
/* Terminate fields with FieldEnd */
FieldEnd(field_array,NUMFIELDS);
}
Page 12 The C Window Library Page 12
The above method declares an array of FIELD_ENTRY's, but does
not initialize them in the same way as the first method. Note
that there is no function call to FieldAllocate() or
FieldDeallocate() since the array of fields, field_array, was
already declared with 6 elements (NUMFIELDS + 1). All other
aspects of this method is the same as the second method.
This method statically declares an array but does have to
allocate any memory from the heap.
From this point on, this manual will use the first method
discussed on page 2 when code fragments are written.
FormInitialize() function
-------------------------
The next step is to take the array of FIELD_ENTRY's and assign
them to a window. The FormInitialize() does just this.
A prototype of this function is as follows:
FORMPTR FormInitialize(void *window, FIELD_ENTRY *field_entry,
int form_options)
Note that this function returns a pointer to a structure. This
pointer is called a FORMPTR. You must assign the return value
to a variable declared as a FORMPTR.
The first argument to FormInitialize() seems strange. The
reason for the void pointer instead of the usual WPOINTER or
VWPOINTER is that either WPOINTER or VWPOINTER can be used as
the first argument. As was stated before, forms can either be
window based or virtual window based.
If the first argument is a WPOINTER, the window must be
initialized and opened before calling FormInitialize(). If the
first argument is a VWPOINTER, the virtual window must be
initialized with VirtualInitialize() and must be an attributed
virtual window (VirtualInitialize() must be called with
ATTRIBUTE as the first argument).
The second argument is the array of FIELD_ENTRY's.
The third argument are the form options. A list of the form
options are as follows:
Form Option
-----------
FORM_WRAP - form manager will move the input cursor to the
first input field if the last input field is
accepted, and will move the input cursor to the
last input field if the cursor goes beyond the
first field.
Page 13 The C Window Library Page 13
FORM_CHECK - When this option is on, all fields are checked
on exit of the form to see if they satisfy the
minimum number of characters.
FORM_EXIT_INITIAL - This option allows exiting a form if an
attempt is made to move the input cursor
above the first input field in the form.
FORM_NOEXIT_LAST - When this option is on, the form is not
exited when the last field is accepted.
FORM_HIGHLIGHT - When this option is on, each field takes on its
field color only when it is being inputted.
When a field is not being inputted, the color of
the field is the text color of the window.
When this option is off, all fields take on
their color regardless if the field is currently
being inputted.
FORM_VIRTUAL - You must use this option if the first argument
to FormInitialize() is a VWPOINTER.
FORM_STATIC - The form window will not be hidden when the form
is exited.
NO_FORM_OPTIONS - All options described above are turned off.
You can combine form options using the bitwise OR (|). Form
options can be turned off or on any time using the
FormSetOptions() function defined later in the manual.
Example:
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
WPOINTER w;
VWPOINTER vw;
FORMPTR form, /* pointers to FORM's */
form2;
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,19,"___",'_',1,3,FIELD_RJUSTIFY,0,NORM,"3[0-9]",
CWL_STRING, 1, 19, "__________", '_', 0, 10,NO_FIELD_OPTIONS,
0,NORM, "10.",
CWL_INTEGER,2, 19, "__", '_', 2, 2,NO_FIELD_OPTIONS, 0,NORM,
"2[0-9]",
CWL_DOUBLE,3, 19,"_______",'_',1,7,FIELD_COMMA|FIELD_LJUSTIFY,
0,NORM,"7[0-9/.]",
CWL_CHAR, 4, 19, "_", '_', 1, 1, FIELD_UPPERCASE, 0,NORM,
"[YyNn]",
FIELDEND };
Page 14 The C Window Library Page 14
main()
{
WindowInitializeSystem();
WindowInitDesktop(0);
FormInitializeSystem();
FormInitializeFloat();
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,40,10,
NORM,NORM,SINGLEBOX);
/* vw must be ATTRIBUTEd if we want to use it as a form */
vw = VirtualInitialize(ATTRIBUTE,10,80,NORM);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
NO_FORM_OPTIONS); /* form options */
if (form == FORM_NULL_PTR)
{
printf("Form could not be initialized");
exit(0);
}
/* Initialize with VWPOINTER */
form2 = FormInitialize(vw, field_array, FORM_VIRTUAL);
{
printf("Form could not be initialized");
exit(0);
}
}
Note that when initializing with a virtual window, the option
FORM_VIRTUAL must be used as a form option.
FormInitialize() returns a valid FORMPTR if successful. If
there is an error, a FORM_NULL_PTR (null FORMPTR) is returned,
and window_error_code is set to one of the following:
NO_FIELDS_DEFINED if there are no fields in the FIELD_ENTRY
array.
NO_HEAP_MEM if there is not enough memory to allocate for the
form and any internal field buffers.
NO_INPUT_CHARS if a field mask contains no characters.
INVALID_NUM_CHARS if the number of characters denoted by a
field's regular expression does not equal the number of input
positions in the field mask.
BAD_WINDOW if the window does not exist.
WINDOW_NOT_OPEN if the window is not open for writing.
BAD_V_WINDOW if the virtual window specified does not exist.
FIELD_RANGE_ERROR if there is a field that is out of bounds of
the dimensions of the window or the virtual window.
Page 15 The C Window Library Page 15
Field Errors
------------
If there is an error with a particular field, the global
variable field_bad_number tells which field is the offending
field. Field numbers are numbered from 1 to the highest field
in the array of fields.
Here is how a complete form error checking function routine
would look like:
#include "cwlwin.h"
#include <stdio.h>
FIELD_ENTRY field_array[] = { /* ... Initialize fields ... */ }
VWPOINTER vw;
WPOINTER w;
FORMPTR form;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,40,10,
NORM,NORM,SINGLEBOX);
/* vw must be ATTRIBUTEd if we want to use it as a form */
vw = VirtualInitialize(ATTRIBUTE,10,80,NORM);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
NO_FORM_OPTIONS); /* form options */
if (form == FORM_NULL_PTR)
write_form_error(1);
/* Initialize with VWPOINTER */
form2 = FormInitialize(vw, field_array, FORM_VIRTUAL);
if (form2 == FORM_NULL_PTR)
write_form_error(2);
}
void write_form_error(int formnum)
{
switch (window_error_code)
{
case NO_FIELDS_DEFINED:
printf("Form %d has no fields",formnum);
break;
case NO_HEAP_MEM:
printf("Not enough heap memory to allocate for form %d",
formnum);
break;
Page 16 The C Window Library Page 16
case NO_INPUT_CHARS:
printf ("Field %d has an invalid mask in form %d",
field_bad_number, formnum);
break;
case TOO_MANY_CHARS:
printf("Field %d has too many input characters in form %d",
field_bad_number, formnum);
break;
case BAD_WINDOW:
printf("Window or virtual window does not exist for"
" form %d", formnum);
break;
case WINDOW_NOT_OPEN:
printf("Window not open for form %d",formnum);
break;
case BAD_V_WINDOW:
printf("Virtual window does not exist for form %d",
formnum);
break;
case FIELD_RANGE_ERROR:
printf("Field %d is out of bounds in form %d",
field_bad_number,formnum);
break;
default:
printf("Undefined error for form %d",formnum);
break;
}
exit(0);
}
The above function write_error_form() processes any error that
may occur when initializing a form.
Setting Number of Decimal Places in a field with
FormSetFieldDecimal()
---------------------
If the field type is CWL_FLOAT or CWL_DOUBLE, the form manager
should be informed of the number of decimal places in the field.
The FormSetFieldDecimal() function tells the form manager the
number of decimal places in a field. Here is the prototype:
int FormSetFieldDecimal(FORMPTR form, int entry, int numdec)
Page 17 The C Window Library Page 17
The first two arguments are the form and entry number,
respectively, and the last argument is the number of decimal
places. If the FormSetFieldDecimal() function is not called,
the form manager will assume 0 decimal places. The form manager
will round off any number that is inputted to the desired
decimal places.
If there are no errors, FormSetFieldDecimal() returns NO_ERROR.
If there are errors, FormSetFieldDecimal() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Page 18 The C Window Library Page 18
SPECIAL DATA TYPES
------------------
In the previous section, there was a very brief discussion of
the special data types, namely CWL_LIST, CWL_TOGGLE,
CWL_SUBFORM, CWL_VSUBFORM, CWL_BUTTON, CWL_RADIO, and
CWL_CHECKBOX. These special data types are very useful if the
information to be entered for a field is not a normal text
field. For example, CWL_LIST allows you to use a popup list of
choices to be displayed, CWL_TOGGLE allows you to toggle between
choices, and CWL_SUBFORM and CWL_VSUBFORM allows you to enter a
subform for a field. The CWL_BUTTON field is a no input field,
but powerful in what it can do. CWL_BUTTON fields can close
forms, go to previous fields, or can have a user defined
definition if the user 'accepts' the field. The CWL_RADIO field
implements a radio button field, and CWL_CHECKBOX implements a
check box type field. A discussion of radio and check box
fields will be discussed below.
For all of the special fields, the field type specified when the
fields on the form was initialized must match with the desired
special field for the field entry.
The CWL_LIST special field
--------------------------
If a field type is CWL_LIST, the form manager will display a
pop-up menu of choices. Once the selection is made, the string
in the pop-up menu is written to the field. The field should be
big enough to hold the longest string in the pop-up menu. Where
does the form get the pop-up menu from? You create the pop-up
menu just like any normal popup menu. If you are not familiar
with creating pop-up menus, please refer to the documentation
included with The C Window Library main documentation.
To let the form know about the pop-up menu, you must call the
FormSetListField() function. This function lets the form know
the address of the pop-up menu pointer (POPUP_MENU_PTR). Here
is the prototype:
int FormSetListField(FORMPTR form, int entry, int rank,
int start, POPUP_MENU_PTR pop)
The first argument is the pointer to the form. The second
argument is the form entry to assign the POPUP_MENU_PTR to. THe
third argument is the rank of the popup window. The fourth
argument is the starting entry to place the highlight on. Entry
numbers are numbered from 1 to the highest entry. The last
argument is the POPUP_MENU_PTR itself.
The form must be initialized with FormInitialize(), the entry
number must exist and must have been defined as a CWL_LIST
field, and the POPUP_MENU_PTR must also have been created before
calling FormSetListField(). If any of these criteria are
violated, an error is returned. Here is an example:
Page 19 The C Window Library Page 19
#include "cwlwin.h"
FIELD_ENTRY fentry[] = {CWL_LIST,8,14,"________",' ',0,8,
NO_FIELD_OPTIONS,0,REVERSE,"8.",
FIELDEND};
FORMPTR form;
POPUP_MENU_ENTRY popup_entry[] = {"Choice 1",0,0,0,NULLFN,
"Choice 2",1,0,0,NULLFN,
"Choice 3",2,0,0,NULLFN,
"Choice 4",3,0,0,NULLFN,
CWL_NULL,-1};
POPUP_MENU_PTR popup;
unsigned menu_colors[NUMPOPUPCOLORS];
WPOINTER w;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
/* set up menu colors */
menu_colors[ENTRYCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[BORDERCOLOR] =CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[HOTKEYCOLOR] =CREATE_VIDEO_ATTRIBUTE(white,blue);
menu_colors[HIGHLIGHTCOLOR]=CREATE_VIDEO_ATTRIBUTE(cyan,black);
menu_colors[UNAVAILCOLOR]=CREATE_VIDEO_ATTRIBUTE(white,black);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,1,1,78,22,NORM,
NORM,SINGLEBOX);
/* create popup menu */
popup = PopupCreateMenu(popup_entry,menu_colors,3,9,7,
NO_POPUP_OPTIONS,WNULLFN,VWNULLFN);
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT);
/* Let form know about popup menu */
FormSetListField(form,0,1,0,popup);
/* get the input */
FormGetInput(form,1,0);
}
If you take a look at the array of FIELD_ENTRY's, the first
field type is a CWL_LIST field. This informs the form manager
that the first field will have a pop-up list associated with it.
Also note that The POPUP_MENU_ENTRY's menu function is a NULLFN.
The C Window Library automatically assigns an internal function
to the pop-up menu when FormSetListField() is called, which will
supersede any function that you may have assigned to the menu
entry.
When FormSetListField() is called, the FORMPTR is assigned the
POPUP_MENU_PTR, and any menu function is overridden by the C
Data Forms function.
Page 20 The C Window Library Page 20
With a pop-up list, you can have hotkeys, secondary hotkeys,
pre-functions, mouse support, etc. just like pop-up menus. The
only limit is that the function to perform when a selection is
made is a Data Forms internal function, and not the function
that you may have assigned to it previously.
If there are no errors, FormSetListField() returns NO_ERROR.
If there are errors, FormSetListField() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to create the data
structure required for a CWL_LIST field.
Retrieving the CWL_LIST selection
---------------------------------
To inspect the choice that was selected, use the
FormGetListChoice() function. Here is the prototype:
int FormGetListChoice(FORMPTR form, int entry)
The only two arguments are the form and entry number of the
CWL_LIST field. If successful, FormGetListChoice() returns an
integer denoting the CWL_LIST entry that was selected. Entry
numbers are numbered from 0 to the highest entry in the list
less one, and are numbered in the order that was specified in
the pop-up menu.
If the CWL_LIST field is protected, FormGetListChoice() returns
0.
If there are errors, FormGetListChoice() returns one of the
following:
UNDEFINED_FORM if the form does not exist.
UNDEFINED_FIELD if the field does not exist, or the field is not
a CWL_LIST field.
The CWL_TOGGLE special field
----------------------------
The CWL_TOGGLE field allows you to make selections by pressing
the space bar (default) to cycle through selections. You can
also accomplish the same thing with a CWL_LIST field, with a
one-line borderless pop-up window. However, CWL_TOGGLE fields
are much easier to use. To let the FORMPTR know that a field is
a toggle field, the FIELD_ENTRY field type must have a
CWL_TOGGLE type, and you must call the FormSetToggleField()
function to assign the pointer to the CWL_TOGGLE list.
Page 21 The C Window Library Page 21
Here is a small example that creates a CWL_TOGGLE list:
char *toglist[] = {"ITEM1", "ITEM2", "ITEM3", TOGGLE_NULL};
In other words, the CWL_TOGGLE list is just an array of
character strings, with the last character string being the
TOGGLE_NULL constant. You MUST have the TOGGLE_NULL constant to
terminate the array of string, or else the form manager will not
know where the CWL_TOGGLE list ends. Of course this is only one
of many ways to create and initialize an array of character
strings.
The prototype to the FormSetToggleField() is as follows:
int FormSetToggleField(FORMPTR form, int entry, char **toglist)
The first argument is the pointer to the form. The second
argument is the form entry to assign the toggle array to, and
the third argument is the toggle character array. The form must
be initialized with FormInitialize(), the entry number must
exist and must have been defined as a CWL_TOGGLE field.
Here is an example:
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
FIELD_ENTRY fentry[] = {CWL_TOGGLE,0,0,"________",' ',0,8,
NO_FIELD_OPTIONS,0,REVERSE,"8.",FIELDEND};
FORMPTR form;
char *tog[] = {"Choice 1","Choice 2","Choice 3","Choice 4",
TOGGLE_NULL};
WPOINTER w;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT|FORM_STATIC);
/* Let form know about toggle field */
FormSetToggleField(form,0,tog);
/* get the input */
FormGetInput(form,1,0);
WindowMoveCursor(w,2,0);
/* get the choice */
WindowPrintf(w,"The choice that was made was %d",
FormGetToggleChoice(form,1));
}
Page 22 The C Window Library Page 22
By default, the toggle key is the space bar, but this can be
changed by changing the field key definitions. This will be
discussed later in subsequent sections.
If there are no errors, FormSetToggleField() returns NO_ERROR.
If there are errors, FormSetToggleField() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Retrieving the toggle selection
-------------------------------
To get the selection that was made in a toggle field, use the
FormGetToggleChoice() function. This function returns the
toggle entry that was selected. Entries are numbered from 0 to
the highest entry in the toggle field, less one. Here is the
prototype:
int FormGetToggleChoice(FORMPTR form, int entry)
The arguments are the form and entry number of the toggle field.
FormGetToggleChoice() returns -1 if the toggle field is a
protected field.
If there are errors, FormGetToggleChoice() returns one of the
following:
UNDEFINED_FORM if the form does not exist.
UNDEFINED_FIELD if the field does not exist, or the field is not a
CWL_TOGGLE field.
CWL_SUBFORM and CWL_VSUBFORM special fields
-------------------------------------------
You can define a field in a form as another form. When the
field that is defined as a subform is entered, the form manager
processes the subform. When the subform is completed, the form
manager returns control to the next field entry in the form that
called the subform. Subforms can contain other subforms, so
there is no theoretical limit to the nesting level for subforms.
If you have deeply nested subforms, make sure that you have
enough stack space when compiling and linking your programs.
The only difference between CWL_SUBFORM and CWL_VSUBFORM is that
CWL_VSUBFORM informs the form manager that the subform is a
virtual (scrolling) form.
Page 23 The C Window Library Page 23
The way to define a field as a CWL_SUBFORM or CWL_VSUBFORM is to
make sure the field type for the FIELD_ENTRY is CWL_SUBFORM
(CWL_VSUBFORM). Setting up a subform is EXACTLY the same way as
you would set up a regular form. THERE IS NO DIFFERENCE! Once
your subform is set up, you must call the FormSetSubformField()
for CWL_SUBFORMS, or FormSetVSubformField() for CWL_VSUBFORMS.
Here are the prototypes:
FormSetSubformField(FORMPTR form, int entry, int rank,
int start, FORMPTR subform)
FormSetVSubformField(FORMPTR form, int entry, int rank,
int start, FORMPTR vsubform, WPOINTER viewport)
The only difference between the two functions is that
FormSetVSubformField() allows you to specify the viewport that
the virtual form will be displayed on. You must supply this
argument if you want the virtual subform to work correctly.
The first argument is the form to assign the subform to. The
second argument is the entry in the form that will be a subform
field. The third argument is the rank of the subform window.
The fourth argument is the starting entry in the subform to
begin getting input. The fifth argument is the pointer to the
subform itself. The last argument in FormSetVSubformField() is
the viewport window. All of the above must exist, or an error
will be returned. Here is an example:
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
/* initialize entries for form 1 */
FIELD_ENTRY fentry[] = {CWL_INTEGER,0,0,"________",' ',0,8,
NO_FIELD_OPTIONS,0,REVERSE,"8.",
CWL_SUBFORM,0,0,"",' ',0,0,NO_FIELD_OPTIONS,
0,0,"",FIELDEND};
/* initialize entries for subform */
FIELD_ENTRY fentry2[] =
{CWL_INTEGER,0,0,"____",' ',0,4,NO_FIELD_OPTIONS,0,
REVERSE,"4.", FIELDEND};
FORMPTR form,subform;
WPOINTER w,w2;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
w2 = WindowInitialize(DESKTOP_WINDOW,BORDER,5,9,50,12,
NORM,NORM,SINGLEBOX);
Page 24 The C Window Library Page 24
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT);
subform = FormInitialize(w2,fentry2,FORM_HIGHLIGHT);
/* Let form know about subform field */
FormSetSubformField(form,1,1,0,subform);
/* get the input */
FormGetInput(form,1,0);
}
Note that a CWL_SUBFORM (CWL_VSUBFORM) FIELD_ENTRY's only
important parts are the field type, and options. The mask,
attribute, regular expression, start position, row, col, etc.
are irrelevant since the field is a whole form. This is why the
CWL_SUBFORM field entry has bogus (don't care) arguments for
these items.
If there are no errors, FormSetSubformField() and
FormSetVSubformField() return NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR or subform FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
CWL_BUTTON fields
-----------------
A button field is a field that does not accept input but does
certain actions when selected. These actions can be anything
from closing a form to doing a user-defined function. When the
button field is accepted, the action tied to the button field is
done. If the user wants to skip over the button field, he/she
would hit a previous field or next field key. These key
definitions are discussed in the GETTING INPUT FROM A FORM
section.
To inform the form manager that a field is a button field, you
must first set the field type to CWL_BUTTON. Field types are
set when defining the array of field entries. After the field
entries have been defined, the next step is to use the
FormSetButtonField() function. Here is the prototype to this
function:
int FormSetButtonField(FORMPTR form, int entry, int retval,
char *text, int *attr,
int (*button_func)(FORMPTR f, int e,
int *new_entry))
The first argument is the form to set the button field.
The second argument is the entry in the form to set as the
button field.
Page 25 The C Window Library Page 25
The third argument is the value that will be returned to the
form manager if the button field is accepted. The possible
return values and their descriptions will be discussed later.
The fourth argument is a string that is written to the form
window. This string will be placed in the (row,col) coordinates
specified when the field was defined. This string should
contain useful information to the user as to what the button
will do if it is accepted. For example, the string "Close" can
be written to the form window if accepting the button will close
the form. This string is also highlighted when the button field
is the current field. If the FORM_HIGHLIGHT option is on, the
button field is only highlighted when it is the current field.
The fifth argument is an array of attributes that will be used
for highlighting the button field if it is the active field, and
lowlighting if it is not the active field. The positions in
this array denote the following colors:
NORMATTR - This is the color of the unhighlighted button field.
HIATTR - This is the color of the highlighted button.
For instance:
int myattr[2];
/* ... */
myattr[NORMATTR] = CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_);
myattr[HIATTR] = CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_);
The last argument is a pointer to a user-defined function that
will return a value to the form manager. The possible return
values will be discussed later. The user-defined function takes
three arguments. The first argument is a pointer to the form
that called your user-defined function, and the second argument
is the entry in the form that called your user-defined function.
The third argument is a pointer to an integer that will denote a
field number to change to if the FIELD_NEWFIELD value is
returned to the form manager. The FIELD_NEWFIELD value will be
discussed below.
An advantage of using a user-defined function is that the return
value to the form manager can be dynamic. In other words, your
user-defined function controls what value is returned to the
form manager. You may have different return values that you
want to implement depending on the state of the form, what input
has been entered in previous fields, etc. This user-defined
function is not limited. You can do just about anything in this
function, including opening other forms, displaying windows,
etc.
The user-defined function MUST return a value to the form
manager. If not, unpredictable things may happen in the
processing of the forms.
If no user-defined function is desired, use the NO_BUTTON_FUNC
macro in place of the function pointer in the last argument in
FormSetButtonField(). The button field will just return the
value assigned to it if NO_BUTTON_FUNC is used. For example:
Page 26 The C Window Library Page 26
FormSetButtonField(form,entry,FORM_ACCEPT,"String",NO_BUTTON_FUNC)
will return FORM_ACCEPT if the button field is accepted.
If you do have a user-defined function, the normal return value,
i.e. the third argument in FormSetButtonField() is ignored, and
the return value for the user-defined function is used.
Here are the possible return values that a button field can
return to the form manager. These return values are also used
for the user-defined function (if it exists) that is bound to
the button.
Return Value Definition
------------ ----------
FIELD_PREVFIELD Move input cursor to the previous
field in the form and start editing
from there.
FIELD_NEXTFIELD Move input cursor to the next field
in the form and continue editing the
next field.
FIELD_CONTINUE_PROCESS Do nothing and go on to the next
field.
FORM_CLEAR Clear the form and move input cursor
to first available field.
FORM_ACCEPT Accept the current input in the form
and exit.
FIELD_NEWFIELD Move cursor to a new field and
continue editing from there.
FORM_CANCEL Do not accept any input that may have
been previously entered and quit.
FIELD_CONTINUE Stay in the button field.
The FIELD_PREVFIELD return value will move the input cursor to
the previous field in the form. If you try to move beyond the
first available field on the form the FORM_WRAP and/or the
FORM_EXIT_INITIAL form options will take action depending on
whether they are on or off. See CREATING FIELD ENTRIES for a
definition of the FORM_WRAP and FORM_EXIT_INITIAL options.
The FIELD_NEXTFIELD return value will move the input cursor to
the next field in the form. If you try to move beyond the first
available field in the form, the FORM_WRAP form option will take
action depending on whether this option was turned on.
The FORM_CLEAR return value clears the form of all input data
and moves the input cursor to the first available field.
Page 27 The C Window Library Page 27
The FORM_ACCEPT return value accepts all the input from the
input fields and exits. The form is not exited automatically if
the FORM_CHECK option is on or if a field in the form has the
FIELD_CHECK option on. See CREATING FIELD ENTRIES for a
definition of the FORM_CHECK and FIELD_CHECK options.
The FORM_CANCEL rejects all input and exits the form. The form
is not automatically exited if there is an exit function defined
for the form. Form exit functions are discussed later in the
manual.
The FIELD_CONTINUE_PROCESS is a 'do nothing and go on to the
next field' return value. Use this return value if you want the
button function to tell the form manager to go on to the next
field (or previous field, depending on the direction that the
input cursor was going). This return value is usually used if
there is a user-defined function defined, and only the side
effects that the user function may do is of any concern. For
instance, the user-defined function may display windows, and
then return. You would then return a FIELD_CONTINUE_PROCESS to
the form manager to state that you do not want anything special
to be done.
The FIELD_NEWFIELD return value moves the input cursor to the
field assigned to the pointer in the third argument of the
user-defined function. This return value can only be used if
you have a user-defined function that is bound to the button
field. If you remember, the user-defined function's prototype
passed a pointer to the current field number. If you assign a
field number to the dereferenced pointer and the FIELD_NEWFIELD
return value is used, the form manager will move the input
cursor to the field desired. If the field entry does not exist,
the form manager will not move the input cursor. If the field
is protected (FIELD_PROTECT flag is on) for the desired field,
the input cursor is not moved.
FIELD_CONTINUE returns control to the button field. You cannot
exit this field if it is accepted. You can use this type of
button field to implement help and display help information.
Here is a small example of the CWL_BUTTON field:
#include "cwlwin.h"
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
/* initialize entries for form 1 */
FIELD_ENTRY fentry[] = {CWL_BUTTON,0,0,"",' ',0,0,
NO_FIELD_OPTIONS,0,0,"",
CWL_BUTTON,0,9,"",
' ',0,0,NO_FIELD_OPTIONS,0,
0,"", FIELDEND};
FORMPTR form;
WPOINTER w;
main()
{
int i;
int attr[2];
Page 28 The C Window Library Page 28
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,1,1,78,22,NORM,
NORM,SINGLEBOX);
attr[NORMATTR] = NORM;
attr[HIATTR] = REVERSE;
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT);
/* Let form know about button fields */
FormSetButtonField(form,0,FIELD_NEXTFIELD,"Accept",attr,
NO_BUTTON_FUNC);
FormSetButtonField(form,1,FORM_CANCEL,"Cancel",attr,
NO_BUTTON_FUNC);
WindowWriteCenterString(w,
"Use Left or Right Arrow Keys to move highlight",2);
/* get the input */
FormGetInput(form,1,0);
}
In the above example, two button fields are defined. The row
and column entries in the field description, fentry[], tells
where the button field will be placed. Note that the only
meaningful entries in the CWL_BUTTON field are its row and
column in the form, and the field options (the only option that
can be used is FIELD_PROTECT). All other arguments are
meaningless (i.e. regular expression, starting input position,
etc.). The video attributes are derived from the array of
attributes given in the FormSetButtonField() function.
When the form encounters the first button, the highlight is
moved to the position of the first button's prompt string.
When the user hits the 'accept' key, the return value
FIELD_NEXTFIELD is returned to the form manager, informing it to
move the cursor to the next field. A return value of
FIELD_CONTINUE_PROCESS would have accomplished the same thing.
The highlight is then moved to the next field, which is also a
button field. When the user accepts this field, the form is
automatically exited.
If there are no errors, FormSetButtonField() will return
NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to allocate for the
internal button data structure.
Page 29 The C Window Library Page 29
Radio Fields and the RADIO_ENTRY structure
------------------------------------------
A radio field is a field that comprises a list of choices given
to the user. Only one of the choices can be chosen. Usually a
radio field is set up as a column and/or row of prompts with a
'floating' character that goes from prompt to prompt when the
user is selecting an option. Unlike the CWL_LIST option, the
radio field is not a popup menu, but is comprised of text
written to the form window.
To set up a radio field, the field type must be initialized to
CWL_RADIO. This is done when initializing the array of field
entries.
The next step is to initialize an array of RADIO_ENTRY
structures. Here is the layout for the RADIO_ENTRY structure:
char *prompt - Prompt string to write to the form window.
int hotkey_letter - Letter to highlight in prompt string.
unsigned prompt_row - row to write the prompt string.
unsigned prompt_col - column to write the prompt string.
unsigned button_row - row to write the radio button character.
unsigned button_col - column to write the radio button character.
An array of these structures is needed to complete the total radio
field definition. Here is an example:
RADIO_ENTRY radio_entry[] =
{"( ) Radio 1",'2',0,0,0,1, /* Radio Field 1 */
"( ) Radio 2",'2',1,0,1,1, /* Radio Field 2 */
"( ) Radio 3",'3',2,0,2,1, /* Radio Field 3 */
CWL_NULL}; /* Terminator */
Note that the variable radio_entry is an array of 3
RADIO_ENTRY's. The first entry is a string that will be written
to the window. In the example above the first RADIO_ENTRY's
prompt string is "( ) Radio 1". The next entry is the character
to highlight in the prompt string. This character will serve as
a 'hotkey'. When this character is pressed, the radio button
character will automatically be placed at the desired choice.
If no hotkey is desired, this entry should be 0. The third and
fourth entries are the (row,col) coordinates of where the prompt
is placed in the form window. The fifth and sixth entries are
the (row,col) coordinates of the 'floating' character. This
character will be placed at the desired position when the user
moves the highlight from entry to entry. Note that the above
example strategically placed the floating character in between
the parentheses in each of the prompt strings. This is the
usual way to display a radio field, but you have the flexibility
to design your own layouts.
The array of RADIO_ENTRY's MUST be terminated with the CWL_NULL
constant. Leaving this out will cause unpredictable results.
Page 30 The C Window Library Page 30
Once the array of RADIO_ENTRY's has been set up, the next thing
is to call the FormSetRadioField() function. This function
binds the RADIO_ENTRY's to the form, and defines attributes and
the button character to use for the radio field. Here is the
prototype:
int FormSetRadioField (FORMPTR form, int entry,
RADIO_ENTRY *rptr, int rchar,
int start, int *attr)
The first two arguments are the form and the entry to assign the
RADIO_ENTRY's to. These must exist for the FormSetRadioField()
function to succeed. The third argument is the array of
RADIO_ENTRY's that was set up previously. The fourth argument
is the character that will float from choice to choice when the
user is deciding which selection to make. The fifth argument is
the starting entry to place the button character. Entry numbers
are numbered from 0 to the highest radio entry less one. The
last argument is an array of integers denoting the color
attributes to use for the radio field. Each element of this
color array stands for a different aspect of the radio field.
Here are the constants that denotes positions in the color
array:
NORMATTR - This is the color of the unhighlighted entry.
HIATTR - This is the color of the highlighted entry. The
highlighted entry is the current entry that the user
has the choice of accepting. The highlight is moved
from entry to entry when the user hits the
appropriate keys. See GETTING INPUT FROM A FORM for
a discussion of these keys.
HOTATTR - This is the color of the hotkey.
UNAVAILATTR - This is the attribute to use for unavailable radio
entries. More on available and unavailable
entries later on.
To initialize an array that is large enough to hold the
attributes, Use the NUMRADIOCOLORS constant. This constant
holds the number of colors needed to define the radio field's
color scheme.
Here is a small example of using FormSetRadioField():
#include "cwlwin.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
RADIO_ENTRY radio_entry[] = {"( ) Radio 1",'1',0,0,0,1,
"( ) Radio 2",'2',1,0,1,1,
"( ) Radio 3",'3',2,0,2,1,
CWL_NULL};
Page 31 The C Window Library Page 31
FORMPTR form;
FIELD_ENTRY field[] = {CWL_RADIO,0,0,"",' ',
NO_FIELD_OPTIONS,0,0,"",FIELDEND};
/* Initialize array of colors */
int attr[NUMRADIOCOLORS];
main()
{
int retval;
/* Assume form is initialized */
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
retval = FormSetRadioField(form,0,radio_entry,7,0,attr);
if (retval != NO_ERROR)
/* some error message */
}
The above call to FormSetRadioField() uses the FORMPTR form and
field entry 1 (this is the RADIO field). The array,
radio_entry, is used as the array of RADIO_ENTRY's. The ASCII
character 7 is used as the floating button character. The IBM
PC character set defines this as the 'bullet' character. This
character is usually used for radio fields, but you can use any
ASCII character you desire (however, I highly recommend NOT
using the space character!). The fifth argument starts the
radio button character on the first radio entry.
If there are no errors, FormSetRadioField() and will return
NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to allocate for the
internal radio field data structure.
Deactivating and Activating Radio Entries
-----------------------------------------
If FormSetRadioField() is successful, all of the radio entries
are available for the user to choose from. However, there may
be situations where you may want some options disabled. To
disable radio entries use the FormDeactivateRadioEntry()
function. Here is the prototype to the function:
int FormDeactivateRadioField(FORMPTR form, int entry,
int radionum)
Page 32 The C Window Library Page 32
The first two arguments are the form and entry number of where
to find the radio entry. The last argument is the entry in the
radio field to deactivate. The reason for using the form and
entry to find the radio field is that you can use the same radio
field in different forms. Therefore you must supply the form
and entry number to find the radio field. Once the radio entry
is found, the prompt string for the desired radio entry takes on
the UNAVAILATTR color. Also this field is skipped automatically
when the user is moving the button character from field to
field.
To reactivate a field, the FormActivateRadioEntry() function is
used. Here is the prototype:
int FormActivateRadioEntry(FORMPTR form, int entry,
int radionum)
The arguments have the same definition as the
FormDeactivateRadioEntry(). The radio entry is automatically
given its NORMATTR color.
Retrieving the Radio selection
------------------------------
To find out what selection was made in the radio field, use the
FormGetRadioChoice() function. This function returns the number
of the radio entry that was chosen. Radio entries are numbered
from 1 to the highest entry. Entries are numbered as they are
ordered in the RADIO_ENTRY array. Here is the prototype to the
function:
int FormGetRadioChoice(FORMPTR form, int entry)
The only arguments are the form and field entry where the radio
field is defined. Here is a small example:
#include "cwlwin.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
RADIO_ENTRY radio_entry[] = {"( ) Radio 1",'1',0,0,0,1,
"( ) Radio 2",'2',1,0,1,1,
"( ) Radio 3",'3',2,0,2,1,
CWL_NULL};
FORMPTR form;
FIELD_ENTRY field[] = {CWL_RADIO,0,0,"",' ',0,0,
NO_FIELD_OPTIONS,0,0,"",FIELDEND};
int attr[NUMRADIOCOLORS];
WPOINTER w;
Page 33 The C Window Library Page 33
main()
{
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,COLOR1,
COLOR1,SINGLEBOX);
/* Initialize form */
form = FormInitialize(w,field,FORM_HIGHLIGHT|FORM_STATIC);
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
FormSetRadioField(form,0,radio_entry,7,0,attr);
WindowWriteCenterString(w,
"Hit TAB to accept, Up or Down Arrows to change choice",3);
FormGetInput(form,1,0);
WindowMoveCursor(w,4,19);
VideoPrintf("The radio choice was %d",
FormGetRadioChoice(form,0));
}
The example above sets up a radio field, gets the input from the
form, and then prints the radio entry that was chosen. You can
call the FormGetRadioChoice() at any time, even in user-defined
functions that may be performed while the form is active.
If successful, FormGetRadioChoice() returns the current radio
entry that is chosen. If all of the radio entries are
deactivated, or the radio field is a protected field (no input
will be accepted), the return value is -1.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Checkbox Fields and the CHECKBOX_ENTRY structure
------------------------------------------------
A checkbox field is a field that comprises a list of choices
given to the user. Any number of these choices can be selected.
This differs from the radio field defined above in that the
radio fields only allowed one selection.
To set up a checkbox field, the field type must be initialized
to CWL_CHECKBOX. This is done when initializing the array of
field entries.
Page 34 The C Window Library Page 34
The next step is to initialize an array of CHECKBOX_ENTRY
structures. Here is the layout for the CHECKBOX_ENTRY
structure:
char *prompt - Prompt string to write to the form
window.
int hotkey_letter - Letter to highlight in prompt string.
unsigned prompt_row - row to write the prompt string.
unsigned prompt_col - column to write the prompt string.
unsigned button_row - row to write the checkbox button
character.
unsigned button_col - column to write the checkbox button
character.
An array of these structures is needed to complete the total
checkbox field definition. Here is an example:
CHECKBOX_ENTRY checkbox_entry[] =
{"[ ] Check 1",'1',0,0,0,1, /* Checkbox field 1 */
"[ ] Check 2",'2',1,0,1,1, /* Checkbox field 2 */
"[ ] Check 3",'3',2,0,2,1, /* Checkbox field 3 */
CWL_NULL}; /* Terminator */
Note that the variable checkbox_entry is an array of 3
CHECKBOX_ENTRY's. The first entry is a string that will be
written to the window. In the example above the first
CHECKBOX_ENTRY's prompt string is "[ ] Check 1". The next entry
is the character to highlight in the prompt string. This
character will serve as a 'hotkey'. When this character is
pressed, the checkbox button character will automatically be
placed at the desired choice. If no hotkey is desired, this
entry should be 0. The third and fourth entries are the
(row,col) coordinates of where the prompt is placed in the form
window. The fifth and sixth entries are the (row,col)
coordinates of the checkbox character. This character will be
placed at the desired position when the choice is selected.
Note that the above example strategically placed the checkbox
character in between the brackets in each of the prompt strings.
This is the usual way to display a checkbox field, but you have
the flexibility to design your own layouts.
The array of CHECKBOX_ENTRY's MUST be terminated with the
CWL_NULL constant. Leaving this out will cause unpredictable
results. Once the array of CHECKBOX_ENTRY's has been set up,
the next thing is to call the FormSetCheckboxField() function.
This function binds the CHECKBOX_ENTRY's to the form, and
defines attributes and the button character to use for the
checkbox field. Here is the prototype:
int FormSetCheckboxField (FORMPTR form, int entry,
CHECKBOX_ENTRY cptr[], int cchar,
int start, int *attr)
Page 35 The C Window Library Page 35
The first two arguments are the form and the entry to assign the
CHECKBOX_ENTRY's to. These must exist for the FormSetCheckbox()
function to succeed. The third argument is the array of
CHECKBOX_ENTRY's that was set up previously. The fourth
argument is the character that will be placed in when the entry
is selected. The fifth argument is the checkbox entry to place
the cursor when the field is initially edited. The last
argument is an array of integers denoting the color attribute to
use for the checkbox field. Each element of this color array
stands for a different aspect of the checkbox field. Here are
the constants that denotes positions in the color array:
NORMATTR - This is the color of the unhighlighted entry.
HIATTR - This is the color of the highlighted entry. The
highlighted entry is the current entry that the user
has the choice of accepting. The highlight is moved
from entry to entry when the user hits the
appropriate keys. See GETTING INPUT FROM A FORM for
a discussion of these keys.
HOTATTR - This is the color of the hotkey.
UNAVAILATTR - This is the attribute to use for unavailable
checkbox entries. More on available and
unavailable entries later on.
To initialize an array that is large enough to hold the
attributes, Use the NUMCHECKBOXCOLORS constant. This constant
holds the number of colors needed to define the checkbox field's
color scheme.
Here is a small example of using FormSetCheckboxField():
#include "cwlwin.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
CHECKBOX_ENTRY checkbox_entry[] = {"[ ] Check 1",'1',0,0,0,1,
"[ ] Check 2",'2',1,0,1,1,
"[ ] Check 3",'3',2,0,2,1,
CWL_NULL};
FORMPTR form;
FIELD_ENTRY field[] = {CWL_CHECKBOX,0,0,"",' ',0,0,
NO_FIELD_OPTIONS, "", FIELDEND};
int attr[NUMCHECKBOXCOLORS];
WPOINTER w;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
Page 36 The C Window Library Page 36
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,COLOR1,
COLOR1,SINGLEBOX);
/* Initialize form */
form = FormInitialize(w,field,FORM_HIGHLIGHT);
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
FormSetCheckboxField(form,0,checkbox_entry,'X',0,attr);
}
The above call to FormSetCheckboxField() uses the FORMPTR form
and field entry 0 (this is the CWL_CHECKBOX field). The array,
checkbox_entry, is used as the array of CHECKBOX_ENTRY's. The
'X' character is used as the checkbox character. This character
is usually used for checkbox fields, but you can use any ASCII
character you desire (as stated before, I highly recommend NOT
using the space character!).
If there are no errors, FormSetCheckboxField() and will return
NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to allocate for the
internal checkbox field data structure.
Deactivating and Activating Checkbox Entries
--------------------------------------------
If FormSetCheckboxField() is successful, all of the checkbox
entries are available for the user to choose from. However,
there may be situations where you may want some options
disabled. To disable checkbox entries use the
FormDeactivateCheckboxEntry() function. Here is the prototype
to the function:
int FormDeactivateCheckboxField(FORMPTR form, int entry,
int checkboxnum)
The first two arguments are the form and entry number of where
to find the checkbox entry. The last argument is the entry in
the checkbox field to deactivate. The reason for using the form
and entry to find the checkbox field is that you can use the
same checkbox field in different forms. Therefore you must
supply the
Page 37 The C Window Library Page 37
form and entry number to find the checkbox field. Once the
checkbox entry is found, the prompt string for the desired
checkbox entry takes on the UNAVAILATTR color.
To reactivate a field, the FormActivateCheckboxEntry() function
is used. Here is the prototype:
int FormActivateCheckboxEntry(FORMPTR form, int entry,
int checkboxnum)
The arguments have the same definition as the
FormDeactivateCheckboxEntry(). The checkbox entry is
automatically given its NORMATTR color.
Retrieving the checkbox selection
---------------------------------
To find out whether a checkbox entry was selected, use the
FormGetCheckboxChoice() function. This function returns 1 if
the entry is selected, 0 otherwise. Checkbox entries are
numbered from 1 to the highest entry. Entries are numbered as
they are ordered in the CHECKBOX_ENTRY array. Here is the
prototype to the function:
int FormGetCheckboxChoice(FORMPTR form, int entry, int cboxentry)
The arguments are the form and field entry where the checkbox
field is defined. The last argument is the checkbox entry to
test to see if it was selected. Here is a small example:
#include "cwlwin.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
CHECKBOX_ENTRY checkbox_entry[] = {"[ ] Check 1",'1',0,0,0,1,
"[ ] Check 2",'2',1,0,1,1,
"[ ] Check 3",'3',2,0,2,1,
CWL_NULL};
FORMPTR form;
FIELD_ENTRY field[] = {CWL_CHECKBOX,0,0,"",' ',0,0,
NO_FIELD_OPTIONS,0,0,"", FIELDEND};
int attr[NUMCHECKBOXCOLORS];
WPOINTER w;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
Page 38 The C Window Library Page 38
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,COLOR1,
COLOR1,SINGLEBOX);
/* Initialize form */
form = FormInitialize(w,field,FORM_HIGHLIGHT|FORM_STATIC);
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
FormSetCheckboxField(form,0,checkbox_entry,'X',0,attr);
WindowWriteCenterString(w,
"Hit TAB to accept, Space Bar to toggle, Arrow keys to change"
"choice",3);
FormGetInput(form,1,0);
WindowMoveCursor(w,5,0);
for (i=0; i<3; i++)
VideoPrintf("Checkbox choice %d was %s chosen\n",i,
FormGetCheckboxChoice(form,1,i)?"":"not");
}
The example above sets up a checkbox field, gets the input from
the form, and then loops to see if any checkboxes were selected.
The string "not" is printed if FormGetCheckboxChoice() returns
0, else an empty string is printed. FormGetCheckboxChoice() can
be called at any time, even in user-defined functions that may
be performed while the form is active.
FormGetCheckboxChoice() returns 1 if the choice was selected, 0
otherwise.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Page 39 The C Window Library Page 39
GETTING INPUT FROM A FORM
-------------------------
The following section discusses how to call functions that
process the input form.
FormGetInput()
--------------
The FormGetInput() function processes a form. Here is a
prototype:
int FormGetInput(FORMPTR form, int rank, int start)
or
int FormGetInput(FORMPTR form, int rank, int start, WPOINTER w)
The first prototype is for non-virtual forms (regular windows
are used).
The second prototype is for virtual forms. The second
prototype's last argument is a pointer to window. This window
is the viewport that is currently assigned to the virtual window
used to initialize the FIELD_ENTRY's. This parameter is
necessary since the form manager only knows what the virtual
window is, and has no record of the viewport (since a virtual
window can have multiple viewports).
The first argument to FormGetInput() is the pointer to a form.
This form must have been previously initialized with
FormInitialize().
The second argument is the rank of the window the form is going
to be displayed on.
The third argument is the field entry to start the input from.
Field entries are numbered from 0 to the highest field defined
in the form less one. If the field is protected, a circular
search for the next available field is done. For example , if
there are 6 fields, and field 4 is protected, field 5 is the
next available field. However if field 5 is protected, field 0
is the next available field.
The fourth argument, as discussed above, is an optional
argument. This argument must be used if you are using a virtual
form.
If there are no errors, FormGetInput() returns NO_ERROR.
If there are errors, FormGetInput() returns one of the following
and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
BAD_WINDOW if the viewport window does not exist.
Page 40 The C Window Library Page 40
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
FIELD_ENTRY field_array[] =
/* define first field entry */
{CWL_INTEGER,0,19,"___",'_',1,3,FIELD_RJUSTIFY,NORM,0,
"3[0-9]",
CWL_STRING, 1, 19, "__________", '_', 0, 10,
NO_FIELD_OPTIONS, 0,NORM, "10.",
CWL_INTEGER,2, 19, "__", '_', 2, 2,NO_FIELD_OPTIONS,
0,NORM, "2[0-9]",
CWL_DOUBLE,3, 19, "_______",'_',1,7,
FIELD_COMMA|FIELD_LJUSTIFY,0,NORM,"7[0-9/.]",
CWL_CHAR, 4, 19,"_", '_', 1, 1, FIELD_UPPERCASE, 0,NORM,
"[YyNn]",
FIELDEND};
WPOINTER w;
FORMPTR form;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,40,10,NORM,
NORM,SINGLEBOX);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
NO_FORM_OPTIONS); /* form options */
if (form == FORM_NULL_PTR)
{
printf("Form could not be initialized");
exit(0);
}
FormGetInput(form,1,0); /* Get Input for the form */
}
Virtual Form Scrolling
----------------------
If the form is a virtual form, the form is scrolled
automatically to the desired field if the field is not currently
in the viewport. If the form has to be scrolled up or down, the
field will come into view on the last line of the viewport or
the first line, depending on whether the form was scrolled up or
down to bring the field into view.
If the form has to be scrolled left or right to bring the field
in view, the field will either be brought in so that it is right
justified in the viewport, or will appear on the left edge of
the viewport depending on whether the form manager had to scroll
the form left or right.
Page 41 The C Window Library Page 41
Editing Input
-------------
When getting input from a form, the following key definitions
are used as the defaults:
Offset in Key
Function Key Table
-------- --- -------------
Move cursor left Left Arrow FIELD_MOVELEFT_KEY
Move cursor right Right Arrow FIELD_MOVERIGHT_KEY
Delete character Del FIELD_DELNOMOVE_KEY
Toggle Insert/Overwrite Insert FIELD_INSTOGGLE_KEY
Erase Input ^E FIELD_ERASE_KEY
Destructive backspace Backspace FIELD_BACKSPACE_KEY
Accept Input and goto Enter FIELD_ACCEPT_KEY
next field.
Accept default and Not Assigned FIELD_ACCEPTDEFAULT_KEY
return
Go to first column Home FIELD_HOME_KEY
Move cursor to last End FIELD_END_KEY
character
Go to previous field Up Arrow FIELD_PREVFIELD_KEY
Go to next field Down Arrow FIELD_NEXTFIELD_KEY
Toggle Field Space Bar FIELD_TOGGLE_KEY
Button Accept key Enter BUTTON_ACCEPT_KEY
Button Move to next Right Arrow BUTTON_NEXTFIELD_KEY
field
Button Move to prev Left Arrow BUTTON_PREVFIELD_KEY
field
Move Radio button to Down Arrow RADIO_NEXTENTRY_KEY
next entry
Move Radio button to Up Arrow RADIO_PREVENTRY_KEY
previous entry
Move to next field from Tab RADIO_NEXTFIELD_KEY
radio field
Move to previous field ShiftTab RADIO_PREVFIELD_KEY
from radio field
Page 42 The C Window Library Page 42
Select/deselect Space Bar CHECKBOX_CHOICE_KEY
checkbox entry
Move checkbox cursor to Down Arrow CHECKBOX_NEXTENTRY_KEY
next checkbox entry
Move checkbox cursor to Up Arrow CHECKBOX_PREVENTRY_KEY
previous checkbox entry
Move to next field from Tab CHECKBOX_NEXTFIELD_KEY
checkbox field
Move to previous field ShiftTab CHECKBOX_PREVFIELD_KEY
checkbox field
Accept form ^S FORM_EXIT_ACCEPT_KEY
Escape form Escape FORM_CANCEL_KEY
Clear Form ^End FORM_CLEAR_KEY
Here is a list of what the key functions perform:
Move cursor left - Moves the cursor left one character. If the
beginning of the input field is encountered
the cursor is not moved.
Move cursor right - Moves the cursor right one character. If
the end of the input field is encountered,
the cursor is not moved.
Delete character at cursor - Deletes the character at the
position of the cursor. If in
insert mode, any input to the right
of the cursor is moved one
character to the left. If in
overwrite mode, no characters are
moved.
Toggle Insert/Overwrite Mode - toggles the input between insert
and overwrite mode. If in insert
mode, the default cursor is an
underline cursor. If in
overwrite mode, the default
cursor is a full block.
Erase Input - Deletes all characters inputted and moves the
cursor to the first input position.
Destructive Backspace - deletes the character immediately to the
left of the cursor and moves the cursor
to the left one character. If insert
mode is on, the characters from the
current cursor position to the end of
the input field are also moved.
Page 43 The C Window Library Page 43
Accept string - Accepts the string that is inputted and returns
the string. Also goes to next field by default.
Accept default and return - Returns the default string given to
the input routine.
Go to first column in field - Moves cursor to the first input
position.
Go to last character in field - Moves cursor to the last
character in the current input
string.
Go to previous field - Moves input cursor to the first character
in the previous field. If field is field 1 or
first available field, the input cursor
is moved to the last input field if the
FORM_WRAP option is on, otherwise the
input cursor is not moved.
Go to next field - Moves the input cursor to the first character
in the next field in sequence.
Toggle field - Displays next choice in a CWL_TOGGLE field.
Only is active for CWL_TOGGLE field.
Undefined for other fields.
Button Accept - Accepts the CWL_BUTTON field and will perform
whatever the buttons return value was.
Button Move to next field - Moves to the next field from a
button Does not accept the button
field.
Button move to prev. field - Moves to previous field from a
button field. Does not accept the
button field.
Move Radio button to next radio entry - moves the highlight in
the radio entry to the
next available radio
entry.
Move Radio button to prev. radio entry - moves the highlight in
the radio entry to the
previous radio entry.
Move to next field from radio - moves to the next field from a
radio field.
Move to prev. field from radio - moves to the previous field
from a radio field.
Select/Deselect checkbox entry - toggles checkbox entry for
selection/delection.
Page 44 The C Window Library Page 44
Move to next checkbox entry - moves the highlight to the next
checkbox entry.
Move to prev. checkbox entry - moves the highlight to the
previous checkbox entry.
Move to next field from checkbox - moves to the next field from
a checkbox field.
Move to prev. field from checkbox - moves to the previous field
from a checkbox field.
Accept form - Accepts the input to a form, and exits
processing the form.
Escape form and do not accept - Exits form without accepting the
input to any fields.
Clear Form - clears all input in a form and moves the cursor to
the first available field.
Changing the Editing Key definitions globally using the
CWLform_edit_key table
----------------------
You can change the key definitions globally (all fields will
have the same key definitions) by changing the CWLform_edit_key
array of values. The mapped position is the offset in a table
of field key functions. By changing the value there, you can
change the keys used to perform these functions. If you do want
to change these keys, I recommend using the key definitions
found in the keycodes.h file. For example, if you wanted tab
key to be the advance to next field key you would do the
following:
CWLform_edit_key[FIELD_NEXTFIELD_KEY] = TAB;
The table of key functions is stored in the array
CWLform_edit_key. The TAB definition is found in the keycodes.h
file. To totally undefine a key definition, assign a 0 to the
desired array position in window_edit_key. For example:
CWLform_edit_key[FIELD_DELNOMOVE_KEY] = 0;
undefines the delete character at cursor definition.
When changing keys, make sure that the definitions all have
unique key combinations. If you desire more keystrokes for a
particular key function, see Undefined Form Keystroke Processing
below.
Changing the Editing Key definitions using FormAssignFieldKeys()
----------------------------------------------------------------
The FormAssignFieldKeys() assigns a key definition to a
particular field. In other words, each field can have its own
Page 45 The C Window Library Page 45
set of editing key definitions. Here is the prototype:
int FormAssignFieldKeys(FORMPTR form, int entrynum,
unsigned *keydef)
The first argument is the pointer to the form. The form must
have been successfully initialized with FormInitialize().
The second argument is the field entry number to assign these
key definitions to. As stated before, entry numbers are labeled
from 0 to the highest entry number in the form less one.
The third argument is an array of key definitions. This array
must be analogous to the CWLform_edit_key array.
Example:
#include "cwlwin.h"
#include <string.h>
/* ... define everything ... */
unsigned newkeys[NUMFORMKEYS];
FORMPTR form;
FIELD_ENTRY field_entry[] = { /* .. Field definitions ... */ };
WPOINTER w;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
/* ... assume Form Initialization stuff has been done ... */
/* copy old key definitions to the new array */
memcpy(newkeys,CWLform_edit_key,sizeof(CWLform_edit_key));
/* assign desired keys */
newkeys[FIELD_NEXT_KEY] = TAB;
newkeys[FIELD_PREV_KEY] = SHIFTTAB;
/* Assign this key definition to second field entry */
FormAssignFieldKeys(form,1,newkeys);
}
Note that the constant NUMFORMKEYS was used to make sure that
our newkeys array was large enough to hold all the key
definitions. Also note the shortcut that was taken with the
memcpy() function. This copied all the old key definitions to
the newkeys array. Both the newkeys array and the
CWLform_edit_key array are guaranteed to be the same size if the
constant NUMFORMKEYS is used.
If there are no errors, FormAssignFieldKeys() returns NO_ERROR.
If there are errors, FormAssignFieldKeys() returns one of the
following and sets window_error_code to one these values:
Page 46 The C Window Library Page 46
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Traversing fields and the FORM_HIGHLIGHT option
-----------------------------------------------
When going from field to field, you can have each field take on
the field color only when they are the active field (field
currently being input). This will happen if the FORM_HIGHLIGHT
option is on. If the field is not the active field, the field
takes on the same color as the window or the viewport text
color.
If the FORM_HIGHLIGHT option is off, each field will take on its
field color even if they are not the current field.
Page 47 The C Window Library Page 47
ASSIGNING VALUES TO AND RETRIEVING VALUES FROM A FORM
-----------------------------------------------------
When you edit an input field, you are entering just a string of
characters. The C Window Library's form manager will
automatically convert these strings to the correct data type,
and assign these values to specified variables when a form is
exited, or whenever you want to retrieve the data.
The field type determines what type of conversion will be done.
The supported types are the normal C types. The CWL_SUBFORM,
CWL_VSUBFORM, CWL_BUTTON, CWL_RADIO, and CWL_CHECKBOX fields do
not have a return type. The CWL_LIST field returns the string
in the popup menu that was selected. The CWL_TOGGLE field
returns the string that was chosen in the toggle field list.
FormSetFieldVariable()
----------------------
The FormSetFieldVariable() function assigns a variable to a
particular field in a form. When the form is exited, the data
is converted and transferred to the variable specified. Here is
the prototype:
int FormSetFieldVariable(FORMPTR form, int entrynum,
void *uservar, int display)
The first argument is the pointer to a form.
The second argument is the field entry to assign the user
variable to.
The third argument is a pointer to the user variable. The
fourth argument is a flag to tell the form manager whether to
display the value in the variable on the form. If display is
TRUE, the variable's value is automatically displayed in the
form. If display is FALSE, the variable's value is not
displayed in the form. No matter what the last argument is, the
address of the variable is assigned to the form.
If the field type is CWL_TOGGLE, this type translates to a
string type because a string will ultimately be displayed in the
field when a selection is made. CWL_SUBFORM's, CWL_VSUBFORM's,
CWL_BUTTON's, CWL_RADIO's, CWL_CHECKBOXes and CWL_LIST's have no
corresponding C data type, therefore you cannot assign a
variable to these field types.
Example:
#include "cwlwin.h"
#include <string.h>
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(_WHITE,_BLACK)
FORMPTR form;
Page 48 The C Window Library Page 48
FIELD_ENTRY field_entry[] =
{CWL_INTEGER,0,19,"_____",' ',1,5,NO_FIELD_OPTIONS,0,
REVERSE,"5[0-9]",
CWL_ULINTEGER,1,19,"_________",' ',1,9,NO_FIELD_OPTIONS,
0,REVERSE,"9[0-9]",FIELDEND};
WPOINTER w;
main()
{
int intvar = 123; /* define integer and long variables */
unsigned long lvar = 456L;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,60,4,NORM,
NORM,SINGLEBOX);
form = FormInitialize(w,field_entry,FORM_HIGHLIGHT);
/* Set user variables */
FormSetFieldVariable(form,0,&intvar,TRUE);
FormSetFieldVariable(form,1,&lvar,TRUE);
FormGetInput(form,1,0);
VideoPrintf(
"The value of intvar is %d.\nThe value of lvar is %ul",
intvar,lvar);
}
When the form is exited, the variables intvar and lvar have the
values automatically converted.
If you change the value of a variable that is assigned to a
field, the field is not updated. Use the FormPutFieldData() to
change the value of a field.
Warning! You must make sure that you assign the pointer to a
variable of the correct type. If not, you may overwrite memory
when the conversion takes place.
Placing input in a form with FormPutFieldData()
-----------------------------------------------
You can write the value of a variable or an expression to a
field at anytime using the FormPutFieldData() function. Here is
the prototype:
int FormPutFieldData(FORMPTR form, int entry, ...)
The first argument is the form, and the second is the entry
number. The last argument third is the value to write to the
field. Note that the ellipses are used when prototyping the
last argument. The reason for this is that the variable or
expression can be of any type, therefore the undefined third
argument.
Page 49 The C Window Library Page 49
You should make sure that the variable/expression translates to
the same data type as the field type. There is no harm done if
you have an expression of a different type than the field, but
you may get weird characters in the field when it is displayed.
Here is an example:
#include "cwlwin.h"
/* assume everything is initialized */
main()
{
int intvar = 0;
long lvar = 2;
/*...*/
FormPutFieldData(form,0,intvar); /* place value of intvar in
entry 1 */
FormPutFieldData(form,1,lvar); /* place value of lvar in
entry 2 */
FormPutFieldData(form,0,3+5*6); /* place value of expression
in entry 1 */
/* ... */
}
If there are errors, FormPutFieldData() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Retrieving Input with FormGetFieldData()
----------------------------------------
You can retrieve and convert the string entered in a field at
any time, including if the form has been exited, with the
FormGetFieldData() function. Here is the prototype:
int FormGetFieldData(FORMPTR form, int entrynum, void *uservar)
The first and second arguments are the form and field entry
number, respectively.
The third argument is the pointer to the desired variable to
assign this value to.
Example:
#include "cwlwin.h"
FORMPTR form;
FIELD_ENTRY field[] = {CWL_INTEGER,
/* other initializations */ };
int myvar;
Page 50 The C Window Library Page 50
main()
{
/* assume everything is initialized */
/* get what was entered in field 1 and copy converted
value to myvar */
FormGetFieldData(form,1,&myvar);
}
Warning! You must make sure that you assign the pointer to a
variable of the correct type. If not, you may overwrite memory
when the conversion takes place.
If there are no errors, FormGetFieldData() returns NO_ERROR.
If there are errors, FormGetFieldData() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Pre-filling a form with default data with
FormInitializeFieldData()
-----------------------------------------
You can pre-fill a form with data before you start getting input
from the form. The only restriction is that the data must be in
string form.
The FormInitializeFieldData() partially or totally initializes a
form with default data. The data must be in string form. Here
is the prototype:
int FormInitializeFieldData(FORMPTR form, char **data, int
start, int end)
The first argument is the pointer to a form.
The second argument is a pointer to an array of characters.
This will be dealt with in depth later on.
The third and fourth arguments are the starting entry to
initialize and the ending entry to initialize.
FormInitializeFieldData() initializes a range of field entries.
If the ending entry number is less than the starting entry
number, the ending entry number will be made equal to the
starting entry number.
Setting up array of strings using Allocate2DArray() function
------------------------------------------------------------
There are many ways to set up the array of strings required for
the second argument to FormInitializeFieldData(). Here are
various methods of assigning "123" to an array of strings:
Page 51 The C Window Library Page 51
/* Method 1 */
#include <string.h>
char data[5][4];
FORMPTR form;
main()
{
int i;
/* ... assume form already initialized */
/* copy "123" to data array */
for (i=0;i<4;i++)
strcpy(data[i],"123");
FormInitializeFieldData(form,data,0,4);
}
/* Method 2 */
#include <string.h>
char *data[5] = {
"123",
"123",
"123",
"123",
"123" };
main()
{
/* ... assume form already initialized */
FormInitializeFieldData(form,data,0,4);
}
/* Method 3 */
#include "cwlwin.h"
char **data;
main()
{
data = (char **)Allocate2DArray(5,4,sizeof(char));
for (i=0;i<5;i++)
strcpy(data[i],"123");
FormInitializeFieldData(form,data,0,4);
}
The first two methods are self-explanatory, or if they are not,
any elementary book on C programming will explain the methods
used to initialize an array of strings.
Page 52 The C Window Library Page 52
The third method dynamically allocates memory for a two
dimensional array. Note the use of the function
Allocate2DArray(). This function allocates a two dimensional
array from the heap. The first and second arguments to this
function are the number of rows and columns in the array,
respectively. The third argument is the size of each data
element (in bytes) in the array. Since we want to initialize a
two dimensional array of five strings with 4 characters for each
string (you should allow an extra character for the terminating
null for each string), the size of each element will be the size
of one character. Note the use of sizeof() to determine the
size of a character.
You can use Allocate2DArray() with any data type. You must make
sure that the return value is cast to the proper pointer type,
since the returning data type is a void pointer (This rule is
relaxed for C programs, but it is strictly enforced in C++
programs).
Allocate2DArray() returns a null pointer if it cannot allocate
the memory desired. You can allocate up to 64K of memory with
this function. To calculate the amount of memory that will be
allocated, you should use the following formula:
rows X cols X sizeof(each data element)
The prototype for this function is include in the window.h file.
Since cwlwin.h includes window.h, there was no need to
explicitly include window.h in any of the examples.
Freeing a two dimensional array with Free2DArray()
--------------------------------------------------
If you want to dispose of a two dimensional array allocated with
Allocate2DArray(), you should use the Free2DArray() function.
The prototype is as follows:
void Free2DArray(void **array)
The only argument is the pointer to the two dimensional array.
Since this function does not return anything, you must make sure
that you are actually freeing a valid two dimensional array.
Using FormInitializeFieldData()
-------------------------------
As was stated above, FormInitializeFieldData() can totally or
partially fill a form with default data. The number of fields
that will be filled is determined by the starting and ending
field entry numbers, which are denoted by the third and fourth
arguments to FormInitializeFieldData(). For instance if the
starting entry is 0 and the ending entry is 5, the form manager
will start filling in the fields 0 through 5 with the data
stored in the array of strings, which was passed as the second
Page 53 The C Window Library Page 53
argument, to FormInitializeFieldData(). If a CWL_NULL is
encountered in the array of strings before the last entry
specified is reached,
FormInitializeFieldData() will stop initializing fields and will
return NO_ERROR. FormInitializeFieldData() should be called before
calling FormGetInput().
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE,BLACK_)
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"3[0-9]",
CWL_INTEGER,1,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"3[0-9]",
CWL_STRING,2,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"3[0-9]",
INTEGER,3,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"3[0-9]",
CWL_UINTEGER,4,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"3[0-9]",
CWL_CHAR,5,35,"_",'_',1,1,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"[YyNn]",
CWL_CHAR,6,35,"_",'_',1,1,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"[YyNn]",
CWL_INTEGER,7,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,
REVERSE,"3[0-9]",
FIELDEND};
WPOINTER w;
FORMPTR form;
char *data[8] = {
"123",
"0",
"ABC",
"200",
"230",
"N",
"Y",
"100"};
main()
{
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,40,10,NORM,
NORM,SINGLEBOX);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
FORM_HIGHLIGHT); /* form options */
Page 54 The C Window Library Page 54
if (form == FORM_NULL_PTR)
{
printf("Form could not be initialized");
exit(0);
}
FormInitializeFieldData(form,data,0,7);
FormGetInput(form,1,0); /* Get Input for the form */
}
If there are no errors, FormInitializeFieldData() returns
NO_ERROR.
If there are errors, FormInitializeFieldData() returns one of
the following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the starting field does not exist.
Page 55 The C Window Library Page 55
SETTING FIELD OPTIONS
---------------------
In the previous sections, the field options were set up during
initialization of the field entries. You can also set field
options at any time. If you want to set field options during
form input there are some restrictions.
FormSetFieldOptions()
---------------------
The FormSetFieldOptions() function turns on or off field
options. Here is the prototype:
int FormSetFieldOptions(FORMPTR form, int entrynum, int options,
int flag)
The first and second arguments are the form and the field entry
number, respectively.
The third arguments are the options desired. The fourth
arguments tell us whether to turn these options on or off. If
flag is equal to 1, the options are turned on. If flag is 0,
the options are turned off.
The field options are the same options specified in the CREATING
FIELD ENTRIES section above. Multiple field options can be
specified by using the bitwise OR (|) between field option
constants, just as before.
The field option that you would probably use this function for
most of the time is the FIELD_PROTECT option. As defined, if
the FIELD_PROTECT option is on, the form manager will skip over
this field and will go to the next available field. You will
probably want to toggle a field's FIELD_PROTECT option during
input of a form.
It is advised NOT to change the field options of a particular
field if the field is currently being edited. This may lead to
undesired results.
#include "cwlwin.h"
FORMPTR form;
/* ... skip other initializations ... */
main()
{
/* ... skip initializations ... */
/* set field protect option */
FormSetFieldOptions(form,0,FIELD_PROTECT,1);
/* turn off field protect option */
FormSetFieldOptions(form,0,FIELD_PROTECT,0);
}
Page 56 The C Window Library Page 56
If there are no errors, FormSetFieldOptions() returns NO_ERROR.
If there are errors, FormSetFieldOptions() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 57 The C Window Library Page 57
SETTING FORM OPTIONS
--------------------
In the previous sections, the form options were set up when
FormInitialize() was called. You can also set form options at
any time, including during input of a form.
FormSetOptions()
----------------
The FormSetOptions() function turns on or off form options.
Here is the prototype:
int FormSetOptions(FORMPTR form, int options, int flag)
The first argument is the pointer to the form.
The second argument are the options desired. The third argument
tells us whether to turn these options on or off. If flag is
equal to 1, the options are turned on. If flag is 0, the
options are turned off.
The form options are the same options specified in the
FormInitialize() function, which is described in the CREATING
FIELD ENTRIES section above. Multiple form options can be
specified by using the bitwise OR (|) between form option
constants, just as before.
You should not use the FORM_VIRTUAL or FORM_HIGHLIGHT options in
this function. The FormInitialize() function uses these options
to set up the form, and assumes the form will remain a virtual
or windowed form throughout the life of the form. The form
manager also assumes that the FIELD_HIGHLIGHT option remains the
same throughout the life of the form.
#include "cwlwin.h"
FORMPTR form;
/* ... skip other initializations ... */
main()
{
/* ... skip initializations ... */
form = FormInitialize( /* arguments to FormInitialize */ );
/* set form checking option */
FormSetOptions(form,0,FORM_CHECK_ON,1);
/* turn off form checking option */
FormSetOptions(form,0,FORM_CHECK_OFF,0);
}
Page 58 The C Window Library Page 58
If there are no errors, FormSetOptions() returns NO_ERROR.
If there are errors, FormSetOptions() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the form does not exist.
INVALID_FIELD_OPTION if FORM_VIRTUAL or FORM_HIGHLIGHT is used
as an option.
Page 59 The C Window Library Page 59
WRITING VALUES TO THE FIELD BUFFER
----------------------------------
You can write values to the field buffer as strings and have
them displayed immediately. This will be necessary if you want
to change a field's value if the field is not the current field
being edited. The FormWriteFieldValue() function does just
this. This function is an alternative to the FormPutFieldData()
function.
FormWriteFieldValue()
---------------------
The FormWriteFieldValue() writes a string to the field's input
buffer and displays the changes immediately. Here is the
prototype:
int FormWriteFieldValue(FORMPTR form, int entrynum, char *value)
The first and second arguments are the form and the field entry
number, respectively.
The third argument is the pointer to the string of characters to
write to the string buffer. The length of the string cannot
exceed the length of the field's input buffer. If you do not
know the length of the field buffer, you can use the
FIELD_BUFSIZE() macro.
#include "cwlwin.h"
main()
{
/*... Assume initializations are done ... */
FormWriteFieldValue(form,0,"45");
}
This writes a string "45" to the field's input buffer and
displays "45" on the form (if the field's position is visible on
the screen).
If there are no errors, FormWriteFieldValue() returns NO_ERROR.
If there are errors, FormWriteFieldValue() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 60 The C Window Library Page 60
SETTING FIELD PRE-FUNCTIONS
---------------------------
The C Window Library's form manager allows functions to be
called prior to inputting a field. This function is not limited
to just 'call a function and return to inputting' type of a
function that you may find in some other commercial or shareware
function libraries. The pre functions in The C Window Library
have the added power of telling the form manager what to do next
i.e. edit the current field, go to some other field, exit the
form, etc.
There are two ways of setting up a pre-input function. One way
is to define a global function that will be called for every
field in every form defined. The second way is to define a
pre-input function for each individual field in a particular
form.
Defining a global pre-functions
-------------------------------
You can define a function that will be performed prior to
inputting of every field in any form defined. The
CWLfield_prefunc function pointer points to this function. Here
is the prototype:
int (*CWLfield_prefunc)(FORMPTR form, int *entrynum)
The first argument is the pointer to the current active form.
The second argument is a pointer to an integer that represents
the current field number being edited. The reason for a pointer
and not the actual value will become apparent later on.
Defining a field specific pre-input functions
---------------------------------------------
The FormSetFieldPreFunction() defines a pre-input function for a
particular field in a form. Here is the prototype:
int FormSetFieldPreFunction(FORMPTR form, int entrynum,
int (*prefunc)(FORMPTR form, ]
int *entry))
The first argument is the pointer to the form, and the second
the field number to assign the function to.
The third argument is a pointer to the function that returns an
integer. The arguments to this function are the same as the
CWLfield_prefunc function pointer defined above.
Page 61 The C Window Library Page 61
Return Values to the Form Manager
---------------------------------
The CWLfield_prefunc and the function defined in the
FormSetFieldPreFunction() MUST return a value back to the form
manager. This return value tells the form manager what to do
next. Here is a list of the valid return values:
Option Definition
------ ----------
FIELD_PREVFIELD Move input cursor to the previous field
in the form and start editing from
there.
FIELD_NEXTFIELD Move input cursor to the next field in
the form and continue editing the next
field.
FIELD_CONTINUE_PROCESS Edit the input for the current field.
FIELD_PROCESS_DATA Process input that was already entered
in the field.
FORM_CLEAR Clear the form and move input cursor to
first available field.
FORM_ACCEPT Accept the current input in the form and
exit.
FIELD_NEWFIELD Move cursor to a new field and continue
editing from there.
FORM_CANCEL Do not accept any input that may have
been previously entered and quit
The FIELD_PREVFIELD return value will move the input cursor to
the previous field in the form. If you
try to move beyond the first available field on the form the
FORM_WRAP and/or the FORM_EXIT_INITIAL form options will take
action depending on whether they are on or off. See CREATING
FIELD ENTRIES for a definition of the FORM_WRAP and
FORM_EXIT_INITIAL options.
The FIELD_NEXTFIELD return value will move the input cursor to
the next field in the form. If you try to move beyond the first
available field in the form, the FORM_WRAP form option will take
action depending on whether this option was turned on.
The FIELD_CONTINUE_PROCESS return value will just let the form
manager edit the current field, just as if the pre-input
function was not called.
The FIELD_PROCESS_DATA return value will process whatever data
is residing the field's input buffer, and will not edit the
current field. You can place strings in the field input buffer
by calling the FormWriteFieldValue() function. The
Page 62 The C Window Library Page 62
FIELD_PROCESS_DATA will still right or left justify, comma
format, etc. whatever is in the field buffer, just as if it were
entered manually (edited).
The FORM_CLEAR return value clears the form of all input data
and moves the input cursor to the first available field.
The FORM_ACCEPT return value accepts all the input from the
input fields and exits. The form is not exited automatically if
the FORM_CHECK option is on or if a field in the form has the
FIELD_CHECK option on. See CREATING FIELD ENTRIES for a
definition of the FORM_CHECK and FIELD_CHECK options.
The FIELD_NEWFIELD return value moves the input cursor to the
field assigned to the pointer to the current entry. If you
remember, the pre-function prototype passed a pointer to the
current field number. If you assign a field number to the
dereferenced pointer and the FIELD_NEWFIELD return value is
used, the form manager will move the input cursor to the field
desired. If the field entry does not exist, the form manager
will not move the input cursor. If the field is protected
(FIELD_PROTECT flag is on) for the desired field, the input
cursor is not moved.
The FORM_CANCEL rejects all input and exits the form. The form
is not automatically exited if there is an exit function defined
for the form. Form exit functions are discussed later in the
manual.
If both the CWLfield_prefunc and an entry has a pre-input
function defined via the FormSetFieldPreFunction() function, the
CWLfield_prefunc is performed first. If the return value from
the global function is FIELD_CONTINUE_PROCESS, then the
pre-input function defined for the field is performed.
#include "cwlwin.h"
#include "menu.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NUMPROMPTS 5
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,35,"___",'_',1,3,FIELD_RJUSTIFY01,REVERSE,"3[0-9]",
CWL_STRING, 1, 35, "__________", '_', 0, 10, NO_FIELD_OPTIONS,
0,REVERSE, "10.",
CWL_LINTEGER,2, 35, "_________", '_', 2, 12,
FIELD_COMMA|FIELD_ZSUPPRESS2, 0,REVERSE, "9[0-9]",
CWL_DOUBLE,3, 20, "_______",'_',1,7, FIELD_COMMA|FIELD_LJUSTIFY,0,
REVERSE,"7[0-9/.]",
CWL_CHAR, 4, 20, "_", '_', 1, 1, FIELD_UPPERCASE, 0,REVERSE,
"[YyNn]",
FIELDEND};
FORMPTR form;
WPOINTER w, helpwin;
Page 63 The C Window Library Page 63
char *prompt[] = { "Enter an integer:",
"Choose a string:",
"Enter a large integer value:",
"Enter a double:",
"Enter Yes or No (Y/N):"};
char *help[] = {"Enter a value between 0 and 999",
"Use Up arrow or down arrow to make selection",
"Enter a value between 0 and 2,000,000",
"Enter a value with a decimal point",
"Enter a 'Y' for yes, 'N' for no"};
int display_help();
int get_choice();
int choose_list();
POPUP_MENU_ENTRY popup_entry[] = {"Choice 1",0,0,0,NULLFN,
"Choice 2",1,0,0,NULLFN,
"Choice 3",2,0,0,NULLFN,
"Choice 4",3,0,0,NULLFN,
"Choice 5",4,0,0,NULLFN,
"Choice 6",5,0,0,NULLFN,
"Choice 7",6,0,0,NULLFN,
CWL_NULL,-1};
POPUP_MENU_PTR popup;
unsigned menu_colors[NUMPOPUPCOLORS];
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
WindowInitDesktop(0);
menu_colors[ENTRYCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[BORDERCOLOR] =CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[HOTKEYCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,blue);
menu_colors[HIGHLIGHTCOLOR] =
CREATE_VIDEO_ATTRIBUTE(cyan,black);
menu_colors[UNAVAILCOLOR] =
CREATE_VIDEO_ATTRIBUTE(white,black);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt[i],i,0);
/* setup help window */
helpwin = WindowInitialize(DESKTOP_WINDOW,NOBORDER,24,0,78,1,
REVERSE,REVERSE,0);
popup = PopupCreateMenu(popup_entry,menu_colors,3,9,7,
NO_POPUP_OPTIONS,WNULLFN,VWNULLFN);
Page 64 The C Window Library Page 64
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
FormSetListField(form,1,popup);
/* set field pre-func of second field */
FormSetFieldPreFunction(form,1,get_choice);
/* display help window */
WindowDisplay(helpwin, 2, NOEFFECT);
/* get form info */
FormGetInput(form,1,0);
}
/* Displays help for each field */
int display_help(FORMPTR form, int *entry)
{
/* clear window and display appropriate help */
WindowClear(helpwin);
WindowWriteString(helpwin,help[*entry],0,0);
/* return value back to form manager */
return FIELD_CONTINUE_PROCESS;
}
The above example displays a help message for each input field.
Note that the display_help() function returns a
FIELD_CONTINUE_PROCESS to the form manager.
If there are no errors, FormSetFieldPreFunction() returns
NO_ERROR.
If there are errors, FormSetFieldPreFunction() returns one of
the following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 65 The C Window Library Page 65
SETTING FIELD POST FUNCTIONS
----------------------------
The C Window Library's form manager allows functions to be
called after inputting a field.
There are two ways of setting up a post-input function. One way
is to define a global function that will be called for every
field in every form defined. The second way is to define a
post-input function for each individual field in a particular
the form.
Defining a global post-function
-------------------------------
You can define a function that will be performed prior to
inputting of every field in any form defined. The
CWLfield_postfunc function pointer points to this function.
Here is the prototype:
int (*CWLfield_postfunc)(FORMPTR form, int *entrynum)
The first argument is the pointer to the current active form.
The second argument is a pointer to an integer that represents
the current field number being edited. The reason for a pointer
and not the actual value will become apparent later on.
Defining a field specific post-function
---------------------------------------
The FormSetFieldPostFunction() defines a post-input function for
a particular field in a form. Here is the prototype:
int FormSetFieldPostFunction(FORMPTR form, int entrynum,
int (*postfunc)(FORMPTR form, int *entry))
The first argument is the pointer to the form, and the second
the field number to assign the function to.
The third argument is a pointer to the function that returns an
integer. The arguments to this function are the same as the
CWLfield_postfunc function pointer defined above.
Return Values to the Form Manager
---------------------------------
The CWLfield_postfunc and the function defined in the
FormSetFieldPostFunction() MUST return a value back to the form
manager. This return value tells the form manager what to do
next. Here is a list of the valid return values:
Page 66 The C Window Library Page 66
Option Definition
------ ----------
FIELD_PREVFIELD Move input cursor to the previous
field in the form and start editing
from there.
FIELD_NEXTFIELD Move input cursor to the next field
in the form and continue editing the
next field.
FIELD_CONTINUE_PROCESS Continue processing the field
(display value entered in field
buffer from previous edit).
FIELD_PROCESS_DATA Same as FIELD_CONTINUE_PROCESS.
FORM_CLEAR Clear the form and move input cursor
to first available field.
FORM_ACCEPT Accept the current input in the form
and exit.
FIELD_NEWFIELD Move cursor to a new field and
continue editing from there.
FORM_CANCEL Do not accept any input that may have
been previously entered and quit
The above return values are the same as the return values for
pre-input function except for the FIELD_CONTINUE_PROCESS and
FIELD_PROCESS_DATA functions. FIELD_CONTINUE_PROCESS just
continues as if no post-input function was called.
FIELD_PROCESS_DATA has the same definition as
FIELD_CONTINUE_PROCESS.
If both the CWLfield_postfunc and an entry has a post-input
function defined via the FormSetFieldPostFunction() function,
the CWLfield_postfunc is performed first. If the return value
from the global function is FIELD_CONTINUE_PROCESS, then the
post-input function defined for the field is performed.
Here is an example of using the post-input functions:
#include <stdio.h>
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NUMPROMPTS 3
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,35,"___",'_',1,3,FIELD_RJUSTIFY,0,REVERSE,"3[0-9]",
CWL_INTEGER,1,35,"___",'_',1,3,FIELD_RJUSTIFY,0,REVERSE,"3[0-9]",
CWL_INTEGER,2,35,"___",'_',1,3,FIELD_RJUSTIFY,0,REVERSE,"3[0-9]",
CWL_INTEGER,3,35,"___",'_',1,3,FIELD_RJUSTIFY,0,REVERSE,"3[0-9]",
CWL_INTEGER,4,35,"____",'_',1,4,FIELD_RJUSTIFY|FIELD_PROTECT,0,
REVERSE,"4[0-9]",
FIELDEND};
Page 67 The C Window Library Page 67
FORMPTR form;
WPOINTER w, helpwin;
char *prompt = "Enter a number between 0 and 999:";
char *totstr = "Current Total :";
int display_total();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
/* write prompts to the form window */
for (i=0;i<=NUMPROMPTS;i++)
WindowWriteString(w,prompt,i,0);
WindowWriteString(w,totstr,4,0);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* set global post-function */
CWLfield_postfunc = display_total;
/* get form info */
FormGetInput(form,1,0);
}
/* call total function */
int display_total(FORMPTR form, int *entry)
{
int i,total=0,num;
for (i=0;i<4;i++)
{
FormGetFieldData(form,i,&num);
total+=num;
}
FormPutFieldData(form,4,total);
return FIELD_CONTINUE_PROCESS;
}
The above example displays a running total of four input fields.
The total is displayed in the fifth input field. Note the return
value of FIELD_CONTINUE_PROCESS, which informs the form manager to
carry on as if no post-input function had been call.
If there are no errors, FormSetFieldPostFunction() returns
NO_ERROR.
If there are errors, FormSetFieldPostFunction() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Page 68 The C Window Library Page 68
UNDEFINED KEYSTROKE PROCESSING
------------------------------
Another powerful feature of the form library is that you can
call a function for keys that are not in the current key
definitions. For instance, say you want the Tab key and the
down arrow to mean accept the input and go to the next field.
Since there is only room for one definition for accept input,
you can write a function that checks for the Tab key, and return
a value to the form manager as to what action to take.
The CWLform_undef_fkey_func and CWLform_undef_akey_func function
pointers
--------
There are two global variables, CWLform_undef_fkey_func and
CWLform_undef_akey_func. These two variables are pointers to
functions that return an integer. By setting these functions to
point to your own functions, you can process undefined
keystrokes yourself and return to the form manager what action
to take.
The CWLform_undef_fkey_func is used to define keys that are not
normal ASCII keys. For instance, Control key and Alt key
combinations, the F-keys, PgDn and PgUp, etc. The
CWLform_undef_akey_func is used to define normal ASCII keys
(keys with ASCII values between 32 and 255, inclusive).
Whenever an undefined key is encountered, the form manager will
pass the current FORMPTR, current field entry (as an integer),
the string that has been currently entered, the current key
pressed, and the current position number of the character being
processed to your function. The prototype for this function is
as follows:
int (*CWLform_undef_fkey_func)(FORMPTR form, /* current form */
int entry, /* current field */
char *str,/* string currently entered */
int key, /* key that was pressed */
int *pos) /* position number of current
character being processed */
The prototype to the CWLform_undef_akey_func is similar to the
one above. The str is a pointer to a null-terminated string of
characters that has been currently entered. For instance, if
the string currently entered is
ABC123
str will point to "ABC123". The key value is the key that was
pressed. You should use the values defined in the header file
"keycodes.h" if you want to check for non-ascii keys. This will
ensure that you are properly checking the keystroke desired.
For instance, if you want to check if the key pressed was the
Page Up key, use the constant PGUP defined in keycodes.h.
Page 69 The C Window Library Page 69
The pos argument is a pointer to an integer that denotes the
number of the current character that the cursor is on. The
first character is at position number 0, the second character in
the input field is 1, etc. If there is an input mask the
position number does not include any characters that are used to
create the non-input positions. For instance:
"__/__/__ "
01 23 45
The numbers under the mask are the position numbers for each
character. The reason why the pos argument is a pointer, and
not a regular integer will be defined later.
Specifying when to call an undefined key function in a Regular
Expression
----------
An empty bracketed simple regular expression tells the form
manager to call the undefined keystroke function. An example of
this type of regular expression is as follows:
Regular Definition
Expression ----------
----------
[A-Z][] The first input position must be
between 'A' and 'Z', and the second
position will automatically call
the user defined undefined
keystroke function.
20[] All twenty input positions will
call the undefined keystroke
function.
3[0-9]2[]2[A-Z] The first three input positions
must be between '0' and '9', the
next two input positions
automatically call the undefined
keystroke function, and the last two
positions must be between 'A' and 'Z'.
If you use this form of a regular expression, you MUST have
defined an undefined keystroke function. If you did not define
one, you will more than likely get into an infinite loop. Using
this form of regular expression combined with the return values
(defined below) that can be returned to the input manager, you
will virtually have total control of the way the input is
handled.
Return Values To The Form Manager
---------------------------------
When writing your function you must return an integer to the
form manager. This integer will inform the form manager as to
Page 70 The C Window Library Page 70
what action to take. Here are a list of the return values and
what they inform the form manager:
Return Action to
Value Take
------ ---------
FIELD_CONTINUE Do not Process keystroke and continue
getting input.
FIELD_MOVELEFT Move cursor left in field.
FIELD_MOVERIGHT Move cursor right in field.
FIELD_DELNOMOVE Delete character at cursor.
FIELD_INSTOGGLE Toggle Insert/Overwrite mode.
FIELD_BACKSPACE Destructive Backspace.
FIELD_ACCEPT Accept Input and go to next field.
FIELD_ACCEPTDEFAULT Accept default field string and return.
FIELD_ERASEINPUT Erase Input and go to first character in
the field.
FIELD_GOTOFIRST Go to first input character in field.
FIELD_GOTOLAST Move cursor to last input character in
field.
FIELD_INSERTCHAR Accept character as valid and insert it
at the current cursor position.
FIELD_NEXTFIELD Accept input and go to the next field in
the form.
FIELD_PREVFIELD Accept input and go to the previous
field.
FORM_ACCEPT Accept all input in the form and exit
form.
FORM_CLEAR Clear the form and move input to first
available field entry.
FORM_CANCEL Do not accept any input that may have
been previously entered and quit
editing.
FIELD_MOVE_TO_CHARACTER Move cursor to input position
specified in the *pos argument.
The FIELD_MOVE_TO_CHARACTER return value moves the input cursor
to the position in the input string specified in the fourth
Page 71 The C Window Library Page 71
argument of CWLform_undef_akey_func or CWLform_undef_fkey_func.
If you recall, the fourth argument was a pointer to an integer.
You can assign a value to the *pos argument in your user defined
function, and then return a FIELD_MOVE_TO_CHARACTER return code
to move the input cursor to the desired input position.
These user-defined functions can do anything, not just process
keystrokes. For instance, if you want F1 to be a help key,
where the help function is in a function called do_help() you
must make sure that:
a) the F1 key is undefined (not defined in the CWLform_edit_key
array)
b) the CWLform_undef_fkey_func function pointer points to your
function c) return an integer to the form manager from your
function.
Here is a typical way that this would be set up:
#include "window.h"
/* ... Other #includes and #defines */
int do_help(); /* define help function */
main()
{
WindowInitializeSystem();
FormInitializeSystem();
/* ...Some code */
CWLform_undef_fkey_func = do_help; /* point function pointer
to do_help */
FormGetInput(/* ... Parameters */); /* call input
function */
/* ... Other code */
}
int do_help(FORMPTR form, int entry, char *str, int ch, int pos)
{
if (ch == F1) /* check for F1 */
{
/* help function goes here */
}
return FIELD_DONT_PROCESS; /* make sure form manager does not
process this or any other undefined
keystroke */
}
With this flexibility in the input functions, you can totally
control how input is handled.
Page 72 The C Window Library Page 72
PROCESSING EDITING ERRORS
-------------------------
There are two categories of errors that The C Window Library
checks for when editing a field in a form. The first category
includes checking to see if enough characters have been entered
into the field and to make sure the input matches the regular
expression.
The second category are errors that occur when the field is
checked to see if the data entered falls in a valid range, the
name entered is found in a database of some type, etc. namely
the errors that The C Window Library cannot check for
internally, only you (the programmer) knows whether the data
entered is valid.
This section deals with the first category of errors.
Minimum Number of Characters Error Checking
-------------------------------------------
The C Window Library internally checks to see if the number of
characters entered manually into a field (not data written to
the field using the FormWriteFieldValue() function) is enough to
satisfy the minimum number of characters that must be entered
for the field. As stated before, the minimum number of
characters expected is initialized in the FIELD_ENTRY structure.
Overriding Error Checking for Minimum number of characters
----------------------------------------------------------
You can override checking the number of characters entered by
turning on one or both of the override options,
FIELD_OVERRIDE_FORWARD and FIELD_OVERRIDE_BACKWARD. The
FIELD_OVERRIDE_FORWARD overrides checking when the field is
exited with a forward (toward the last field in the form)
advance. The FIELD_OVERRIDE_BACKWARD overrides checking when
the field is exited with a backward advance (toward the first
field in the form). As stated in previous sections,
FormSetFieldOptions() turns on or turns off field options. Some
useful purposes of overriding the number of characters entered
error checking is to allow the user to move to a previous field
so that it can be changed, without having to enter some data in
the current field. Here is an example of using this technique
with the FIELD_OVERRIDE_BACKWARD option.
#include "cwlwin.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NUMPROMPTS 8
Page 73 The C Window Library Page 73
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
CWL_INTEGER,1,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
CWL_INTEGER,2,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
CWL_INTEGER,3,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
CWL_INTEGER,4,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
CWL_INTEGER,5,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
CWL_INTEGER,6,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
CWL_INTEGER,7,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,0,REVERSE,
"3[0-9]",
FIELDEND};
FORMPTR form;
WPOINTER w;
char *prompt = "Enter a number :";
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i,0);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* get form info */
FormGetInput(form,1,0);
}
The example above allows the user to edit a previous field even
though the field may not contain any characters. The
FIELD_OVERRIDE_BACKWARD option allows us to override the minimum
number of characters error check.
Checking if Field Characters Match Regular Expression
-----------------------------------------------------
Another check that is done internally is to see if each
character entered matches the corresponding regular expression
character.
Page 74 The C Window Library Page 74
This check is only done automatically if the FIELD_CHECKREGEXP
or FIELD_CHECKREGEXP_IGNORECASE options are turned on. The way
these two options work are exactly the same as the CHECKREGEXP
and CHECKREGEXP_IGNORECASE options work for single input fields
in the WindowGet...() family of functions. See page 6 for more
details on these options.
Calling a User Written Function when errors occur
-------------------------------------------------
You can set up a function that will be called if any of the
fields fail the minimum number of entered characters test or the
regular expression error test by pointing the CWLedit_error_func
function pointer to a user-written function. Here is the
prototype to this function pointer:
int (*CWLedit_error_func)(FORMPTR form, int entrynum,
int errtype, char *str, int errval)
The first argument is a pointer to the form of where the error
occurred.
The second argument is the number of the offending field entry.
The third argument is the type of error that occurred. If the
error occurred because the minimum number of characters were not
entered, this value is the constant FIELD_MINCHARS_ERROR. If
the error was caused because the input conflicts with the
regular expression, this value is the constant
FIELD_REGEXP_ERROR.
The fourth argument is the string that was entered in the field.
The fifth argument depends on the type of error. If the error
is a FIELD_MINCHARS_ERROR error, this value is the minimum
number of characters expected. If the error is a
FIELD_REGEXP_ERROR error this value is the position in string
that does not match the regular expression. Position numbers in
the string start from 0.
Return Values for User Written Function
---------------------------------------
You MUST return a value back to the form manager if your
user-defined error function is called. There are two possible
return values, FIELD_ERROR and FIELD_ACCEPT. FIELD_ERROR tells
the form manager to edit the field again i.e. let the user
correct his/her error. The FIELD_ACCEPT return value accepts
the input, even though there is an error.
Here is an example:
#include <stdio.h>
#include "cwlwin.h"
Page 75 The C Window Library Page 75
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define WHITEONRED CREATE_VIDEO_ATTRIBUTE(RED_,WHITE_)
#define NUMPROMPTS 8
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,1,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,2,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,3,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,4,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,5,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,6,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,7,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
FIELDEND};
FORMPTR form;
WPOINTER w, error_win;
char *prompt = "Enter a number :";
int display_error();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
error_win =
WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,WHITEONRED,
WHITEONRED, SINGLEBOX);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i,0);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* initialize error function */
CWLedit_error_func = display_error;
/* get form info */
FormGetInput(form,1,0);
}
Page 76 The C Window Library Page 76
/* This is called if there is an editing error */
int display_error(FORMPTR form, int entry, int errval,
char *str, int pos)
{
char buf[80];
WindowClear(error_win);
switch (errval)
{
case FIELD_MINCHARS_ERROR: /* not enough characters */
sprintf(buf,
"You must enter at least %d characters in this field",pos);
break;
case FIELD_REGEXP_ERROR: /* regular expression error */
sprintf(buf,"Invalid character entered in position %d",pos);
break;
}
/* display window and return to form manager */
WindowWriteCenterString(w,buf,2);
WindowWriteCenterString(error_win,
"Press Any Key to Continue...",4);
WindowDisplay(error_win,1,EXPLODE);
MakeSound(300,500);
GET_KEY();
WindowHide(error_window,CONTRACT);
return FIELD_ERROR;
}
If the CWLedit_error_func points to a NULLFN, no function is
called.
Page 77 The C Window Library Page 77
USER DEFINED ERROR CHECKING
---------------------------
This section discusses the way to have a user-defined error
checking function. This function checks errors that The C Data
Forms Library could not possibly do internally. This includes
checking the input for valid names, passwords, etc.
The FormSetFieldValidateFunction() function
-------------------------------------------
The FormSetFieldValidateFunction() allows the programmer to
assign a validation function to a field. Here is the prototype:
int FormSetFieldValidateFunction(FORMPTR form, int entrynum,
int (*func)(FORMPTR cform,
int centry,
char *str))
The first argument is the pointer to a form. The second
argument is the entry number to assign the function to.
The third argument is a pointer to the user-defined function.
This function should allow three arguments. The first and
second are the pointer to the form, and the field entry number.
The last argument is the string entered in the field.
Return Values for the user defined error function
-------------------------------------------------
You MUST return a value back to the form manager if your
user-defined validation function is called. There are two
possible return values, FIELD_ERROR and FIELD_ACCEPT.
FIELD_ERROR tells the form manager that there was an error, and
to edit the field again i.e. let the user correct his/her error.
The FIELD_ACCEPT return value accepts the input as valid.
#include <stdio.h>
#include "cwlwin.h"
#include <stdlib.h>
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define WHITEONRED CREATE_VIDEO_ATTRIBUTE(RED_,WHITE_)
#define NUMPROMPTS 8
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,1,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,2,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,3,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,4,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,5,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,6,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,7,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
FIELDEND};
Page 78 The C Window Library Page 78
FORMPTR form;
WPOINTER w, error_win;
char *prompt = "Enter a number :";
int display_error();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
error_win =
WindowInitialize(DESKTOP_WINDOW,BORDER,9,0,78,8,WHITEONRED,
WHITEONRED,SINGLEBOX);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i,0);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* initialize validation function */
for (i=0;i<NUMPROMPTS;i++)
FormSetFieldValidateFunction(form,i,check_range);
/* get form info */
FormGetInput(form,1,0);
}
/* This is called to check the range */
int check_range(FORMPTR form, int entry, char *str)
{
int num;
WindowClear(error_win);
num = atoi(str);
/* check and display error window if out of range */
if (num < 1 || num > 500)
{
WindowPrintf(error_win,
"The number entered %s, must be between %d and %d",
str,LOWLIM,HILIM);
WindowWriteCenterString(error_win,
"Press Any Key to Continue...",4);
WindowDisplay(error_win,1,EXPLODE);
MakeSound(300,500);
Page 79 The C Window Library Page 79
GET_KEY();
WindowHide(error_win,CONTRACT);
/* re-edit this field */
return FIELD_ERROR;
}
else
/* field OK */
return FIELD_ACCEPT;
}
The above example tests each field to make sure the input falls
between 1 and 500. If not, an error window is displayed and
FIELD_ERROR is returned to the form manager. If the field is in
range, FIELD_ACCEPT is returned to the form manager.
There is a better way to check if a field is included in a range
of values. This will be discussed later in the
FormCheckFieldRange() function.
If there are no errors, FormSetFieldValidateFunction() returns
NO_ERROR.
If there are errors, FormSetFieldValidateFunction() returns one
of the following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
FormCheckFieldRange()
---------------------
The FormCheckFieldRange() checks if a field's input falls within
the range of two values. These values can be any data type,
except doubles (doubles are handled with a separate function).
Here is the prototype:
int FormCheckFieldRange(FORMPTR form, int entrynum, int
options, ...)
Note the last argument. The prototype suggests that the
argument is optional, but not really. The '...' means that
there are two values expected. The first value is the lower
limit, and the second value is the upper limit. These values
can be of any simple data type, (char, int, unsigned, etc.) as
well as two string.
The first two arguments are the pointer to the form and the
field entry number, respectively. The third arguments are range
options to use. Here are the list of range options:
Page 80 The C Window Library Page 80
Range Option Definition
------------ ----------
INCLUDE_LOW Includes the lower limit as valid.
INCLUDE_HIGH Includes the upper limit as valid.
EXCLUDE_LOW Excludes the lower limit as valid.
EXCLUDE_HIGH Excludes the upper limit as valid.
NO_RANGE_OPT No range options (use default).
INCLUDE_LOW includes the lower limit in the range check as being
a valid number.
INCLUDE_HIGH includes the upper limit in the range check as
being a valid number.
EXCLUDE_LOW does not accept any value that is equivalent to the
lower limit.
EXCLUDE_HIGH does not accept any value that is equivalent to the
upper limit.
NO_RANGE_OPT uses the default (INCLUDE_LOW | INCLUDE_HIGH).
Note that the bitwise OR (|) can be used to combine options.
INCLUDE... options override EXCLUDE... options if they are both
used simultaneously.
Here are a few examples of using FormCheckFieldRange():
a) FormCheckFieldRange(form,0,NO_RANGE_OPT,100,200)
b) FormCheckFieldRange(form,1,NO_RANGE_OPT,-1, 50)
c) FormCheckFieldRange(form,3,EXCLUDE_LOW,'a','z')
d) FormCheckFieldRange(form,2,NO_RANGE_OPT,"abc","def");
a) Tests if the value entered in field 0 is between 100 and 200,
inclusive.
b) Tests if the value entered in field 1 is between -1 and 50,
inclusive.
c) Tests if the single value entered in field 1 is
between 'a' and 'z', but not including 'a'.
d) Tests if the string entered is between "abc" and "def"
inclusive.
When the test is made, a value is returned that tells how the
test turned out.
Value returned Definition
-------------- ----------
FIELD_LOW Field value is too small.
FIELD_HIGH Field value is too large.
FIELD_OUT_OF_RANGE Field is either too small or too
large.
FIELD_OK Field is in range.
Page 81 The C Window Library Page 81
If there are no errors, FormCheckFieldRange() returns one of the
values above.
If there are errors other than the ones mentioned above,
FormCheckFieldRange() returns one of the following and sets
window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 82 The C Window Library Page 82
CLEARING A FORM
---------------
FormClear()
-----------
You can clear a form of all input and move the input cursor to
any field using the FormClear() function. Here is the
prototype:
int FormClear(FORMPTR form, int entry)
The first argument is the pointer to the form, and the second
argument is the entry to place the input cursor when the form is
cleared. If the entry is protected, the form manager tries to
find the next available field. The number of characters that is
cleared is determined by the visible width of the input field.
If there is no error, FormClear() returns NO_ERROR.
If there are errors FormClear() returns the following and sets
window_error_code to this value:
UNDEFINED_FORM if the FORMPTR does not exist.
Page 83 The C Window Library Page 83
EXITING A FORM
--------------
When the last input field is edited, or the form is exited
prematurely, an exit function can be called before the form is
actually closed.
FormSetExitFunction()
---------------------
The FormSetExitFunction() sets up a function that will be called
whenever a form is exited. Here is the prototype:
int FormSetExitFunction (FORMPTR form,
int (*exit_func)(FORMPTR cform,
int status,
int *currfield))
The first argument is the pointer to the form. The second
argument is the pointer to a user-defined exit function. This
function is passed three arguments from the form manager.
The first argument is the current form. The second argument is
a status indicator that tells how the form was exited (last
field was exited, first field was exited etc.). Here are the
list of status codes:
Status Code Definition
----------- ----------
FIRST_FIELD_EXIT Form was exited by moving the
input cursor to a field before
the first available field in a
form.
LAST_FIELD_EXIT Form was exited by moving the
input cursor to a field after
the last available field.
FORM_END Form exited and saved by other
means i.e. an accept key was hit
in the middle of the form or An
'OK' button was activated.
FORM_CANCEL Form exited and potentially
cancelled in the middle of the
form.
The third argument is a pointer to an entry number. The
user-defined exit function MUST return a value back to the form
manager. Here is a list of the valid return values:
FORM_END_PROCESS - End processing of the form.
FORM_REEDIT - Reedit the form starting at the entry number
assigned to the pointer *currfield.
The FORM_END_PROCESS value ends the processing of the fields.
Page 84 The C Window Library Page 84
The FORM_REEDIT value tells the form manager to collect input
again in the form, but start at the number assigned to
*currfield.
#include <stdio.h>
#include "cwlwin.h"
#include <stdlib.h>
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define WHITEONRED CREATE_VIDEO_ATTRIBUTE(RED_,WHITE_)
#define NUMPROMPTS 8
#define LOWLIM 1
#define HILIM 200
FIELD_ENTRY field_array[] =
{CWL_INTEGER,0,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,1,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,2,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,3,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,4,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,5,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,6,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
CWL_INTEGER,7,35,"___",'_',1,3,NO_FIELD_OPTIONS,0,REVERSE,"3[0-9]",
FIELDEND};
FORMPTR form;
WPOINTER w, error_win, again_win;
char *prompt = "Enter a number :";
int check_range();
int edit_again();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowInitDesktop(0);
w = WindowInitialize(DESKTOP_WINDOW,BORDER,0,0,78,22,NORM,
NORM,SINGLEBOX);
error_win =
WindowInitialize(DESKTOP_WINDOW,BORDER,9,0,78,10,WHITEONRED,
WHITEONRED,SINGLEBOX);
again_win =
WindowInitialize(DESKTOP_WINDOW,NOBORDER,24,0,80,1,
REVERSE,REVERSE,0);
WindowWriteString(again_win,
"Enter a field to edit or ENTER to exit the form",0,0);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i,0);
Page 85 The C Window Library Page 85
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* initialize exit function */
FormSetExitFunction(form,edit_again);
FormSetFieldOptions(form,0,FIELD_PROTECT,1);
/* initialize validation function */
for (i=0;i<NUMPROMPTS;i++)
FormSetFieldValidateFunction(form,i,check_range);
/* get form info */
FormGetInput(form,1,0);
}
/* This is called if there is an editing error */
int check_range(FORMPTR form, int entry, char *str)
{
int num;
WindowClear(error_win);
num = atoi(str);
/* check and display error window if out of range */
if (num < LOWLIM || num > HILIM)
{
WindowPrintf(error_win,"The number entered %s is out of range\n"
"The number must be between %d and %d",
str,LOWLIM,HILIM);
WindowWriteCenterString(error_win,
"Press Any Key to Continue...",4);
WindowDisplay(error_win,1,EXPLODE);
MakeSound(300,500);
GET_KEY();
WindowHide(error_win,CONTRACT);
/* re-edit this field */
return FIELD_ERROR;
}
else
/* field OK */
return FIELD_ACCEPT;
}
/* ask user whether they want to re-edit the form */
int edit_again(FORMPTR form, int status, int *entry)
{
char buf[3];
int num;
buf[0] = 0;
WindowDisplay(again_win,1,NOEFFECT);
Page 86 The C Window Library Page 86
/* loop until user has a viable entry or hits return */
do
{
WindowGetString(again_win,0,49,buf,'_',0,2,NO_OPTIONS,0,
"2[0-9]");
num = atoi(buf);
} while (!((num >= 1 && num <= NUMPROMPTS) || buf[0] == 0));
WindowHide(again_win,NOEFFECT);
/* return hit, so quit */
if (buf[0] == 0)
return FORM_END_PROCESS;
else
{
/* assign entry number and return */
*entry = num - 1;
return FORM_REEDIT;
}
}
The example above makes use of the exit function by asking the
user whether he/she wants to edit another field. If the field
number entered is in range, edit_again() returns a FORM_REEDIT
to the form manager, as well as assigns the appropriate field
number.
If the field number that is assigned to *entry is out of bounds,
the form manager will always start editing input from the first
available field.
If there is no error, FormSetExitFunction() returns NO_ERROR.
If there are errors FormSetExitFunction() returns the following
and sets window_error_code to this value:
UNDEFINED_FORM if the FORMPTR does not exist.
Page 87 The C Window Library Page 87
DISPOSING OF A FORM
-------------------
If a form is no longer needed, all memory allocated to the form
should be returned to the heap.
FormClose()
-----------
The FormClose() function deallocates all memory allocated to the
form, and makes the FORMPTR invalid. Here is the prototype:
int FormClose(FORMPTR form)
The only argument is the pointer to the form. Once this
function is called, the FORMPTR cannot be used unless it is
assigned to a valid form.
If there is no error, FormClose() returns NO_ERROR.
If there are errors FormClose() returns the following and sets
window_error_code to this value:
UNDEFINED_FORM if the FORMPTR does not exist.
Page 88 The C Window Library Page 88
USING A MOUSE
-------------
Using the mouse
---------------
You can now use a Microsoft compatible mouse to go from field to
field by clicking the left mouse button on any unprotected
field. You can also move the cursor within a field using the
mouse.
Setting up to use the mouse
---------------------------
To use the mouse, you must do three things.
b) Call MouseInitializeSystem().
c) Call the FormSetMouse() function.
The MouseInitializeSystem() function is described in The C
Window Library manual. It must be called with
MOUSE_FULL_INSTALL as the first argument for the mouse to be
used with Data Forms.
Once this is done, a call to FormSetMouse() must be made after
the form is initialized with FormInitialize(). Here is the
prototype to this function:
int FormSetMouse(FORMPTR form, int opt)
The first argument is the form to set the mouse for, and the
second argument is whether the mouse is to be turned on or off
for the form. If the second argument is TRUE, the mouse can be
used. If the argument is FALSE, the mouse is disabled for the
form. If MouseInitializeSystem() is called, the mouse will
still be visible even if it cannot be used for a form.
Remember to call MouseRestoreSystem() before your application
terminates.
FormSetMouse() returns NO_ERROR if there are no errors. If
there is an error, UNDEFINED_FORM is returned.
Going from field to field with the mouse
----------------------------------------
Once the form is activated with FormGetInput(), you can use a
mouse to go from field to field. There are some things that you
must be aware of though.
Page 89 The C Window Library Page 89
If a field has a minimum number of characters that must be
entered before moving to another field, the mouse WILL NOT move
the input cursor out of the field until the minimum number of
characters is entered. The only thing that can override this
are the FIELD_OVERRIDE...() macros defined in The C Data Forms
manual.
If the field type is CWL_SUBFORM, you cannot access the parent
form with the mouse even if both forms are visible on the
screen. The parent form is the form that called the subform.
As of this version, the mouse can only be used in one form at a
time. If you want to exit the subform so that you can go back
to the parent form, you should create a CWL_BUTTON field in the
subform that when selected will close the subform and return to
the parent form.
If the field is a CWL_TOGGLE field, clicking the mouse will
accept the current choice that is displayed.
If the field is a CWL_BUTTON field, clicking the mouse will
accept the action of the CWL_BUTTON field.
If the field is a RADIO field, clicking the mouse will choose
whatever active radio entry that the mouse is on. The prompt
string for the RADIO_ENTRY determines where the mouse will be
sensed for each RADIO_ENTRY. In other words, if your prompt
string is "Files Menu" and this is located at (1,1) of the form,
the mouse will be sensed for this RADIO_ENTRY when it falls in
the prompt's area on the screen, which is row 1 and columns 1
through 10 of the form window.
CWL_CHECKBOX fields work the same as the CWL_RADIO fields except
that clicking the mouse will toggle the field on or off.
If the field type is one of the 'normal' fields, i.e.
CWL_STRING, CWL_INTEGER, CWL_DOUBLE, CWL_CHAR, etc. The cursor
can be moved to different parts of the input field by clicking
the mouse in a different location in the input field.
If the mouse is clicked on a PROTECTed field, or in an area of
the form that is not occupied by any fields, nothing happens and
the input continues. In a future release, you will be able to
act on this 'errant' mouse click before Data Forms takes over.
Changing the mouse defaults
---------------------------
By default, the left mouse button is held down when moving form
between fields. If you prefer a different button to be used to
move the input cursor, you can change the button by changing the
following global variable:
Page 90 The C Window Library Page 90
int CWLfield_button_press - holds the current button to be
used to move the input cursor in
a form.
The following constants can be assigned to this variable:
Constant Definition
-------- ----------
MOUSELEFT_PRESS Left button.
MOUSERIGHT_PRESS Right button.
MOUSEMIDDLE_PRESS Middle button.
By default, CWLfield_button_press is assigned MOUSELEFT_PRESS.
Here is an example of changing this variables:
#include "cwlwin.h"
main()
{
...
MouseInitializeSystem( /* arguments */ );
FormInitializeSystem();
/* change mouse menu buttons */
CWLfield_button_press = MOUSERIGHT_PRESS;
...
}
field_button_press is assigned their default values when
MouseInitializeSystem() is called. If you want to change
this variables, make sure that the change is made after
calling MouseInitializeSystem() and FormInitializeSystem().
Page 91 The C Window Library Page 91
MISCELLANEOUS FORM FUNCTIONS
----------------------------
FormGetFieldString()
--------------------
The FormGetFieldString() returns the input entered in the field
buffer. Here is the prototype:
int FormGetFieldString(FORMPTR form, int entry, char *buffer)
The first two arguments are the FORMPTR and field entry number.
The third argument is the pointer to a buffer that the field
data will be copied to. The buffer must be large enough to hold
the string plus 1 for the null byte.
If there is no error, FormGetFieldString() returns NO_ERROR.
If there are errors, FormGetFieldString() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
FormGetFieldRowCol()
--------------------
The FormGetFieldRowCol() function returns the coordinates of a
field in a viewport. This function is useful if you have a
virtual form, and want to know where the field is located in the
viewport, and not the virtual window. Here is the prototype:
int FormGetFieldRowCol(FORMPTR form, int entry, unsigned *row,
unsigned *col)
The *row and *col arguments are pointers to integers that will
store the row and column of the field, respectively.
Since virtual forms can scroll left, right, up, or down,
depending on where the field is, this function can be useful to
pinpoint where the field is located in the viewport. If the
form is a simple windowed form, *row and *col will just contain
the row and column of the field when initialized.
If there is no error, FormGetFieldRowCol() returns NO_ERROR.
If there are errors, FormGetFieldRowCol() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
FIELD_NOT_IN_VIEW if the field is not currently displayed in the
viewport. If this error occurs, *row and *col are invalid and
should not be used.
Page 91 The C Window Library Page 91
FORM MACROS
-----------
Most of these macros use individual FIELD_ENTRY's as an
argument. You should use the GET_FIELD_FROM_FORM() macro to get
individual field entries from a form. An example will follow
the first two macro definitions to illustrate how to get an
individual FIELD_ENTRY.
GET_FIELD_FROM_FORM(form,entry) - returns the FIELD_ENTRY for a
form. This macro simplifies
getting individual FIELD_ENTRY's
from an array of field entries.
FIELD_PROTECT_ON(entry) - returns 1 if the FIELD_ENTRY
entry has the FIELD_PROTECT option
on, 0 otherwise.
Example:
FIELD_ENTRY fields[] = { /* ... List of field entries ... */};
/* other stuff */
FORMPTR form;
main()
{
int is_on;
FIELD_ENTRY fe;
.
.
.
/* Here is one way to get the third FIELD_ENTRY in the
fields array */
fe = fields[2]; /* Gets the third field entry in array fields */
is_on = FIELD_PROTECT_ON(fe);
/* Here is another way to get the third field entry, given that the
form exists and it was initialized with the fields array */
fe = GET_FIELD_FROM_FORM(form,2);
is_on = FIELD_PROTECT_ON(fe);
}
Page 92 The C Window Library Page 92
Remember when accessing FIELD_ENTRY's directly from the array, the
first FIELD_ENTRY is 0, the second is FIELD_ENTRY 1, etc.
FIELD_COMMA_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_COMMA option on, 0 otherwise.
FIELD_RJUSTIFY_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_RJUSTIFY option on, 0
otherwise.
FIELD_LJUSTIFY_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_LJUSTIFY option on, 0
otherwise.
FIELD_UPPERCASE_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_UPPERCASE option on, 0
otherwise.
FIELD_LOWERCASE_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_LOWERCASE option on, 0
otherwise.
FIELD_CHECKSPACES_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_CHECKSPACES option on, 0
otherwise.
FIELD_ENHANCEDKEY_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_ENHANCEDKEY option on, 0
otherwise.
FIELD_CHECKREGEXP_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_CHECKREGEXP option on, 0
otherwise.
FIELD_AUTORETURN_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_AUTORETURN option on, 0
otherwise.
FIELD_CHECKREGEXP_IGNORECASE_ON(entry) - returns 1 if the
FIELD_ENTRY entry has the
FIELD_CHECKREGEXP_IGNORECASE
option on, 0 otherwise.
FIELD_FLUSHBUFFER_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_FLUSHBUFFER option on, 0
otherwise.
FIELD_HOMECURSOR_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_HOMECURSOR option on,
0 otherwise.
FIELD_ZSUPPRESS1_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_ZSUPPRESS1 option on,
0 otherwise.
FIELD_ZSUPPRESS2_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_ZSUPPRESS2 option on,
0 otherwise.
Page 93 The C Window Library Page 93
FIELD_PASSWORD_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_PASSWORD option on, 0 otherwise.
FIELD_OVERRIDE_FORWARD_ON(entry) - returns 1 if the FIELD_ENTRY
entry has the
FIELD_OVERRIDE_FORWARD option on, 0
otherwise.
FIELD_OVERRIDE_BACKWARD_ON(entry) - returns 1 if the FIELD_ENTRY
entry has the
FIELD_OVERRIDE_BACKWARD option on,
0 otherwise.
FIELD_CLEARFIELD_ON(entry) - returns 1 if the FIELD_ENTRY entry
will be cleared if the first key
hit in this field is a key
recognized by the field's regular
expression.
FORM_DIRECTION(form) -
returns FORM_FORWARD if the user is moving the input cursor
towards the last field in the form, FORM_BACKWARD if the
user is moving the form input cursor toward the first
field. If the FORM_WRAP option is on, FORM_DIRECTION()
does not change if the form has wrapped to the first or
last available field.
This macro is useful if you want to invoke a pre or post-input
function only if the user is moving toward the last field and not
if they are going toward the first field.
FORM_EXPLODE_TYPE(form) - returns what type of special effect will
be used when the form window is displayed
or hidden. You can also assign values to
this macro. The default value is NOEFFECT.
Example: FORM_EXPLODE_TYPE(form) = EXPLODE;
FORM_WRAP_ON(form) - returns 1 if the FORM_WRAP option is on, 0
otherwise.
FORM_CHECK_ON(form) - returns 1 if the FORM_CHECK option is on, 0
otherwise.
FORM_EXIT_INITIAL_ON(form) - returns 1 if the FORM_EXIT_INITIAL
option is on, 0 otherwise.
FORM_HIGHLIGHT_ON(form) - returns 1 if the FORM_HIGHLIGHT option is
on, 0 otherwise.
FORM_VIRTUAL_ON(form) - returns 1 if the form is a virtual form, 0
otherwise.
FORM_NOEXIT_LAST_ON(form) - returns 1 if the FORM_NOEXIT_LAST
option is on, 0 otherwise.
Page 94 The C Window Library Page 94
FORM_STATIC_ON(form) - returns 1 if the FORM_STATIC option is on, 0
otherwise.
FORM_WINDOW(form) - returns the pointer (WPOINTER) to the form's
window.
FORM_VIRTUAL_WINDOW(form) - returns the pointer (VWPOINTER) to the
form's virtual window.
FORM_NUMBER_OF_FIELDS(form) - returns an integer which is the
number of fields in a form.
FIELD_IN_RANGE(form,entry) - returns 1 if the entry number exists
in a form, 0 otherwise.
FIELD_ROW(entry) - returns an integer which is the row of the
FIELD_ENTRY entry.
FIELD_COLUMN(entry) - returns an integer which is the column of the
FIELD_ENTRY entry.
FIELD_TYPE(entry) - returns an integer denoting the field type of a
FIELD_ENTRY (i.e. CWL_INTEGER, CWL_STRING, etc.)
FIELD_MASK(entry) - returns a pointer (char *) to the mask string
used for a FIELD_ENTRY.
FIELD_FILL(entry) - returns an integer that denotes the fill
character used for a FIELD_ENTRY.
FIELD_MINIMUM(entry) - returns an integer which denotes the minimum
number of characters needed to be filled in
for a FIELD_ENTRY.
FIELD_VISIBLE_WIDTH(entry) - returns an integer which is the
visible width of a FIELD_ENTRY.
FIELD_REGEXP(entry) - returns a pointer (char *) to the regular
expression string used in a FIELD_ENTRY
entry.
FIELD_ATTRIBUTE(entry) - returns an integer which denotes the
attribute used for the FIELD_ENTRY entry.
FIELD_VARPTR(entry) - returns a pointer (void *) to the user's
variable that will hold the converted data
of the FIELD_ENTRY entry.
FIELD_CHANGE(form,entry) - returns 1 if the data entered in the
field defined by entry has been changed
since editing the form, 0 otherwise. If
the form is re-edited with another call
to FormGetInput(), FIELD_CHANGE() is
reset to 0 for all fields in the form.
Page 95 The C Window Library Page 95
FORM_CHANGE(form) - returns 1 if any fields in the form have
changed, 0 otherwise. If the form is
re-edited with another call to
FormGetInput(), FORM_CHANGE() returns 0.
Page 96 The C Window Library Page 96
INDEX
-----
B
Button Field (see Field-Pushbutton)
C
Checkbox Field (see Field-Checkbox)
F
Field
Attributes ......................... 9
Checkbox ........................... 34 - 39
Comma (see Field-Options)
Constants .......................... 5
Creating ........................... 2 - 13
Errors ............................. 16 - 17
FIELD_ENTRY structure .............. 3 - 10
Fill Character ..................... 6
Getting Field Buffer ............... 89
Getting Row and Column ............. 89
Justification (see Field-Options)
List Box ........................... 19 - 21
Mask ............................... 6
Maximum Width ...................... 6
Minimum Characters allowed ......... 6
Options ............................ 6, 56 - 57
Proteceted (see Field-Options)
Pushbutton ......................... 25 - 29
Radio .............................. 30 - 34
Range Checking ..................... 80 - 82
Regular Expression ................. 9
Row and Column ..................... 5
Setting Decimal Places ............. 17 - 18
Special Fields ..................... 19 - 39
Starting Input Position ............ 9
Storing Values in Field Buffer ..... 60
Subform ............................ 23 - 25
Toggle ............................. 21 - 23
Types .............................. 4 - 5
Zero Suppression (see Field-Options)
Floating Point (See Form-Initializing Floating Point)
Page 97 The C Window Library Page 97
Forms
Clearing ........................... 83
Disposing .......................... 88
Exiting ............................ 84 - 87
Form Manager ....................... 1
Getting Input ...................... 40 - 47
Initializing ....................... 13 - 16
Initializing Library ............... 2
Introduction ....................... 1
Options ............................ 13 - 14, 58 - 59
Virtual Scrolling .................. 41
Editing Input ...................... 42 - 46
Assigning Values To Fields ......... 48 - 55
Retrieving Values From Fields ...... 50 - 55
I
Initializing
Forms (see Forms - Initializing)
Library (see Forms - Initializing Library)
L
List Box Field (see Field-List Box)
M
Macros ................................... 92 - 96
Mouse .................................... 89 - 91
R
Radio Field (see Field-Radio)
Regular Expressions
(see Field - Regular Expressions)
S
Subform Field (see Field-Subforms)
Page 98 The C Window Library Page 98
U
User-Defined Functions
Post-Input Function .................... 66 - 68
Pre-Input Function ..................... 61 - 65
Undefined Key Function ................. 69 - 72
Error Function ......................... 73 - 82
Exit Function .......................... 84 - 87
V
Virtual Forms (see Forms)
Page 99 The C Window Library Page 99