Category : Pascal Source Code
Archive   : TOTDOCS.ZIP
Filename : CHAPT11.TXT

 
Output of file : CHAPT11.TXT contained in archive : TOTDOCS.ZIP
Controlling
User
Input





"I'm sick of writing documentation." Bob Ainsbury







Introduction

The Toolkit includes three major units to help you prompt the user for
input: totIO1, totIO2 and totIO3. These units provide more than 20
different input objects to accommodate all of your user input needs.
Objects may be used individually to prompt a user for input, or
combined together to build a powerful input form or dialog box.

There are objects to prompt for strings, numbers, dates, word-wrapping
memo fields, radio buttons, check boxes and lists. In the unlikely
event that there is no object type to support your specific needs, you
can create your own customized input objects.



Two Quick Examples

The Toolkit form input facilities are powerful and extensive, but you
don't need to understand every feature and facility to use them! Here
are a couple of examples to prove the point.

The following example, DEMIO1.PAS, is a simple program which prompts
the user to enter a real number.

program DemoIOOne;
{demIO1 - single field input}

Uses DOS, CRT,
totFAST, totIO1, totIO2;

Var
Price: FixedRealIOOBJ;

begin
ClrScr;
with Price do
begin
Init(35,5,8,2);
SetLabel('How much was the doppleganger? ');
SetValue(250.0);
SetMinMax(0.1,12250.0);
SetRules(EraseDefault);
Activate;
Writeln;writeln('You entered ',GetValue);

11-2 User's Guide

--------------------------------------------------------------------------------

Done;
end;
end.


Let's analyze the program. At the top of the program is the declaration
of a variable called Price, which is of type FixedRealIOOBJ. All form
input fields have object names ending in "IOOBJ", which stands for
input-output object. The FixedRealIOOBJ object is for the input of real
numbers which have a fixed number of decimal places.

In the main part of the program, only the three bold statements are
mandatory. The Init statement initializes the field. The four parame-
ters represent the (X,Y) coordinate of the first character in the
field, the number of whole digits, and the number of decimal places,
respectively. In this example, the field will be located in column 35,
row 5, with 8 significant digits, and 2 decimal places. The Activate
command instructs the Toolkit to display the field and wait for user
input. The Done method disposes of the object.

The other statements are used to customize the field. Any input field
can have a label, and usually, the label is displayed to the immediate
left of the field. The SetLabel method assigns a label to the input
field. By default, the field will have an initial value of zero. The
SetValue method is used to assign an initial default value of 250.0. As
you may have guessed, the SetMinMax method ensures that the user inputs
a number within a specified range. Figure 11.1 shows the error message
generated by the user when an invalid number is entered. The SetRules
method instructs the Toolkit to erase the default value if the user
first presses a non-editing key, e.g. a number.

The function method GetValue returns the value entered by the user.



Figure 11.1 [SCREEN]
Automatic Input
Validation



The second example, DEMIO2.PAS, shows how to combine a number of fields
into a full screen input form:

program DemoIOTwo;
{demIO2 - full field input}

Uses DOS, CRT,
totFAST, totIO1, totIO2;



Controlling User Input 11-3

--------------------------------------------------------------------------------

Var
Name: LateralIOOBJ;
Phone: PictureIOOBJ;
Price: FixedRealIOOBJ;
Keys: ControlkeysIOOBJ;
Manager: FormOBJ;
Result: tAction;

procedure InitVars;
{}
begin
with Name do
begin
Init(35,5,20,40);
SetLabel('Vendor Name');
end;
with Phone do
begin
Init(35,7,'(###) ###-####');
SetLabel('Tel');
end;
with Price do
begin
Init(35,9,8,2);
SetLabel('Unit Price');
SetValue(250.0);
SetMinMax(0.1,12250.0);
SetRules(EraseDefault);
end;
Keys.Init;
end; {InitVars}

begin
ClrScr;
Screen.TitledBox(15,3,65,11,76,79,78,2,' Quicky Input Demo ');
Screen.WriteCenter(25,white,'Press TAB to switch fields and
press ESC or F10 to end');
InitVars;
with Manager do
begin
Init;
AddItem(Keys);
AddItem(Name);
AddItem(Phone);
AddItem(Price);
Result := Go;
if Result = Finished then
{update the database..}
else



11-4 User's Guide

--------------------------------------------------------------------------------

{call Esc routine};
end;
end.


In this example, there are three input fields which prompt the user to
input a name, a telephone number and a unit price. The object Keys, of
type ControlKeysIOOBJ, is used to control which keys allow the user to
switch between fields and terminate the input session. By default, the
following keys are supported [KEYCAP], [KEYCAP], [KEYCAP] and [KEYCAP].

Every full screen input form must be controlled by a form manager of
type FormOBJ. In the example, the instance Manager is used.

The procedure InitVars is called to initialize all the input fields
using methods similar to the ones used in the previous example. In the
body of the main program, the Manager instance is initialized, and each
of the IO objects is included in the form by calling the method AddI-
tem. Finally, the function method Go is called to instruct the Toolkit
to process user input. The method returns a member of the enumerated
type tAction, which indicates whether the user escaped or ended nor-
mally - in this case by pressing [KEYCAP].

Figure 11.2 illustrates the output generated by this program. Note that
the first field can literally scroll, allowing the user to input data
which is longer than the visible field.



Figure 11.2 [SCREEN]
Full Screen
Input



The Object Hierarchy

The totIO units make extensive use of inheritance and polymorphism, and
this is reflected in the object hierarchy (see figure 11.3).



Controlling User Input 11-5

--------------------------------------------------------------------------------

Figure 11.3
totIO
Object Hierarchy



11-6 User's Guide

--------------------------------------------------------------------------------

At first, the object hierarchy may seem daunting, but there really
isn't much to it. Many of the objects are abstract, and these are
shaded gray in the figure. Remember that you should not create
instances of abstract objects -- use a descendant.

All you have to decide is which object fits your input needs, and then
create an instance. For example, if you want to prompt a user for a
date, use the DateIOOBJ, or if you want to prompt for a number, choose
RealIOOBJ, FixedRealIOOBJ, or IntIOOBJ.

It is often difficult to determine which methods are applicable to
which objects, especially with a deeply structured object hierarchy.
Part 3: Flash Cards lists, in one place, all the methods available for
each object in the IO hierarchy.

Listed below is a brief description of each input object:

StringIOOBJ Basic string input. Provides methods to force the
case of text, and to justify text when the user moves
to another field.

PictureIOOBJ String input which supports a special field mask or
picture to control input. The following special
format characters govern input:

! Forces letters to upper case
# Only accepts numbers
@ Only accepts letters and punctuation
* Accepts any character

For example, the field mask '(###) ###-####' is ideal
for US telephone numbers.

LateralIOOBJ String input which supports lateral scrolling. For
example, the field width can be set to 20 characters
wide, but the user might be allowed to enter up to 40
characters.

DateIOOBJ Input of dates. The Toolkit supports eight different
date formats, and this field will automatically
verify that the date entered is valid, and, option-
ally, within a specified range.

IntIOOBJ Whole number input. Use this object when you want to
obtain a whole number, i.e. shortint, byte, integer,
word, longint. Provides methods to ensure input is
within a specified range.

RealIOOBJ Real number input. By using Toolkit compiler direc-
tives (discussed on page 3.9), this object can get
input of single, double, extended, and comp reals.
Provides methods to ensure input is within a speci-
fied range.




Controlling User Input 11-7

--------------------------------------------------------------------------------

FixedRealIOOBJ Like RealIOOBJ, this object is for the input of real
numbers. The object is similar to contemporary data-
base packages - there are a fixed number of decimal
places, and when the user presses [KEYCAP] the cursor
jumps to the right of the decimal place.

HexIOOBJ Just for the engineers, this accepts the input of
hexadecimal numbers!

WWArrayIOOBJ A multi-line word-wrapping field. A one-dimensional
string array is assigned to the field. The contents
of the array are updated with the user's input.

WWLinkIOOBJ Also a multi-line word-wrapping field. A DLLOBJ
instance is assigned to the field. The linked list is
updated with the user's input.

ArrayIOOBJ A scrollable list of options from which the user may
select one. The displayed list is based on the
contents of a one-dimensional string array.

LinkIOOBJ A scrollable list based on the contents of a DLLOBJ
instance.

CheckIOOBJ A check box field, where the user can check any item
in the list.

RadioIOOBJ A radio button field where the user can select any
one item in the list.

StripIOOBJ A "Turbo 6.0 like" button which the user can select,
e.g. buttons for Edit, Save, Cancel, etc.

Strip3dIOOBJ The same as StripIOOBJ, except that a small 3-D
shadow is drawn behind the strip.

ButttonIOOBJ A "Norton Utilities-like" box button.

HotKeyIOOBJ HotkeyIOOBJ are invisible fields, used to trap for
special keys. For example, the key [KEYCAP] might
terminate the input session.

ControlKeysIOOBJ Defines which keys are used to move between fields,
and which keys terminate the input session.



Figure 11.4 shows a not-so-useful screen which uses every input type!
The on-disk demo file DEMIO3.PAS created the display.




Note: All the display colors used by the input objects are con-
trolled by the global instance pointer IOTOT. IOTOT controls all
the common display characteristics for input fields. This makes it

11-8 User's Guide

--------------------------------------------------------------------------------

easy to change the overall look and feel of your program, by just
changing the IOTOT values. IOTOT will be discussed in detail later
in the chapter (page 11-40).


Figure 11.4 [SCREEN]
Every Field
Type



Common Field Methods

All the Toolkit IO objects are derived from the base object ItemIOOBJ.
This abstract object defines the following fundamental methods which
are shared by all the objects:


SetActiveStatus(Selectable:boolean);

The Toolkit allows you to display fields in a form which are not always
accessible, i.e. the user cannot land the cursor on the field. Fields
which are displayed, but cannot be highlighted, are referred to as
inactive fields. By default, all fields are active, but the method
SetActiveStatus can be used to control activity status. Pass True to
activate the field, or False to deactivate it.


SetHotkey(HK:word);

Every field can be optionally selected by pressing a Hotkey. You can
assign a hotkey to any field with the method SetHotKey. The passed
parameter is the Toolkit key code (refer to the table on page 6-3) that
represents the key which will activate the field. For example, the
statement SetHotKey(305) assigns the key [KEYCAP] to the object. When
the user presses [KEYCAP], the cursor will jump to this field. Be sure
to assign different hotkeys to each field. To inform the user of the
hotkey, you can use the SetLabel method with the embedded character '~'
to highlight the key, e.g. SetLabel('~N~ame');.


SetID(ID:word);

By default, every field has an ID of zero. You can assign each field a
different ID with the SetID method. This ID is used to indicate the
highlighted field when a user presses a help function, or when a field
raises a signal to indicate that other fields need to be refreshed. The
topics of Help and Signals are discussed later.


In addition to these basic methods, all visible fields share the fol-
lowing two methods:



Controlling User Input 11-9

--------------------------------------------------------------------------------

SetLabel(Lbl:string);

Every visible field can have a label. The label is usually displayed to
the immediate left of the input field. When the field is highlighted,
the label is drawn in a different color to signify that the field is
active. Use the SetLabel command to specify a string label for any
field. Note that the use of the embedded control character '~' is sup-
ported. Refer to the discussion of the Screen.WriteHi method on page
5-3 for further information.


SetMessage(X,Y:byte; Msg:string);

The Toolkit can display an optional message at some location on the
screen when the field is highlighted. When the user leaves the field,
the message is erased. (Note: the old screen contents which were cov-
ered by the message are not restored.) Use the SetMessage method to
identify the location of the message and the message text.


Listed below is the demo program DEMIO4.PAS, which is a variation on
the program DEMIO2.PAS, discussed earlier. The usability has been
enhanced by adding informative (!) messages, and the user can jump to
the various fields by pressing hotkeys. Figure 11.5 shows the resultant
display.

program DemoIOFour;
{demIO4 - using hotkeys, labels, and messages}

Uses DOS, CRT,
totFAST, totIO1, totIO2;

Var
Name: LateralIOOBJ;
Phone: PictureIOOBJ;
Price: FixedRealIOOBJ;
Keys: ControlkeysIOOBJ;
Manager: FormOBJ;
Result: tAction;

procedure InitVars;
{}
begin
with Name do
begin
Init(35,5,20,40);
SetLabel('Vendor ~N~ame');
SetHotkey(305); {Alt-N}
SetMessage(22,11,'Enter the vendor''s name, 40 chars Max');
end;
with Phone do
begin



11-10 User's Guide

--------------------------------------------------------------------------------

Init(35,7,'(###) ###-####');
SetLabel('~T~el');
SetHotkey(276); {Alt-T}
SetMessage(22,11,'Enter the vendor''s phone number');
end;
with Price do
begin
Init(35,9,8,2);
SetLabel('Unit ~P~rice');
SetHotKey(281); {Alt-P}
SetMessage(22,11,'Enter the unit price in dollars');
end;
Keys.Init;
end; {InitVars}

begin
ClrScr;
Screen.TitledBox(15,3,65,12,76,79,78,2,' Quicky Input Demo ');
Screen.WriteCenter(25,white,'Press TAB to switched fields and press
ESC or F10 to end');
InitVars;
with Manager do
begin
Init;
AddItem(Keys);
AddItem(Name);
AddItem(Phone);
AddItem(Price);
Result := Go;
if Result = Finished then
{update the database..}
else
{call Esc routine};
end;
end.




Figure 11.5 [SCREEN]
Using Labels &
Messages



Field Types

The Object hierarchy illustrates the interrelated nature of the totIO
objects. The objects are loosely organized into the following groups:



Controlling User Input 11-11

--------------------------------------------------------------------------------

String StringIOOBJ (totIO2)
PictureIOOBJ (totIO2)
LateralIOOBJ (totIO2)

Number IntIOOBJ (totIO2)
RealIOOBJ (totIO2)
FixedRealIOOBJ (totIO2)
HexIOOBJ (totIO2)

Date DateIOOBJ (totIO2)

Check/Radio CheckIOOBJ (totIO1)
RadioIOOBJ (totIO1)

Lists ArrayIOOBJ (totIO2)
LinkIOOBJ (totIO2)

Wordwrap WWArrayIOOBJ (totIO3)
WWLinkIOOBJ (totIO3)

Buttons StripIOOBJ (totIO1)
Strip3dIOOBJ (totIO1)
ButtonIOOBJ (totIO1)

Hotkeys HotkeyIOOBJ (totIO1)
ControlKeysIOOBJ (totIO1)



The objects which fall into the category of single line objects are the
String, Number and Date object groups. These objects are similar in
nature, and share the following common methods:


SetIns(InsOn: boolean);

Pass True to set the field initially in insert mode, or False to be in
overtype mode.


SetRules(Rules:byte);

The rules control some of the field's editing properties. The following
constants are declared in the totIO1 unit:

NoRules This is the default state, with no editing rules
active.

AllowNull Use this rule to instruct the Toolkit to accept an
empty or null number field, even though the SetMinMax
method has been used to confine the acceptable input
within a range.

SuppressZero This rule suppresses the display of the default field
value in number fields, when the value is zero, i.e.
the field is empty, rather than showing "0" or "0.0".

11-12 User's Guide

--------------------------------------------------------------------------------

EraseDefault When active, this rule forces the emptying of the
field's default value, when a user highlights the field
and presses a non-editing key.

JumpIfFull This rule forces the user to the next field, as soon as
the current field is filled.

To specify multiple rules, simply sum the rules. For example, the
following statement will enforce three of the rules:

SetRules(AllowNull+EraseDefault+JumpIfFull);


SetDispChar(Ch:char);

Normally, the key pressed by the user is displayed in the input field.
However, for security, you may want to echo a different character to
the screen. Use this method to suppress the display of the typed char-
acters. The Toolkit will use the character Ch to identify that a char-
acter has been pressed. This method is ideal for password fields. Note
that the field stores the actual typed characters, as this method only
affects the way the display is updated. Pass a character of ' ' (space)
to instruct the Toolkit to echo the typed characters.


SetPadChar(Pad:char);

This method controls which character is used to pad out the empty part
of the input field. By default, the character used is defined in the
IOTOT object (discussed later).


With the exception of the FixedRealIOOBJ, the single line input fields
also share the following two methods:


SetJust(Just:tJust);

When the user leaves the current field, the Toolkit can automatically
justify the field data. This method controls the justification. The
totSTR unit includes the declaration of an enumerated type tJust, which
has the following members: JustLeft, JustCenter and JustRight. (Sounds
like a good name for a breakfast cereal!) By default, fields are left
justified.


SetCursor(Curs:tCursPos);

Every time the user jumps to a new field, the Toolkit has to decide
where to position the cursor. This method controls the cursor position-
ing for each field. The totIO1 unit includes the declaration of an
enumerated type tJust, which has the following members: CursLeft,
CursRight and CursPrev. Use CursLeft and CursRight to force the cursor




Controlling User Input 11-13

--------------------------------------------------------------------------------

to the leftmost or rightmost character position respectively. The Cur-
sPrev setting (default) instructs the Toolkit to position the cursor
where it was the last time the field was edited.



String Fields

The three string field objects (StringIOOBJ, PictureIOOBJ and Lateral-
IOOBJ) are all located in the totIO2 unit. All these objects are
descended from the abstract object VisibleIOOBJ, and share the
following methods, which were described earlier:

SetActiveStatus(Selectable:boolean);
SetHotkey(HK:word);
SetID(ID:word);
SetLabel(Lbl:string);
SetMessage(X,Y:byte;Msg:string);
Activate;

In addition, the following methods are shared by all three objects:


SetCase(Cas:tCase);

The totSTR unit includes the declaration of an enumerated type tCase
which has the following members: Lower, Upper, Proper and Leave. This
method can be used to control whether the Toolkit automatically adjusts
the case field string when the user leaves the field. Set the case to
Leave if you want the string to remain the same case as when it was
entered.


SetForceCase(On:boolean);

The SetForceCase method is used to control whether the case of the
string input is adjusted while the user is typing in the string. Pass a
True parameter to force the case adjustment (as specified with the
method SetCase) every time a character is pressed. Pass a False parame-
ter if you want the string to be adjusted only when the user moves to
another field.


SetValue(Str:string);

This method assigns a default value to the field. This value will be
displayed when the field is first displayed.


GetValue: string;

This method should be called (after the user has completed the input
session) to determine which string was entered.




11-14 User's Guide

--------------------------------------------------------------------------------

Done;

This method disposes of the memory consumed by the object, and should
be called after all user input is completed.



StringIOOBJ

The StringIOOBJ is used to obtain string input from the user. The user
may enter any alphanumeric character, including upper ASCII and inter-
national characters. The only method specific to StringIOOBJ is the
important Init method. The syntax of Init is as follows:


Init(X,Y,FieldLen:byte);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field. The third parame-
ter specifies the field length.



LateralIOOBJ

The LateralIOOBJ object is very similar to StringIOOBJ, except that the
field can scroll horizontally, allowing the user to input more charac-
ters than are visible in the field. LateralIOOBJ has its own Init
method as follows:


Init(X,Y,Fieldlen,MaxLen:byte);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field, the third parame-
ter specifies the visible field length, and the fourth parameter speci-
fies the maximum length of the input string, i.e. the scrollable field
length.



PictureIOOBJ

The PictureIOOBJ object gives you character by character control of the
input data, and allows you to embed non-editable characters into the
field.

When you initialize the object using the Init method (discussed later),
you must specify a string which represents the field picture. The pic-
ture is comprised of non-editable characters and the following four,
pre-defined, format characters:

# Allows the input of the characters (0-9 . -) and indicates
that only numbers may be input.



Controlling User Input 11-15

--------------------------------------------------------------------------------

@ Allows only letters of the English alphabet and punctuation
characters.

* Allows any character the user can find.

! Converts all alphabetical characters to upper case.

Any other characters embedded in the picture are treated as fixed and
for display only.

For example, the picture '(###) ###-####' would be used for the input
of US telephone numbers, and the picture '@@@####' might be used for a
seven character part number which comprises three letters and four dig-
its.

The field picture is specified in the Init method as follows:


Init(X,Y:byte; Picture:string);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field, and the third
parameter specifies the field picture.


Two other methods are provided to give even more control over which
characters can be input. You can either specify the characters which
are allowable, or the characters which are not allowable. The following
two methods serve this purpose:


SetDisAllowChar(Str:string);

When this method is used, the Toolkit will not allow the user to input
any of the characters specified in the Str. For example, SetDisAllow-
Char('\:'); will not allow the user to input a backslash or colon,
regardless of the field picture.


SetAllowChar(Str:string);

This method is the opposite of the previous one, and it is used to
identify all the characters which the Toolkit will allow the user to
enter. For example, SetAllowChar('AaBbCc0123456789'); will only allow
the user to input numbers, or the characters A, B and C.


Only use one or the other of these methods. If you only want to stop
the user from entering a few specific characters, use SetDisAllowChar.
On the other hand, if you only want to allow a few characters to be
input, use the SetAllowChar method.



11-16 User's Guide

--------------------------------------------------------------------------------

The function method GetValue will return the condensed string excluding
the format characters. For example, a telephone number would be
returned as 10 digits with no brackets or spaces. The following method
will return the fully formatted string, including all embedded format
characters:


GetPicValue:string;

Returns the string entered by the user, including all formatting char-
acters.




Note: the totStr unit includes the function PicFormat which
returns a formatted string. Refer to chapter 14: String Handling
for further information.




String Field Examples

Listed below is an extract of the demo program DEMIO5, which focuses on
string fields. Figure 11.6 shows an example of the display generated by
the full program.

procedure InitVars;
{}
begin
with Field1 do
begin
Init(40,3,10);
SetLabel('Field 1 (StringIOOBJ)');
end;
with Field2 do
begin
Init(40,5,10);
SetLabel('Field 2 (StringIOOBJ)');
SetCase(upper);
SetValue('hello');
SetRules(EraseDefault+JumpIfFull);
end;
with Field3 do
begin
Init(40,7,15,30);
SetLabel('Field 3 (LateralIOOBJ)');
end;
with Field4 do
begin
Init(40,9,15,30);


Controlling User Input 11-17

--------------------------------------------------------------------------------

SetLabel('Field 4 (LateralIOOBJ)');
SetCase(Upper);
SetForcecase(True);
SetCursor(CursLeft);
end;
with Field5 do
begin
Init(40,11,'(###) ###-####');
SetLabel('Field 5 (PictureIOOBJ)');
end;
with Field6 do
begin
Init(40,13,'!!!***@@@###');
SetLabel('Field 6 (PictureIOOBJ)');
SetDisAllowChar('aAbBcC123@!');
SetRules(EraseDefault);
end;
with Field7 do
begin
Init(40,15,10);
SetLabel('Field 7 (StringIOOBJ)');
SetDispChar('#');
end;
end; {InitVars}


Figure 11.6 [SCREEN]
Using String
Fields



Don't forget that IO objects can be used individually, to prompt the
user with a single field. Listed below is the demo program DEMIO6.PAS,
which prompts the user to enter a string.

program DemoIOSix;
{demIO6 - single string field input}

Uses DOS, CRT,
totFAST, totIO1, totIO2, totSTR;

var
Field: StringIOOBJ;

begin
with Field do

begin
Init(40,5,10);
SetLabel('Field (StringIOOBJ)');
SetCase(upper);
SetValue('hello');


11-18 User's Guide

--------------------------------------------------------------------------------

SetRules(EraseDefault+JumpIfFull);
clrscr;
Activate;
writeln;writeln('You entered ',GetValue);
Done;
end;
end.




Number Fields

The totIO2 unit includes the following four objects for creating number
fields: IntIOOBJ, RealIOOBJ, FixedRealIOOBJ and HEXIOOBJ. All these
objects are descended from the abstract object CharIOOBJ, and share the
following methods which were described earlier:

SetActiveStatus(Selectable:boolean);
SetHotkey(HK:word);
SetID(ID:word);
SetLabel(Lbl:string);
SetMessage(X,Y:byte;Msg:string);
SetIns(InsOn:boolean);
SetRules(Rules:byte);
SetDispChar(Ch:char);
SetPadChar(Pad:char);
Activate;
Done;


Except for FixedRealIOOBJ, the number fields also support the following
two methods:

SetJust(Just:tJust);
SetCursor(Curs:tCursPos);



IntIOOBJ

The IntIOOBJ object should be used to prompt for whole numbers, i.e.
with a type of byte, word, shortint, integer and longint. The following
additional methods are supported by IntIOOBJ objects:


Init(X,Y,Len:byte);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field. The third parame-
ter specifies the field length.


SetMinMax(Min,Max:longint);



Controlling User Input 11-19

--------------------------------------------------------------------------------

The Toolkit can automatically ensure that the user input falls within a
specified range. Use the method SetMinMax to set an input range. Pass
two zeros to turn off input validation. If the user tries to input an
invalid value, the Toolkit displays a pop-up message explaining the
problem (see figure 11.1), and forces the user to input a valid number.


SetValue(Val:longint);

Use this method to set an initial or default value in the field.


GetValue: longint;

This function method returns the value input by the user.



RealIOOBJ

This object is very similar to IntIOOBJ, except that it is designed for
the input of real numbers, i.e. numbers with one or more decimal
places.


Note: The Toolkit supports all the real types, i.e. real, single,
double, extended and comp. By default, all these types are mapped
to the base type REAL. In other words, if you declare a variable
of type EXTENDED, the Toolkit re-maps it so that Turbo Pascal
treats it like a basic REAL. If you do want to support all the
additional precision reals, edit the file TOTFLAGS.INC and adjust
the conditional defines FLOAT and FLOATEM. Refer to page 3-9 for
further information.


In addition to the common methods, the following methods are supported
by RealIOOBJ objects:


Init(X,Y,Len:byte);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field. The third parame-
ter specifies the field length.


SetMinMax(Min,Max:extended);

The Toolkit can automatically ensure that the user input falls within a
specified range. Use the method SetMinMax to set an input range. Pass
two zeros to suppress input validation. If the user tries to input an
invalid value, the Toolkit displays a pop-up message explaining the
problem (see figure 11.1), and forces the user to input a valid number.




11-20 User's Guide

--------------------------------------------------------------------------------

SetValue(Val:extended);

Use this method to set an initial or default value in the field.


SetENotation(On:boolean);

This method controls whether the user is allowed to enter the number in
E-notation, e.g. 4.435623E+12. Pass True to allow the user to input
E-notation, or False to disallow it.


GetValue: extended;

This function method returns the value input by the user.



FixedRealIOOBJ

You may have used some commercial database or financial software pro-
grams which provide special cursor control when the user is inputting
real numbers. For example, when the user presses [KEYCAP], the cursor
automatically jumps to the right of the fixed decimal place. The Fixe-
dRealIOOBJ object brings this capability to the Toolkit. (The cursor
and key reactions emulate the FoxPro database package - we liked it, so
we copied it!)

FixedRealIOOBJ objects provide the following additional methods:


Init(X,Y,Whole,DP:byte);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field. The third parame-
ter specifies the maximum number of whole numbers, and the last parame-
ter specifies the maximum number of decimal places.


SetMinMax(Min,Max:extended);

The Toolkit can automatically ensure that the user input falls within a
specified range. Use the method SetMinMax to set an input range. Pass
two zeros to suppress input validation. If the user tries to input an
invalid value, the Toolkit displays a pop-up message explaining the
problem (see figure 11.1), and forces the user to input a valid number.


SetValue(Val:extended);

Use this method to set an initial or default value in the field.


GetValue: extended;

This function method returns the value input by the user.

Controlling User Input 11-21

--------------------------------------------------------------------------------

HEXIOOBJ

If you want a user to enter HEX numbers, HEXIOOBJ is the object for
you. HEXIOOBJ is very similar to IntIOOBJ, with the main difference
that HEX allows the user to input numbers and the letters A, B, C, D, E
and F.

As well as the common number methods, HEXIOOBJ supports the following
methods:


Init(X,Y,Len:byte);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field. The third parame-
ter specifies the field length.


SetMinMax(Min,Max:longint);

The Toolkit can automatically ensure that the user input falls within a
specified range. Use the method SetMinMax to set an input range. Pass
two zeros to turn off input validation.


SetValue(Val:longint);

Use this method to set an initial or default value in the field.


GetValue: longint;

This function method returns the value input by the user.




Note: in Turbo Pascal HEX numbers are preceded by a '$' character.
For example, the following method calls have the same effect:
SetValue($FF);
SetValue(255);




Formatting Number Fields

The objects IntIOOBJ, RealIOOBJ and FixedREALIOOBJ all provide optional
formatting capabilities, which can be used to control the format of the
displayed number when the user leaves the field, i.e. when the user is
editing, the number is unformatted, but when the user exits the field,
the number can be formatted in a variety of styles. For example, the
number -123456.78 might be formatted as $123,456.78 CR.

If you want formatted number fields, you must call the following
method:

11-22 User's Guide

--------------------------------------------------------------------------------

InitFormat;

This method instructs the object to format the field when the user
leaves the field.


The totSTR unit includes the object FmtNumberOBJ, which is designed to
format numbers. The FmtNumber object includes the following methods:

SetPrefixSuffix(P,S:char);
SetSign(S:tSign);
SetSeparators(P,T,D:char);
SetJustification(J:tJust);


These methods are described in detail in chapter 14: String Handling.
Refer to this chapter for further information.

Behind the scenes, when the number method InitFormat is called, the
Toolkit creates a private FmtNumberOBJ instance. The number method For-
matPtr can be used to access the FmtNumberOBJ instance using the fol-
lowing syntax:

FormatPtr^.[method]

For example, the following code fragment formats an integer field with
a '$' prefix and embedded commas.

var
Field: IntIOOBJ;

begin
with Field do
begin
Init;
InitFormat;
FormatPtr^.SetPrefixSuffix('$',#0);
FormatPtr^.SetSeparators(' ',',','.');
{...}
end;
end.




Setting the Default Format

The totIO2 unit includes FmtNumberTOT, a pointer to an object instance
of type FmtNumberOBJ. This instance defines the default formatting that
will be applied to real and integer fields during full-screen input.
Whenever a number field object's method InitFormat is called, the
field's initial formats are copied from FmtNumberTOT.



Controlling User Input 11-23

--------------------------------------------------------------------------------

You can control each field's default value by setting FmtNumberTOT to
specifically meet your needs, before you call the InitFormat method.
For example, if you want all your number fields to be formatted with a
suffix of FR, set the default with the following statement:

FmtNumberTOT.SetPrefixSuffix('','FR');

All number objects initialized after this statement will assume the FR
suffix.



Number Field Examples

Back on the first page of this chapter you saw an example of how to
prompt the user for a real number using FixedRealIOOBJ. Take another
look at page 11.1 and see if the statements make more sense now!

Listed below is an extract of the demo program DEMIO8.PAS which illus-
trates how to use many of the methods discussed in this section. Figure
11.7 shows an example of the display generated by the full program.

procedure InitVars;
{}
begin
with Field1 do
begin
Init(40,3,5);
SetLabel('Field 1 (IntIOOBJ)');
end;
with Field2 do
begin
Init(40,5,5);
InitFormat;
SetLabel('Field 2 (IntIOOBJ)');
SetValue(69);
SetRules(EraseDefault+JumpIfFull);
end;
with Field3 do
begin
Init(40,7,10);
SetLabel('Field 3 (RealIOOBJ)');
end;
with Field4 do
begin
Init(40,9,15);
InitFormat;
FormatPtr^.SetSeparators('*',',','.');
FormatPtr^.SetPrefixSuffix('','FR');
FormatPtr^.SetJustification(JustRight);
SetLabel('Field 4 (RealIOOBJ)');


11-24 User's Guide

--------------------------------------------------------------------------------

SetCursor(CursLeft);
end;
with Field5 do
begin
Init(40,11,8,2);
SetLabel('Field 5 (FixedRealIOOBJ)');
end;
with Field6 do
begin
Init(40,13,5);
SetLabel('Field 6 (HEXIOOBJ)');
end;
Keys.Init;
end; {InitVars}



Figure 11.7 [SCREEN]
Using Number
Fields



Date Fields

The DateIOOBJ object is used to prompt the user to input a date. The
Toolkit supports eight different date formats. The totDATE unit
includes an enumerated type tDate which has the following members:
MMDDYY, MMDDYYY, MMYY, MMYYYY, DDMMYY, DDMMYYYY, YYMMDD, YYYYMMDD.
Whenever you work with dates, you must identify the desired date for-
mat.

Refer to chapter 13: Managing Dates for a full description of all the
date manipulation routines which complement DateIOOBJ. There are a
wealth of functions to convert dates to and from Julian, Gregorian and
string formats. For example, the JultoStr and StrtoJul functions con-
vert between Julian and string formats.

DateIOOBJ is a descendant of CharIOOBJ, and inherits the following,
previously described, methods:

SetActiveStatus(Selectable:boolean);
SetHotkey(HK:word);
SetID(ID:word);
SetLabel(Lbl:string);
SetMessage(X,Y:byte;Msg:string);
SetIns(InsOn:boolean);
SetRules(Rules:byte);
SetDispChar(Ch:char);
SetPadChar(Pad:char);
Activate;
Done;


Controlling User Input 11-25

--------------------------------------------------------------------------------

The DateIOOBJ object manipulates dates in Julian format, where dates
are specified as longints. DateIOOBJ includes the following methods:


Init(X,Y:byte; DateFmt:tDate);

This method must be called first. The first two parameters indicate the
(X,Y) coordinate of the first character in the field. The third parame-
ter is a member of the enumerated type tDate, and indicates which for-
mat of date is to be input, e.g. MMDDYY or DDMMYY.


SetMinMax(Min,Max:longint);

The Toolkit will automatically verify if proper dates are entered, i.e.
that the month is between 1 and 12, and the days are valid for the
specified month. The method SetMinMax can also be used to specify a
date range. Pass two zeros to turn off input validation. If the user
tries to input an invalid date or an out of range date, the Toolkit
displays a pop-up message explaining the problem (see figure 11.8), and
forces the user to input a valid number.


SetValue(Date: longint);

Use this method to set an initial or default value in the field. The
date is passed as a Julian (longint) value.


GetValue:longint;

This function method returns the Julian date value input by the user.



Listed below is the demo program DEMIO9.PAS which prompts the user for
the input of a single date. Figure 11.8 is an example of the date
validation performed by the Toolkit.

program DemoIONine;
{demIO9 - single date field input}

Uses DOS, CRT,
totIO1, totIO2, totDate;

Var
Birthday: DateIOOBJ;

begin
ClrScr;
with Birthday do
begin
Init(35,5,MMDDYY);
SetLabel('When is your next birthday? ');
Activate;


11-26 User's Guide

--------------------------------------------------------------------------------

Writeln;
writeln('You entered the Julian date',GetValue);
writeln('i.e. ',JultoStr(GetValue,MMDDYY));
Done;
end;
end.


Figure 11.8 [SCREEN]
Single Date
Input



Listed below is an extract of the demo program DEMIO10.PAS which illus-
trates how to use many of the methods discussed in this section. Figure
11.9 shows an example of the display generated by the full program.

procedure InitVars;
{}
begin
with Field1 do
begin
Init(40,3,MMDDYY);
SetLabel('Field 1 (MMDDYY)');
end;
with Field2 do
begin
Init(40,5,MMDDYY);
SetLabel('Field 2 (MMDDYY)');
SetValue(TodayInJul);
SetRules(EraseDefault+JumpIfFull);
end;
with Field3 do
begin
Init(40,7,DDMMYYYY);
SetLabel('Field 3 (DDMMYYYY)');
end;
with Field4 do
begin
Init(40,9,DDMMYYYY);
SetLabel('Field 4 (DDMMYYYY)');
SetMinMax(GregtoJul(3,1,1992),GregtoJul(3,31,1992));
SetCursor(CursLeft);
end;
Keys.Init;
end; {InitVars}



Controlling User Input 11-27

--------------------------------------------------------------------------------

Figure 11.9 [SCREEN]
Using Date
Fields



Check Boxes and Radio Buttons

Two common elements of contemporary input forms are check boxes and
radio buttons. Both these objects provide ways of choosing items from
lists of options. Figure 11.10 (listed later in the section) illus-
trates both types of objects.

A check box object provides a list of options with each item having its
own check box displayed to the left of the item, e.g. [X] Toast. Any
number of items in the list can be selected. An item's selection status
is toggled by hitting the [KEYCAP] or by clicking the mouse cursor on
it. Selected items have an X in the adjacent check box.

Radio buttons are similar to check boxes, except that only one item can
be selected. When an item is selected, the previously selected item is
deselected. The selected item has a dot in the "button" next to it,
e.g. (.) Ham Sandwich.

The Toolkit objects CheckIOOBJ and RadioIOOBJ are located in the totIO1
unit, and are descended from VisibleIOOBJ. Both objects, therefore,
inherit the following, previously described, methods:

SetActiveStatus(Selectable:boolean);
SetHotkey(HK:word);
SetID(ID:word);
SetLabel(Lbl:string);
SetMessage(X,Y:byte;Msg:string);
Activate;
Done;


The objects are part of the MultLineIOOBJ object family and also
inherit the following method:


SetBoxOn(On:boolean);

All multi-line objects can be optionally displayed in a box. By
default, the objects are not displayed in a box. To activate the box
display, pass a True parameter.


Both objects share the following common methods:


Init(X1,Y1,width,depth:byte; Title:string);



11-28 User's Guide

--------------------------------------------------------------------------------

This method should be called first. The first two parameters specify
the (X,Y) coordinate of the top left of the object. The third and
fourth parameters specify the width and depth of the object in charac-
ters. The width should be large enough to accommodate the longest item,
and leave room for the box, if the box is active. The depth should be
large enough to accommodate the title, all the items and, optionally,
the box.


AddItem(Str:string; HK:word; Selected:boolean);

This method adds an item to the list. The first parameter specifies the
text to be displayed - don't forget that embedded '~' characters can be
used to highlight text (see page 5-3 for further information). The
second parameter is an optional hot key code, which the user can press
to jump to this item and automatically select/deselect it. Pass a value
of zero if you don't want to specify a hotkey. The third parameter
indicates whether the item is selected or not. You can add as many
items as will fit in the object's initialized dimensions.




Note: the generic method SetHotKey is used to specify the hotkey
for the entire object. If the user presses the generic hotkey, the
object will be selected, and the last active item will be high-
lighted. The individual item hotkeys allow the user to both select
the object, and immediately activate the specific item. The demo
program DEMIO12.PAS, discussed later, illustrates hotkeys.




CheckIOOBJ

CheckIOOBJ provides the following two methods for setting and checking
the status of each item:


SetValue(Item:byte; selected:boolean);

This method is used to change the selection status of an item after it
has been added with AddItem. The first parameter specifies the item
number, and the second boolean parameter should be set to True to
select the item, or false to deselect it.


GetValue(Item:byte):boolean;

This boolean function method returns True if the specified item is
selected.



Controlling User Input 11-29

--------------------------------------------------------------------------------

RadioIOOBJ

RadioIOOBJ has the following methods for setting and checking which
item is selected:


SetValue(Item:byte);

Only one item in a radio button object can be selected. Use this method
(after you have added all the items) to specify which item is selected.


GetValue:byte;

This function returns the number of the selected item.



Examples

Listed below is the demo program DEMIO11.PAS illustrating a single
radio button field.

program DemoIOEleven;
{demIO11 - single Radio Button input}

Uses DOS, CRT,
totFAST, totINPUT, totIO1, totIO2;

Var
Bool: RadioIOOBJ;

begin
ClrScr;
with Bool do
begin
Init(35,12,20,5,'Sex?');
SetBoxOn(True);
AddItem('~M~ale',77,true);
AddItem('~F~emale',70,false);
Mouse.Show;
Activate;
Mouse.Hide;
gotoxy(1,20);
if GetValue = 1 then
writeln('You are male!')
else
writeln('Hi, I''m Bob.');
Done;
end;
end.



11-30 User's Guide

--------------------------------------------------------------------------------

Listed below is an extract of the demo program DEMIO12.PAS, which
illustrates how to combine mulitiple fields in a dialog box. Figure
11.10 shows an example of the display generated by the full program.

procedure InitVars;
{}
begin
with Field1 do
begin
Init(17,5,25,4,'Options');
AddItem('~C~ase sensitive',67,false);
AddItem('~W~hole words only',87,false);
AddItem('~R~egular expression',82,false);
end;
with Field2 do
begin
Init(17,10,25,3,'Scope');
AddItem('~G~lobal',71,true);
AddItem('~S~elected text',83,false);
end;
with Field3 do
begin
Init(45,5,17,3,'Direction');
AddItem('Forwar~d~',68,true);
AddItem('~B~ackward',66,false);
end;
with Field4 do
begin
Init(45,10,17,3,'Origin');
AddItem('~F~rom cursor',70,false);
AddItem('~E~ntire scope',69,true);
end;
Keys.Init;
end; {InitVars}


Figure 11.10 [SCREEN]
A Custom
Dialog Box



List Fields

Radio buttons allow the user to select a single item from a list.
Sometimes, however, you may have too many items in the list to display
all together. The ListOOBJ object family can be used to display scroll-
able lists, and these are located in the totIO2 unit.



Controlling User Input 11-31

--------------------------------------------------------------------------------

ListIOOBJ is an abstract object, and you should only use the descen-
dants ArrayIOOBJ and LinkIOOBJ. These objects display the contents of a
string array and a DLLOBJ linked list, respectively. Both these objects
are descendant from MultiLineIOOBJ, and inherit the following, pre-
viously discussed, methods:

SetActiveStatus(Selectable:boolean);
SetHotkey(HK:word);
SetID(ID:word);
SetLabel(Lbl:string);
SetMessage(X,Y:byte;Msg:string);
SetBoxOn(On:boolean);
Activate;
Done;


Both items share the following common Init method:


Init(X1,Y1,width,depth:byte; Title:string);

This method should be called first. The first two parameters specify
the (X,Y) coordinate of the top left of the object. The third and
fourth parameters specify the width and depth of the object in charac-
ters. The width should be large enough to accommodate the longest item,
a scroll bar (if there are too many items to display at once) and leave
room for the box (if the box is active). The depth should be large
enough to accommodate the title, at least one item and, optionally, the
box.


Having initialized the object, the next task is to call the AssignList
method. AssignList instructs the Toolkit where to locate the data for
the items in the list. Each object has its own AssignList method.



ArrayIOOBJ

The Toolkit gets the contents of the list from a string array, which
you must create separately. Having created the array, you must call the
following method:


AssignList(var StrArray; Total:longint; StrLength:byte);

AssignList identifies the string array that will be displayed. The four
parameters are the string array, the total number of elements in the
array, and the length of each string in the array. The string length
parameter must reflect the string length of the array when it was
declared, not the maximum length of any string assigned to the array.



11-32 User's Guide

--------------------------------------------------------------------------------

Listed below is the demo program DEMIO13.PAS, which illustrates how to
build an ArrayIOOBJ field.

program DemoIOThirteen;
{demIO13 - single ArrayIOOBJ input}

Uses DOS, CRT,
totFAST, totIO1, totIO2;

Var
MyList: array[1..10] of string[20];
ListField: ArrayIOOBJ;

procedure FillArray;
{}
begin
MyList[1] := 'Monitor';
MyList[2] := 'Keyboard';
MyList[3] := 'Mouse';
MyList[4] := 'Light Pen';
MyList[5] := 'Microphone';
MyList[6] := 'LCD O/H Panel';
MyList[7] := 'Modem';
MyList[8] := 'Printer';
MyList[9] := 'CD Rom';
MyList[10] := 'Toolkit';
end; {FillArray}

begin
ClrScr;
FillArray;
with ListField do
begin
Init(35,5,15,6,'Peripherals');
AssignList(MyList,10,20);
Activate;
gotoxy(1,20);
writeln('You chose item: ',GetValue,' - ',MyList[GetValue]);
Done;
end;
end.




LinkIOOBJ

This object accesses a DLLOBJ object, to determine which items to dis-
play in the list. You must create a DLLOBJ instance, populate the list,
and then call the following AssignList method:



Controlling User Input 11-33

--------------------------------------------------------------------------------

AssignList(var LinkList: DLLOBJ);

This method is passed a DLLOBJ instance, or any instance of an object
descended from DLLOBJ, e.g. StrDLLOBJ.


Listed below is the demo program DEMIO14.PAS, which illustrates how to
build a LinkIOOBJ field.

program DemoIOFourteen;
{demIO14 - single LinkIOOBJ input}

Uses DOS, CRT,
totFAST, totIO1, totIO2, totLINK;

Var
MyList: StrDLLOBJ;
ListField: LinkIOOBJ;

procedure FillList;
{}
var Retcode: integer;
begin
with MyList do
begin
Init;
Retcode := Add('Monitor');
Retcode := Add('Keyboard');
Retcode := Add('Mouse');
Retcode := Add('Light Pen');
Retcode := Add('Microphone');
Retcode := Add('LCD O/H Panel');
Retcode := Add('Modem');
Retcode := Add('Printer');
Retcode := Add('CD Rom');
Retcode := Add('Toolkit');
end;
end; {FillList}

begin
ClrScr;
FillList;
with ListField do
begin
Init(35,5,15,6,'Peripherals');
AssignList(MyList);
Activate;
gotoxy(1,20);
writeln('You chose item: ',GetValue,' - ',
MyList.GetStr(MyList.NodePtr(GetValue),0,0));
Done;



11-34 User's Guide

--------------------------------------------------------------------------------

MyList.Done;
end;
end.




Both the examples produce identical displays, see figure 11.11 below.



Figure 11.11 [SCREEN]
Displaying
a List



Word Wrapping Fields

Some of the most powerful, but easy to use, form objects are the Word-
WrapIOOBJ objects. These objects can be used to display scrollable memo
fields. The user can type in multiple lines of text with full editing,
and the object provides automatic word wrapping.

WordWrapIOOBJ is an abstract object, and you should only use the
descendants WWArrayIOOBJ and WWLinkIOOBJ. Like the List objects
described in the last section, these objects display the contents of a
string array and a DLLOBJ linked list, respectively. Both objects are
descendant from MultiLineIOOBJ, and inherit the following, previously
discussed, methods:

SetActiveStatus(Selectable:boolean);
SetHotkey(HK:word);
SetID(ID:word);
SetLabel(Lbl:string);
SetMessage(X,Y:byte;Msg:string);
SetBoxOn(On:boolean);
SetIns(InsOn:boolean);
Activate;
Done;


Both items share the following common Init method:


Init(X1,Y1,width,lines:byte; Title:string);

This method should be called first. The first two parameters specify
the (X,Y) coordinate of the top left of the object. The third parameter
specifies the width of the object in characters, and the fourth parame-
ter specifies the number of lines of text to display. The last parame-
ter is an optional title.



Controlling User Input 11-35

--------------------------------------------------------------------------------

Having initialized the object, the next task is to call the AssignList
method. AssignList instructs the Toolkit where to locate the data for
the text. Each object has its own AssignList method, and these are
explained in a later section.

If you want to pre-load the field with some text, you can take advan-
tage of the following auto-word wrapping method:


WrapFull;

This method adjusts the contents of the source data structure, i.e. the
string array or linked list, by word wrapping the existing text. When
you add text to the data structures you do not need to accurately word
wrap the text, but you should make sure that there is always one space
at the end of the line. This space separates the last word on one line
from the first word on the next line.


Sometimes, you may want to display a word wrap field, but not allow the
user to edit the text. The following method controls whether editing is
allowed:


SetAllowEdit(On:Boolean);

Pass true to enable editing (default). When editing is disabled, the
user may still scroll the text, but it cannot be changed.


When the word wrap fields are used on their own, i.e. by calling acti-
vate rather than as part of a form, the user can end the input by
pressing F10. This "end edit" key can be assigned to another key using
the following method:


SetEndKey(K:word);

Specifies the key which will end the input session when the field is
used individually rather than as part of a form. The default is F10.



WWArrayIOOBJ

The Toolkit gets the text contents from a string array, which you must
create separately. Having created the array, you must call the follow-
ing method:


AssignList(var StrArray; Total:longint; StrLength:byte);



11-36 User's Guide

--------------------------------------------------------------------------------

AssignList identifies the string array that will be displayed. The
three parameters are the string array, the total number of elements in
the array, and the length of each string in the array. The string
length parameter must reflect the string length of the array when it
was declared, not the maximum length of any string assigned to the
array.



Note: the Toolkit is unable to extend the size of the array. You
must, therefore, ensure the array is large enough to accommodate
all the text the user is allowed to enter. If you want an unlim-
ited number of lines, or you want the Toolkit to extend the lines
used, take advantage of the WWlinkOBJ described next.




Listed below is the demo program DEMIO15.PAS, which illustrates how to
build an WWArrayIOOBJ field.

program DemoIOFifteen;
{demIO15 - single WWArrayIOOBJ input}
Uses DOS, CRT,
totFAST, totIO1, totIO3, totINPUT;

Var
MyList: array[1..10] of string[60];
WWField: WWArrayIOOBJ;

procedure FillArray;
{}
begin
FillChar(MyList,sizeof(MyList),#0);
MyList[1] := 'It seems like we have to work at innocence ';
MyList[2] := 'and being pure, and at the same time we have ';
MyList[3] := 'to work at being successful so that we have ';
MyList[4] := 'an understanding as to what the rest of the ';
MyList[5] := 'world is up to.';
MyList[6] := '';
MyList[7] := 'Brother Anthony Fiore';
end; {FillArray}

begin
ClrScr;
Screen.WriteCenter(1,15,'Press F10 to finish');
FillArray;
Mouse.Show;
with WWField do
begin
Init(5,7,65,7,'A Quote');
AssignList(MyList,10,60);


Controlling User Input 11-37

--------------------------------------------------------------------------------

WrapFull;
Activate;
gotoxy(1,20);
Done;
end;
Mouse.Hide;
end.



WWLinkIOOBJ

This object accesses a DLLOBJ object to determine which items to dis-
play in the list. You must create a DLLOBJ instance, populate the list,
and then call the following AssignList method:


AssignList(var LinkList: DLLOBJ; Max:integer);

This method is passed a DLLOBJ instance, or any instance of an object
descended from DLLOBJ, e.g. StrDLLOBJ. Max specifies the maximum number
of lines by which the Toolkit can extend the list.


Listed below is the demo program DEMIO16.PAS, which illustrates how to
build a WWLinkIOOBJ field.

program DemoIOSixteen;
{demIO16 - single WWLinkIOOBJ input}
Uses DOS, CRT,
totFAST, totIO1, totIO3, totINPUT, totLINK;

Var
MyList: StrDLLOBJ;
WWField: WWLinkIOOBJ;

procedure FillList;
{}
var Retcode: integer;
begin
with MyList do
begin
init;
Retcode := Add('It seems like we have to work at innocence ');
Retcode := Add('and being pure, and at the same time we have ');
Retcode := Add('to work at being successful so that we have ');
Retcode := Add('an understanding as to what the rest of the ');
Retcode := Add('world is up to.');
Retcode := Add('');
Retcode := Add('Brother Anthony Fiore');
end;
end; {FillList}



11-38 User's Guide

--------------------------------------------------------------------------------

begin
ClrScr;
Screen.WriteCenter(1,15,'Press F10 to finish');
FillList;
Mouse.Show;
with WWField do
begin
Init(5,7,65,7,'A Quote');
AssignList(MyList,40);
WrapFull;
Activate;
gotoxy(1,20);
MyList.Done;
Done;
end;
Mouse.Hide;
end.



The display generated by both of the demo programs is identical, and is
illustrated in figure 11.12.



Figure 11.12 [SCREEN]
A Word Wrap
Field



Button Fields

Buttons are for use with full screen input forms. They provide a way
for the user to invoke an event. For example, an input form may have a
SAVE button and a CANCEL button. A button can be selected by tabbing to
the button and pressing [KEYCAP], pressing the button hotkey, or by
clicking the mouse cursor on the button.

The Toolkit provides three button objects in the totIO1 unit: Stri-
pIOOBJ, Strip3dIOOBJ, and ButtonIOOBJ. All three objects function iden-
tically, and the differences are purely cosmetic. The StripIOOBJ object
provides a single-line button, Strip3dIOOBJ is a single line button
with a black shadow, and ButtonIOOBJ displays the button text sur-
rounded by a box. Refer back to figure 11.4 (on page 11-8) for examples
of each button type.

All three button objects are descended from VisibleIOOBJ and share the
following, previously described, methods:



Controlling User Input 11-39

--------------------------------------------------------------------------------

SetActiveStatus(Selectable:boolean);
SetHotkey(HK:word);
SetID(ID:word);
SetLabel(Lbl:string);
SetMessage(X,Y:byte;Msg:string);
Done;


While the SetLabel method is technically available, it is not normally
used, because the button text acts as a label.

The totIO1 unit includes the declaration of the enumerated type tAc-
tion, which has the following members: None, NextField, PrevField, Fin-
ished, Escaped, Refresh, Signal, Enter, Help, Stop1..Stop9. All these
members are used internally by the Toolkit to control events during
full screen input. The following members should be used with buttons:

Finished Use with buttons to indicate a standard end of a
form editing session, e.g. buttons like "OK",
"Done", "Proceed", "Save".

Escaped Use with buttons that allow the user to exit
without processing the edited data, e.g. buttons
like "Cancel", "Abort".

Help Use with a "Help" button. When selected, the
Toolkit will automatically invoke a context sensi-
tive help system (discussed later).

Stop1..Stop9 These buttons function like Finished. They should
be used to successfully end the form edit session.
They are provided so that you may provide multiple
finished buttons. Based on which button is
selected, you may process the edited data differ-
ently. For example, you may create the following
three buttons:
"Save & Quit" - Finished
"Save & Edit Next" - Stop1
"Save & Backup File" - Stop2
Whichever button is selected, the edit session will
end, and the FormOBJ (discussed later) will return
the tAction member selected.


All three buttons share the following method:


Init(X,Y:byte;Tit:string;Act:tAction);



11-40 User's Guide

--------------------------------------------------------------------------------

This method initializes the button and must be called first. The first
two parameters specify the upper left (X,Y) coordinate of the button.
The third parameter is the title which will be displayed in the button.
The title may include embedded highlight ('~') characters. The fourth
parameter is a member of the enumerated type tAction, which indicates
what action to take when the button is selected.


Listed below is an extract of the program DEMIO17.PAS. This program is
an enhancement to DEMIO12.PAS. Two buttons have been added to the dia-
log box. Compare the display of the new program, shown in figure 11.13,
with the button-less version in figure 11.10 (page 11-30).

procedure InitVars;
{}
begin
{...}
OK.Init(23,14,' ~O~K ',Finished);
OK.SetHotkey(79);
Cancel.Init(36,14,' C~a~ncel ',Escaped);
Cancel.SetHotkey(65);
{...}
end; {InitVars}




Figure 11.13 [SCREEN]
3D Strip
Buttons



Controlling Defaults with IOTOT

One of the basic approaches in the Toolkit is to default as much as
possible! This saves you the chore of setting dozens of parameters like
display colors every time you want to perform a simple task. You can,
of course, change any of the default values to meet your specific
needs.

All the colors and default settings for user input are established by
the instance IOTOT^. IOTOT is a pointer to an object of type InputOBJ
and is designed specifically to give you control of the input defaults.
There are methods for setting display colors, field rules, the case of
string input, whether the fields are initially in insert mode, and so
on.

To modify the defaults, all you have to do is call one of the IOTOT^
methods. Before analyzing the detailed method syntax, you need to be
aware of the wealth of colors used by the Toolkit. Most display set-
tings require four different color attributes to be specified. The



Controlling User Input 11-41

--------------------------------------------------------------------------------

first two attributes are used when the field is highlighted, i.e. when
the user is editing the field, and the second two attributes are used
when the field is not highlighted. You may recall that the Toolkit can
display any string in two colors using the method WriteHi (discussed on
page 5-3). Many of the strings in the IO objects also support the two
colors capability, e.g. field labels, button text, and check boxes.
That is why the color setting methods need to use two colors when the
field is highlighted, and two colors when it isn't, making a total of
four colors for each category.




Don't forget that the Toolkit uses a combined foreground/back-
ground attribute to define each color. Refer to page 3.11 for
further information.


The following methods can be used to change the Toolkit IO defaults:


SetColLabel(Off,OffHot,On,OnHot:byte);

Specifies the display attributes for labels. The first two parameters
specify the display attributes when the field is not highlighted. The
first parameter is the normal attribute, and the second attribute is
the color used after the embedded highlight character, e.g. ~. The
third and fourth parameters specify the attributes to use when the
field is highlighted.


SetColButton(Off,OffHot,On,OnHot:byte);

Specifies the four display attributes for button text.


SetColGroup(Off,OffHot,On,OnHot:byte);

Specifies the four color attributes to use with radio button and check
box fields.


SetColList(Off,OffHot,On,OnHot:byte);

Specifies the four colors to use for list fields.


SetColField(Off,On,Mask,Inactive:byte);

Specifies the colors to use with standard string fields. The first
parameter is the display color when the field is not highlighted, the
second parameter is the color when the field is highlighted, the third
parameter is the color to display formatting characters in PictureIOOBJ
fields, and the fourth parameter is the default display color for any
inactive (i.e. non-selectable) field.


11-42 User's Guide

--------------------------------------------------------------------------------

Note: For consistency, the Toolkit does not allow you to change
the display attributes of an individual field on an input form.
The attributes are always derived from IOTOT at display time. You
must use the methods SetColLabel, SetColButton, SetColGroup, Set-
ColList, and SetColField to change the display attributes of all
the field types in the relevant category.





SetColMsg(Col:byte);

Sets the color of the message which is displayed when the field is
highlighted. Specify an attribute of zero, if you want the current
display attribute to be used.


SetIns(On:boolean);

Controls whether the input fields are initially in insert (True) or
overtype (False) mode.


SetRules(Rules:byte);

Sets the default field rules (refer to page 11-12 for further informa-
tion).


SetPadChar(Pad:char);

When a field value does not entirely fill the allotted field, the
unused characters are represented by displaying a pad character. By
default, this value is set to a dot (ASCII characters 250). This method
is used to change the pad character, and one of the most common alter-
natives is a space, e.g. IOTOT^.SetPadChar(' ');.


SetJust(Just:tJust);

This method is used to set the default justification of the string
fields (see page 11.13).


SetCursor(Curs: tCursPos);

This method controls where the cursor is positioned when an input field
is highlighted (see page 11.13).


SetCase(Cas:tCase);

This method can be used to control whether the Toolkit automatically
adjusts the case of any of the string field objects, when the user
leaves the field (see page 11.13).

Controlling User Input 11-43

--------------------------------------------------------------------------------

SetForceCase(On:boolean);

The SetForceCase method is used to control whether the case of the
string input is adjusted while the user is typing in the string. Pass a
True parameter to force the case adjustment (as specified with the
method SetCase) every time a character is pressed. Pass a False parame-
ter if you want the string to be adjusted only when the user moves to
another field.


The following function methods return information about the current
default settings:


LabelCol(Element:byte): byte;

This function method returns the current attribute for displaying field
labels. Pass a parameter with a value between 1 and 4 to indicate which
attribute you want to determine. The parameter values represent the
following colors:

1 Not highlighted normal attribute.
2 Not highlighted high attribute.
3 Highlighted normal attribute.
4 Highlighted high attribute.


ButtonCol(Element:byte): byte;

Returns the attribute byte of the Button text.


GroupCol(Element: byte): byte;

Returns the attribute byte of radio button and check box fields.


ListCol(Element:byte): byte;

Returns the attribute byte of the list fields.


FieldCol(Element:byte): byte;

Returns the attribute byte of the string fields. Pass a parameter with
a value between 1 and 4 to indicate which attribute you want to deter-
mine. The parameter values represent the following colors:

1 Highlighted attribute.
2 Not highlighted attribute.
3 Attribute of mask character in picture fields.
4 Attribute of inactive (non-selectable) fields.


MessageCol: byte;


11-44 User's Guide

--------------------------------------------------------------------------------

Returns the attribute used for writing the highlighted field's message.


InputPadChar: char;

Returns that character which is used to fill a field when the input is
shorter than the field length.


InputJust: tJust;

Returns the default string justification (see page 11-13)


InputCursorLoc: tCursPos;

Returns the default cursor position (see page 11-13).


InputCase: tCase;

Returns the default case setting for string fields (see page 11-13).


InputForceCase: boolean;

Returns true if user input is forced to a specific case when each
character is input.


If you want to reset all the IOTOT settings back to the original Tool-
kit defaults, all you have to do is call the SetDefaults method as
follows:

IOTOT^.SetDefaults;

By looking at the actual Toolkit code for the SetDefaults method, you
can quickly determine the default values.

procedure InputOBJ.SetDefaults;
{}
begin
if Monitor^.ColorOn then {color System}
begin
SetColLabel(78,76,79,76);
SetColButton(32,46,47,46);
SetColGroup(48,62,63,62);
SetColList(48,62,31,30);
SetColField(48,31,23,71);
end
else
begin
SetColLabel(112,126,127,126);
SetColButton(32,46,47,46);
SetColGroup(48,62,63,62);


Controlling User Input 11-45

--------------------------------------------------------------------------------

SetColList(48,62,31,30);
SetColField(48,31,23,24);
end;
SetColMsg(0);
vInputPad := chr(250);
vCase := Leave;
vForceCase := false;
vInputJust := JustLeft;
vCursorLoc := CursPrev;
vInsert := false;
vRules := AllowNull;
end; {InputOBJ.SetDefaults}



Form Management

In this section, the various techniques for combining a collection of
fields into a form will be explained. You have already learned the
complicated stuff! All you have to do is create a FormOBJ instance and
tell it which field object to include in the form.

FormOBJ is the form manager and is located in the totIO1 unit. To build
a form, initialize the FormOBJ instance, add the fields that will
create the form, and instruct the Toolkit to process the user input.
The following FormOBJ methods perform these services:


Init;

This method initializes the FormOBJ instance, and should always be
called first.


AddItem(var NewItem: ItemIOOBJ);

This method should be called once for every field on the form. The only
passed parameter is an object descended from ItemIOOBJ, i.e. any of the
objects discussed so far in this chapter.


Go:tAction;

Having added all the items, call the function method Go to activate the
form, and process the user's input. The function returns one of the
following members of the enumerated type tAction: Finished, Escaped,
Stop1 through Stop9. The value returned will depend on which button or
key the user pressed. Based on the return value, you can decide how to
process the user-entered data.



11-46 User's Guide

--------------------------------------------------------------------------------

In addition to the standard user input fields, the totIO1 unit includes
a special object, ControlKeysIOOBJ, which is used to control how the
user moves between fields and terminates input. Every form you create
should include a ControlKeysIOOBJ instance. ControlKeysIOOBJ objects
provide the following three methods:


Init;

This method initializes the object and must be called first. The object
actually provides the Toolkit with four special keys: the key to move
on to the next field, the key to move back to the previous field, the
key to finish the edit session, and the key to abort the edit session.
When the ControlIOOBJ object is initialized, these keys are set to
[KEYCAP], [KEYCAP], [KEYCAP] and [KEYCAP], respectively.


SetKeys(Next,Prev,Fin,Esc:word);

This method is used to override the default keys. The method is passed
the four key codes which represent the keys for moving to the next
field, moving back to the previous field, to finish editing, and to
abort editing. For example, the statement

SetKeys(336,328,335,27);

will set the keys to [KEYCAP], [KEYCAP], [KEYCAP] and [KEYCAP]. Be
careful which keys you select. For example, if you have a word wrap
field, you probably don't want to use the up and down arrows. Each time
the user presses the down arrow to edit the next line, he/she will jump
to the next field!


Done;

This should be called to dispose of the object when it is no longer
required.




Listed below is the example DEMIO2.PAS, which was first introduced at
the beginning of the chapter. It shows how to use some of these basic
FormOBJ methods. Refer back to figure 11.2 on page 11-4 to see the
resultant output.

program DemoIOTwo;
{demIO2 - full field input}

Uses DOS, CRT,
totFAST, totIO1, totIO2;



Controlling User Input 11-47

--------------------------------------------------------------------------------

Var
Name: LateralIOOBJ;
Phone: PictureIOOBJ;
Price: FixedRealIOOBJ;
Keys: ControlkeysIOOBJ;
Manager: FormOBJ;
Result: tAction;

procedure InitVars;
{}
begin
with Name do
begin
Init(35,5,20,40);
SetLabel('Vendor Name');
end;
with Phone do
begin
Init(35,7,'(###) ###-####');
SetLabel('Tel');
end;
with Price do
begin
Init(35,9,8,2);
SetLabel('Unit Price');
SetValue(250.0);
SetMinMax(0.1,12250.0);
SetRules(EraseDefault);
end;
Keys.Init;
end; {InitVars}

begin
ClrScr;
Screen.TitledBox(15,3,65,11,76,79,78,2,' Quicky Input Demo ');
Screen.WriteCenter(25,white,'Press TAB to switched fields and
press ESC or F10 to end');
InitVars;
with Manager do
begin
Init;
AddItem(Keys);
AddItem(Name);
AddItem(Phone);
AddItem(Price);
Result := Go;
if Result = Finished then
{update the database..}
else



11-48 User's Guide

--------------------------------------------------------------------------------

{call Esc routine};
end;
end.




The order in which the fields are added using AddItem will be the order
in which the user will jump from field to field. The following FormOBJ
method can be used to control which field is highlighted when the Go
method is called:


SetActiveItem(ID:word);

This method instructs the Toolkit on which field to highlight first.
The only parameter is the field ID of the field to be highlighted.
Don't forget that any field can have a unique ID by calling the method
SetID. By default, all fields have an ID of zero.



Hotkey Fields

By now, you should know that any field can have a hotkey assigned with
the method SetHotKey. There is one remaining type of field that has not
yet been discussed. Namely, HotkeyIOOBJ objects. These fields are "in-
visible" and are used to add special Hotkeys to the form.

HotkeyIOBJ objects only have the following two methods:


Init(HK:word;Act:tAction);

A HotkeyIOOBJ object has only two properties. It has a keycode, which
represents the key that must be pressed to invoke it, and it has an
action code of type tAction, i.e. None, NextField, PrevField, Finished,
Escaped, Refresh, Signal, Enter, Help, Stop1..Stop9. Whenever the user
presses the assigned hotkey, the specified action is invoked. For exam-
ple, if you want to assign the key [KEYCAP] (in addition to [KEYCAP])
to end the edit session, you would initialize a HotkeyIOOBJ instance as
follows: Init(301,Finished);


Done;

This disposes of the object.




Moveable Forms

The object WinFormOBJ is a descendant of FormOBJ, and provides the same
services with one important enhancement. WinFormOBJ manages an input


Controlling User Input 11-49

--------------------------------------------------------------------------------

form on a moveable window. It is ideal for creating moveable dialog
boxes. The Toolkit itself takes advantage of WinFormOBJ to create the
pop-up message objects and the moveable directory dialog box.

WinFormOBJ inherits the following methods from FormOBJ:

Init;
AddItem(var NewItem: ItemIOOBJ);
Done;

Additionally, WinFormOBJ has a function method Win which returns a
pointer to the MoveWinOBJ instance on which the form is built. To
modify the window size and other properties, just call Win^.method,
where method is any MoveWinOBJ instance.

If you are going to create a window-based form using WinFormOBJ, be
sure to create each individual field objects with relative (X,Y) coor-
dinates. In other words, the top left of the form window will be at
coordinates (1,1).

Important Note: before calling the method Go, call the method Draw.
This instructs the WinFormOBJ object to display the window and save the
underlying screen contents.

Refer to the on-disk example DEMIO18.PAS for a full example illustrat-
ing the WinFormOBJ object. DEMIO18.PAS is actually an enhancement to
the program DEMIO17.PAS, creating a text-search dialog box.



Determining User Input

When the user has edited the form, you probably want to know what data
was entered! First, be sure to check the tAction code returned by the
FormOBJ method Go. This will indicate whether the user escaped, or
really wanted the data processed.

The only form input objects which update the original data source are
the word wrapping objects WWArrayIOOBJ and WWLinkIOOBJ. The Toolkit
automatically modifies the data passed to these objects. In all other
cases, you should call each individual object's GetValue method to
determine the user's input.

Review the demo programs DEMIO5,8,10,13,14 to see examples of how to
determine user input. Also, the demo programs in the last section More
Examples! provide still further examples.



11-50 User's Guide

--------------------------------------------------------------------------------

Advanced Techniques

For the majority of situations, you have learned all you need to know
to master form input. However, the Toolkit provides another level of
sophistication for developers who really want to customize their input
forms. Although this section is called Advanced Features, it does not
mean that these features are complicated. The only reason for separa-
ting them into a special section is because you will probably use them
less frequently.

There follows descriptions of how to intercept every character that is
pressed, how to validate individual fields before allowing the user to
leave, and how to implement a help system. The concept of raising sig-
nals between dependent fields is also introduced.



Intercepting Every Character Press

Many of the Toolkit's units include character hooks, which provide a
way for you to nominate a procedure or function to be called every time
a character is pressed. This allows you to intercept each character and
if appropriate, invoke a special routine. You can even change the value
of the character pressed. The FormOBJ and WinFormOBJ objects also pro-
vide a character hook facility.

A character hook is an external procedure which is called every time a
key or mouse button is pressed. To utilize the character hook facility,
all you have to do is create a function following some specific rules,
and then call the FormOBJ method SetCharHook to instruct the Toolkit to
use your function.

For a function to be eligible as a character hook it must adhere to the
following rules:

Rule 1 The function must be declared as a FAR function. This can be
achieved by preceding the function with a {$F+} compiler
directive, and following the function with a {$F-} direc-
tive. Alternatively, Turbo 6 users can use the new keyword
FAR following the function statement.

Rule 2 The function must be declared with four passed parameters.
Parameter one must be a variable parameter of type word.
This parameter indicates which key the user just pressed,
and you may change the value of this parameter to return a
different key. The second and third parameters must be
variable parameters of type byte, and they represent the X
and Y coordinates of the mouse at the time the key was
pressed. The fourth parameter is a variable, and must be of
type word. This parameter indicates the field ID of the
currently active field. This field can be changed to another
ID if you want the user to jump to a different field.



Controlling User Input 11-51

--------------------------------------------------------------------------------

Rule 3 The function must return a value of type tAction. This is an
enumerated type which indicates to the Toolkit how to
proceed. The members of the enumerated type are: None,
NextField, PrevField, Finished, Escaped, Refresh, Signal,
Enter, Help, Stop1..Stop9. If you want the edit session to
terminate, return Finished, Escaped, or Stop1 through Stop9.
If you have changed, inserted, or deleted any items in the
visible list, return Refresh. The Toolkit will then re-
display the entire form contents.

Rule 4 The function must be at the root level, i.e. the function
cannot be nested within another procedure or function.

The following function declaration follows these rules:

{$F+}
function MyCharHook(var K:word;
var X,Y: byte;
var FieldID:word): tAction;
begin
...{function statements}
MyCharHook := NextField;
end;
{$F-}


The following method SetCharHook is then called to instruct the Toolkit
to call your function every time a key is pressed:


SetCharHook(Func:CharFunc);

This method is passed the function name of a function declared using
the rules outlined above, e.g. SetCharHook(MyCharHook);.


Listed below is an extract from the demo program DEMIO19.PAS. This file
is a variation on our old favorite DEMIO2.PAS. In this case, a charac-
ter hook has been added to intercept the key [KEYCAP]. If this key is
pressed, a message showing the current time is displayed. Notice that
if [KEYCAP] is pressed, the hook function replaces the actual key with
a value of 0. This stops the active field from trying to process the
key - a zero key is ignored by the Toolkit. Finally, the hook function
returns a value of None, indicating that the form manager does not need
to take special action.

{$F+}
function ShowTime(var K:word; var X,Y:byte; var ID:word):tAction;
{}
var Msg: MessageOBJ;
begin
if K = 276 then {Alt-T}




11-52 User's Guide

--------------------------------------------------------------------------------

begin
with Msg do
begin
Init(1,'The Time M''Lord');
Addline('');
AddLine(padcenter(CurrentTime,25,' '));
AddLine('');
Show;
Done;
end;
K := 0;
end;
ShowTime := none;
end; {ShowTime}
{$F-}

begin
{...}
with Manager do
begin
Init;
AddItem(Keys);
AddItem(Name);
AddItem(Phone);
AddItem(Price);
SetCharHook(ShowTime);
Result := Go;
{...}
end;
end.



Validating Input

As well as a character hook, the FormOBJ objects provide leave field
and enter field hooks. These functions are called when the user tries
to leave a field, and when the user tries to enter a field. The leave
field hook provides a way to ensure the contents of a field are valid
before moving to another field. The enter field hook can be used to
take some action before entering a field, e.g. display a warning mes-
sage, or move the user to another field if a specific condition is not
met.

Like the character hook, both field hooks must adhere to the following
common rules:

Rule 1 The function must be declared as a FAR function.



Controlling User Input 11-53

--------------------------------------------------------------------------------

Rule 2 The function must return a value of type tAction. This is an
enumerated type, which indicates to the Toolkit how to
proceed.

Rule 3 The function must be at the root level.



The hooked procedure's passed parameters are different for each hook
type, as follows:

Leave The function must be declared with one variable passed
parameter of type word. This parameter represents the field
ID of the field the user is leaving. This parameter can be
changed to another field to instruct the Toolkit to jump to
a different field.

Enter The function must be declared with two passed parameters.
The first parameter is a variable parameter of type word.
This parameter identifies the ID of the field the user is
about to enter. This parameter may be modified, to instruct
the Toolkit to jump to a different field. The second parame-
ter is of type word, and it represents the ID of the field
the user just left.

Listed below are two code sample procedures which adhere to the rules
for leave and enter field hooks.

{$F+}
function MyEnterHook(var NewID:word; LastID: word):tAction
begin
...{function statements}
MyEnterHook := none;
end;
{$F-}

{$F+}
function MyLeaveHook(var LastID: word):tAction
begin
...{function statements}
MyLeaveHook := none;
end;
{$F-}


The FormOBJ methods SetLeaveHook or SetEnterHook can then be called to
instruct the Toolkit to call the specified function whenever a user
tries to leave or enter a field.



11-54 User's Guide

--------------------------------------------------------------------------------

Context Sensitive Help

The fourth category of FormOBJ user hooks is the Help hook. The Help
hook provides a way of implementing context sensitive help into your
form.

To implement a help hook, all you have to do is create a procedure
following some specific rules, and then call the FormOBJ method SetHel-
pHook to instruct the Toolkit to use your function.

For a function to be eligible as a character hook it must adhere to the
following rules:

Rule 1 The procedure must be declared as a FAR procedure.

Rule 2 The procedure must be declared with a single passed parame-
ter of type word. This parameter identifies the ID of the
highlighted field at the time the user requested help.

Rule 3 The procedure must be at the root level.

The following code fragment shows a procedure which adheres to these
rules.

{$F+}
function MyHelpHook(LastID: word);
begin
...{help display statements}
end;
{$F-}


If you go to the trouble of creating a help system, you ought to give
the user some way of requesting help! The two best ways to add help are
with a hotkey and with a help button. Either way is easy, and you ought
to consider using both. The following code fragment shows how to imple-
ment them:

var
HelpBut: Strip3dIOOBJ;
F1key: HotkeyIOOBJ;

begin
{...}
HelpBut.Init(34,12,' ~H~elp ',Help);
HelpBut.SetHotkey(291);
HelpBut.SetID(HelpID);
F1Key.Init(315,Help);
{...}
end.



Controlling User Input 11-55

--------------------------------------------------------------------------------

Notice that the help button is assigned an ID of HelpID. HelpID is a
constant defined in the totIO1 unit. The likelihood is that the user
wants help on the highlighted field, and doesn't actually want to move
to the help button. By assigning an object an ID of HelpID, the Toolkit
knows not to swap to it when it is selected with a mouse button or
hotkey.

Refer to the demo program DEMIO20.PAS for a full example of how to
implement a help system. This program is a further enhancement to the
search dialog box demo program discussed earlier. Figure 11.14 illus-
trates the display generated when the user asks for help.



Figure 11.14 [SCREEN]
Add a Help

System



Creating Descendant Objects

The FormOBJ object provides four different hooks for customizing the
form input to meet your specific needs. If you think there may be an
OOP way to achieve the same results you are right. You can create a
descendent object from either FormOBJ or WinFormOBJ, and replace the
following virtual methods:

function CharTask(var K:word; var X,Y:byte;var FieldID:word):tAction;
function LeaveTask(var FieldID:word):tAction;
function EnterTask(var NewID:word; OldID;word):tAction;
procedure HelpTask(ID:word);

The passed parameters to these virtual methods are exactly the same as
the ones described earlier for the hooks.

Refer to chapter 9: Managing Lists page 9-32 for a comparison of hooks
and virtual methods.



In some special circumstances you will want to create fields which
interact. A good example can be found in the Toolkit object DirWinOBJ
(discussed in chapter 10). This object has three main fields - a
filename input field, a list of matching files, and a list of directo-
ries and drives. If the user enters a new file mask, the file list
needs to be refreshed. Similarly, if the user changes directories, the
file list and the directory list need to be updated.

The solution is for the modified field to raise a signal when changes
need to be made to other fields. When a field raises a signal, the
Toolkit passes the signal to every other field in turn, and each of
these fields may itself raise signals. Every input field object has the
following virtual methods:



11-56 User's Guide

--------------------------------------------------------------------------------

procedure RaiseSignal(var TheSig:tSignal);
procedure HandleSignal(var BaseSig:tSignal; var NewSig:tSignal);
procedure ShutDownSignal(var BaseSig:tSignal);

Refer to Part 2: Extending the Toolkit for further information about
creating input objects which raise and handle signals.



More Examples!

There are several additional on-disk examples included in the Toolkit.
These examples combine many of the features described in this chapter
to provide powerful input routines. For example, IODEM21.PAS shows how
you might use the objects to create a database access program, and
IODEM22.PAS illustrates how you can use PgUp and PgDn to implement a
double input screen.


  3 Responses to “Category : Pascal Source Code
Archive   : TOTDOCS.ZIP
Filename : CHAPT11.TXT

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/