                              General Principles

                                    "Nay, but you, who do not love her.
                                     Is she not pure gold my mistress."
                                                Browning, 1812-1889

The Unit Variables

          Gold is designed such that with a few lines of code, you can
     achieve a great deal of functionality. For example, with just a
     single line of code, you can display a file input dialog box
     showing files, directories, etc. This simplicity is possible
     because Gold has a rich set of default properties; for example, the
     color of the push buttons and the shadow style of windows.

          If you don't like the defaults, you can change them! Each unit
     in Gold contains a special record that defines defaults pertinent
     to the unit. The name of this record follows a standard convention:
     the name begins with the unique characters in the unit name, and
     ends with the four characters VARS. For example, the GOLDDIR.PAS
     unit contains the global variable DIRVARS, the GOLDCAL.PAS unit
     contains the global variable CALVARS, and the GOLDMENU.PAS unit
     contains the global variable MENUVARS. And so on.

          You can modify elements of these records to customize the
     appearance and behavior of Gold. For example, you can redefine the
     keystrokes used to navigate a calendar by changing the NextMKey,
     PrevMKey, NextYKey and PrevYKey elements:

          CalVars.NextMKey := 360;
          CalVars.PrevMKey := 361;
          CalVars.NextYKey := 362;
          CalVars.PrevYKey := 363;

          Similarly, the default calculator style can be customized by
     assigning a value to the CalcVars' element Style, as follows:

          CalcVars.Style := CalcWide;

          Throughout the user's guide, references are made to relevant
     elements of the global variables defined in each unit. Just
     remember that we have tried to make Gold very flexible and if
     you're not sure how to customize the properties of a Gold
     component, look at the appropriate XXXVARS variable in the unit
     source code, and see whether there is a relevant element that you
     can customize.

          A different approach is used for customizing colors. Refer to
     the section Customizing Display Colors.

Compiler Directives and GOLDFLAG.INC

          Every unit in Gold has an include statement to include the
     file GOLDFLAG.INC. This file is designed to specify all the common
     compiler directives that you want to apply to every unit in your
     program.

          The compiler directives added to your main program apply only
     to that module and not to any of the units used by that program. So
     if you wanted to ensure that a specific compiler directive is
     operative in every unit, you would have to edit every units source
     code and add the appropriate directive. Yes, you could add them to
     the IDE options menu, but if you work on multiple projects, it is a
     chore making sure that you have the appropriate directives set. The
     most foolproof way is to set the directives in an include file.

          Whenever you develop a program using Gold, you should add an
     include directive to the main program and any other units you
     develop, as follows:

          {$I GOLDFLAG.INC}

          Any compiler directives you set in the file GOLDFLAG.INC will
     then affect your code and the Gold code. The GOLDFLAG.INC file
     contains a set of master conditional compiler directives named
     FINAL, OVERLAY, FLOAT, FLOATEM, NOVGACHARS, CUTANDPASTE, WORDWRAP
     and TTT5.  By enabling or disabling these master directives, you
     are setting families of specific directives. For example, by
     enabling the FINAL directive, you are indirectly setting the state
     of the range checking, stack checking, debug, and linker
     directives. These master directives are located at the top of
     GOLDFLAG.INC, and by default, some are enabled and others are
     disabled. In the disabled state, the $DEFINE directive is broken up
     with spaces, e.g. { $ DEFINE OVERLAY}

     To activate a directive, simply remove the leading spaces, e.g.

     {$DEFINE OVERLAY}

          Listed below are the default settings of the master compiler
     directives:

          { $ DEFINE FINAL}
          { $ DEFINE FLOAT}
          { $ DEFINE FLOATEM}
          { $ DEFINE OVERLAY}
          { $ DEFINE NOVGACHARS}
          { $ DEFINE TTT5}
          {$DEFINE CUTANDPASTE}
          {$DEFINE WORDWRAP}

          As the listing shows, all the major directives are disabled,
     and the two word processing directives are enabled. The purpose of
     the individual compiler directives are discussed below.

FINAL

          During program development it is a good idea to switch on
     range checking and stack checking, etc. These directives keep you
     honest and allow the compiler to quickly identify potential
     problems. For example, if you try to assign a value of 300 to a
     byte, the problem will be identified with a range error at
     run-time. The bad news is that programs compiled in the check
     everything state tend to be slower and larger than their carefree
     brethren. So, once you have debugged and tested your program and
     you are confident that the checking is no longer necessary, you
     should switch off the appropriate directives.

          The FINAL compiler directive is designed to simplify this
     task. During program development, you should disable the FINAL
     compiler directive, and then enable it when you are ready to build
     and distribute your production program.

          IMPORTANT NOTE: If you want to debug your program using the
     internal or external debugger, you must disable the FINAL
     directive.

          When FINAL is disabled, another directive CHECK is defined.
     When CHECK is enabled, Gold uses some additional code to check that
     sensible parameters are passed to procedures. For example, in
     GoldDB checks are made to ensure that the specified Field number
     exists.

FLOAT

          Gold supports extended reals. By default, Borland Pascal uses
     6-byte reals, but using compiler directives, varying precision
     reals can be used, i.e. Single, Double, Extended and Comp.

          If you want to use the higher precision reals, enable the
     FLOAT compiler directive. Gold will automatically set the
     appropriate compiler directives.

          When FLOAT is enabled, Gold supports all real types. When
     FLOAT is disabled, all the real types are type-cast to the base
     REAL type. In other words, you can still reference the types
     SINGLE, DOUBLE, EXTENDED and COMP in your code, but they all appear
     to the compiler as plain old REAL. The type-casting is performed by
     the small unit GOLDREAL.PAS.

          If your program is compiled with FLOAT enabled and it is going
     to be executed on a computer without a math co-processor installed,
     the FLOATEM compiler directive (discussed next) must also be
     enabled. Note that the GOLDHARD function MathChip will return true
     if the system has a match co-processor installed.

FLOATEM

          Borland Pascal is capable of emulating an 8087 math
     co-processor if the PC does not have one installed. Enable the
     FLOAT and FLOATEM (short for float emulation) directives if you
     want to use high precision reals on PCs without a math
     co-processor.

OVERLAY

     Any of the Gold units can be overlaid.

          Borland Pascal requires that all overlaid units include the
     {$O+} compiler directive, and that all procedures and
     functions are compiled using the far calling method, i.e. they
     are compiled in the {$F+} state. By activating the OVERLAY
     directive in GOLDFLAG.INC, all the Gold units will be compiled
     in the {$F+,$O+} state.

          To help you create programs with overlays, Gold includes the
     template file GOLDOVR.PAS. When you need to overlay some Gold
     units, you should make a copy of GOLDOVR.PAS to a new file, e.g.
     ACCNTOVR.PAS. Then edit the name of the program overlay file
     (default: PROGRAM.OVR) to reflect the name of the file which will
     contain the compiled overlay code, e.g. ACCOUNTS.OVR.

          The USES statement of the main program must list the AccntOVR
     file (or whatever name you gave the unit) before the Gold units
     which are to be overlaid. For example:

          program AccountsPayable;
          {ACCOUNTS.PAS}
          {$F+}
          USES OVERLAY,DOS,CRT,
               AccntOVR, GoldFAST, GoldWIN, GoldIO;

          {$O GoldFAST}
          {$O GoldWIN}
          {$O GoldIO}

          begin
             {.....}
          end.

          In the example, by the time the program tries to load
     GoldFAST, the overlay manager has already been installed (by
     AccntOVR) and so the GoldFAST initialization section can be
     successfully executed as an overlay.

          Review the demo program DEMOV1.PAS and its accompanying unit
     DEMOV1UN.PAS to see these techniques in action.

NOVGACHARS

          One of the innovations in Gold is the ability, on VGA systems,
     to use custom characters for drawing box borders, window icons and
     the like (see the section Using Custom Characters below). The
     support for custom characters is woven into the fabric of the
     GoldFAST unit. If you have no intention of deploying these custom
     characters in your applications, you can save code and data
     resources by enabling the NOVGACHARS directive. Obviously, if this
     directive is enabled, your program won't be able to use the special
     drawing characters.

TTT5

          Many Gold developers have existing programs written with
     TechnoJock's Turbo Toolkit version 5.0. Unfortunately, existing
     programs cannot simply be ported to Gold by modifying the USES
     statement to use the Gold units instead of the TTT units. The
     reason? A number of fundamental changes (i.e. improvements!) were
     made in the basic toolkit design. For example, all underscores were
     removed from procedure and function names, and color attributes are
     passed as a single (combined) byte rather than separate foreground
     and background attributes.

          Although we recommend that you change your programs to use the
     new naming and parameter conventions, we do recognize what a pain
     this can be! By enabling the TTT5 direction in GOLDFLAG.INC, you
     can get the best of both worlds, because Gold automatically
     supports the majority of old-style function calls.

          For example, with TTT5 enabled, you could call
     ActivateVisibleScreen or the old-style Activate_Visible_Screen.

          There is, however, a complication because Borland Pascal does
     not allow two procedures to have the same name within a unit. In
     many situations Gold has changed a procedure's parameters but used
     the same name. For example, Gold WriteAT accepts four parameters:
     the X,Y coordinate, the combined display attribute, and the string.
     In TTT 5.0,  the same procedure accepted 5 parameters -- the
     attribute was passed as a foreground and a background byte. Borland
     Pascal doesn't allow two procedures to be named WriteAT. So, we
     named the old-style procedure FBWriteAT; solving the naming problem
     and giving an indication of the main difference between the
     old-style procedure and its new counterpart.

          Refer to the GoldDust paper "Porting TTT Applications" if you
     are trying to port an old TTT application to use Gold. This paper
     lists all the old TTT 5.0 exported procedures, identifiying the
     TTT5-directive equivalent along with the Gold equivalent.

          The GoldMEMO unit provides sophisticated text editing
     capabilities including cut-and-paste and word-wrap. If you only
     need a plain text editor, and don't need these features, you can
     disable the features and reduce the program size by using the
     CUTANDPASTE and WORDWRAP compiler directives.

CUTANDPASTE

          The CUTANDPASTE directive controls whether Gold will support
     text cut-and-paste in the editing functions. Disable this directive
     if you want to use an editor but don't need cut-and-paste; the
     program will be smaller.

WORDWRAP

          The WORDWRAP directive controls whether Gold will support
     automatic word-wrapping in the text editing functions. Disable this
     directive if you want to use an editor but don't need word-wrap;
     the program will be smaller.

Handling Errors

          Errors happen! As a developer you understand, more than most,
     that errors can occur while a program is running.

          Gold will always try to deal with an error in an appropriate
     way. When a program is compiled with the FINAL directive disabled,
     Gold will alert you to errors (typically in a PromptOK message),
     whether they are trivial or mind-blowingly important. However, when
     the program is compiled with FINAL enabled, the user will not be
     made aware of the error if the consequence of the error is probably
     trivia. If the error is profound, (e.g. there is no memory left) a
     dialog will be displayed to the user.

          All the Gold units that have the potential to fail at run-time
     (which is the majority), have a function which can be called to
     determine whether the last operation was a success. The name of the
     function is LastXXXError, where XXX is the unique identifier in the
     unit name, e.g. LastWINError, LastCALCError, etc. If you are
     writing a commercial-quality application, you should always call
     these last error functions when there is a chance that the last
     operation failed.

          The following example shows how to test for an error in the
     RunCalendar function:

          Answer := RunCalendar(TodayInJul,' A Calendar! ');
          if LastCalError <> 0 then
             promptOK(' Error ','Unable to display calendar')
          else
          begin
             if CalVars.ChooseDay then
             begin
                if Answer = 0 then
                   PromptOK('','You escaped!')
                else
                  PromptOK('',' You selected '
                           +FancyDateStr(Answer,false,false));
             end;
          end;

          Refer to the Gold Reference manual for a complete list of all
     the LastXXXError functions.

ERROR CUSTOMIZATION

          Most of the Gold units are organized so that international
     users can replace the English error messages with local language
     messages.

          The GoldMisc unit includes the following type declaration:

     ErrMsgFunc = function (Ecode:integer):string;

          To use custom error messages, all you need to do is create a
     far procedure which is declared the same as the ErrMsgFunc defined
     above. The function is passed an error code and should return a
     string explaining the nature of the error. The following is an
     extract of the English error messages in GoldMisc (by way of an
     example):

          function MyMiscEMsg(ECode:integer): string;
          {}
          begin
             case Ecode of
               1001: MyMiscEMsg := 'Invalid drive.';
               1002: MyMiscEMsg := 'Failure changing directory';
               1003: MyMiscEMsg := 'Failure making directories';
               else
                  MyMiscEMsg := 'Internal Misc error';
             end; {case}
          end; { MyMiscEMsg }

          Having created a far procedure with the custom error messages,
     you must then instruct Gold to use your function in place of the
     standard message function. To do this, assign the procedure to the
     local variable EmsgFunc which is stored in the XXXVARS record
     (discussed in the first section of this chapter). The following
     code fragment shows this technique being used to assign custom
     messages for the GoldMISC unit:

          MiscVars.EMsgFunc := MyMiscEMsg;

Understanding Hooks

          Good though Gold is, there will be situations where Gold
     doesn't meet your specific applications needs. In many cases, the
     XXXVARS structure will provide you with ways to customize Gold. For
     example, if you want change the window type for the prompt dialogs,
     you could use the following statement to instruct Gold to use a
     window style of 1:

     WinVars.PromptStyle := 1;

          In sophisticated applications, you might encounter some
     behavior or characteristic which cannot be readily changed using
     the above-mentioned technique. Hey, we can't think of everything!

          The solution to these truly custom needs lies in user-defined
     hooks which interact with low-level internal routines. A hook is a
     procedure or function which is called at strategic times during the
     execution of an application. For example, a user-defined hook can
     be called every time a user tries to leave an input field in a
     form. Another example is a hook that is called every time a user
     changes selections on a menu.

          In simple terms, a hook is a user-defined procedure which is
     called by Gold whenever a specific event occurs. But a hook goes
     beyond a simple notification event; a hook can actually change the
     program behavior. For example, a form EnterFieldHook can redirect
     focus (i.e. the highlighted field) to a different field, and a
     character hook can replace the character Alt-A with the five
     characters "APPLE".

          There are over 30 hooks scattered about the product. If you
     find that a particular unit does not behave just how you would
     like, review the Hook section in the appropriate chapter and see if
     a hook will allow you to customize Gold's behavior.

CREATING A HOOK ROUTINE

          To take advantage of a hook, you must create a procedure or
     function with the exact declaration of the hook. In other words,
     the routine must be declared with the exact number and type of
     passed parameters, and (in the case of function hooks) the function
     must return the correct type. Refer to the specific documentation
     for a clarification of each hook's declaration.

          You must create the procedure or function at the root level of
     a program or unit, i.e. it must not be nested within a parent
     procedure or function.

          The procedure must be declared as a far procedure. You can do
     this by adding the far keyword on the procedure declaration line,
     or by using the {$F+} compiler directive.

          The following hook is extracted from the demo program
     DEMIO6.PAS and shows a hind hook being used in an IO form to
     control whether field number 10 is enabled or disabled:

          {$F+}
          procedure MyHindHook(CurrentField:byte;var Refresh:byte);
          {}
          begin
             Refresh := RefreshNone;
             if CurrentField = 9 then {radio button}
             begin
                if (Cust.Radio = 4)
                and (FieldGetState(10) = FldOn) then
                begin
                   FieldSetState(10,FldOff);
                   Refresh := RefreshOthers;
                end
                else if (Cust.Radio <> 4)
                and not (FieldGetState(10) = FldOn) then
                begin
                   FieldSetState(10,FldOn);
                   Refresh := RefreshOthers;
                end;
             end;
          end; {MyHindHook}
          {$F-}

INSTALLING & REMOVING A HOOK

          Having created the hook procedure or function, you must
     instruct Gold to call the routine when the hook event occurs. Refer
     to the hook documentation in the appropriate chapter to determine
     how to install and remove hooks.

          In most cases, Gold provides Assign... and Remove...
     procedures for installing and removing hooks. For example, the
     following statement instructs Gold to use the MyHindHook procedure
     (defined above) to the IO hind hook:

          AssignHindHook(MyHindHook);

          If there is no Remove function, just assign the default hook,
     for example:

          AssignHindHook(NoHindHook);

Customizing Display Colors

          Colors, colors, colors. We get more calls about colors than
     anything. One person's ideal color is another person's anathema. If
     only PCs used green CRT tubes! We have finally realized that we
     cannot please everybody with our default colors. The next best
     thing is to make it easy for you to customize the colors to meet
     your own needs.

          The GoldTINT unit is designed to make it very easy for you to
     customize the default colors used in Gold. This unit provides a
     global variable named TINT which defines every color used in Gold.
     You can change a color using the procedure GoldSetColor which is
     defined as follows:

          GoldSetColor(Zone:TintElement; Col:byte);

          The first parameter identifies the TintElement (see Table
     3.1), and the second attribute is the color byte.

          Use the function GoldGetColor to determine the active color
     for a specific tint element.

          Gold uses a single byte to define the foreground and
     background colors. Table 3.2 (below) identifies all the supported
     color codes.


      Table 3.2

      Color Codes

                       Blk  Blu  Grn  Cyn  Red  Mgt  Brn
           Black         0   16   32   48   64   80   96
           Blue          1   17   33   49   65   81   97
           Green         2   18   34   50   66   82   98
           Cyan          3   19   35   51   67   83   99
           Red           4   20   36   52   68   84  100
           Magenta       5   21   37   53   69   85  101
           Brown         6   22   38   54   70   86  102
           Lt. Gray      7   23   39   55   71   87  103
           Dark Gray     8   24   40   56   72   88  104
           Lt. Blue      9   25   41   57   73   89  105
           Lt. Green    10   26   42   58   74   90  106
           Lt. Cyan     11   27   43   59   75   92  107
           Lt. Red      12   28   44   60   76   92  108
           Lt. Magenta  13   29   45   61   77   93  109
           Yellow       14   30   46   62   78   94  110
           White        15   31   47   63   79   95  111

                       Lt.  Dk.  Lt.  Lt.  Lt.  Lt.  Lt.
                       Gry  Gry  Blu  Grn  Cyn  Red  Mgt  Yel  Wht
           Black       112  128  144  160  176  192  208  224  240
           Blue        113  129  145  161  177  193  209  225  241
           Green       114  130  146  162  178  194  210  226  242
           Cyan        115  131  147  163  179  195  211  227  243
           Red         116  132  148  164  180  196  212  228  244
           Magenta     117  133  149  165  181  197  213  229  245
           Brown       118  134  150  166  182  198  214  230  246
           Lt. Gray    119  135  151  167  183  199  215  231  247
           Dark Gray   120  136  152  168  184  200  216  232  248
           Lt. Blue    121  137  153  169  185  201  217  233  249
           Lt. Green   122  138  154  170  186  202  218  234  250
           Lt. Cyan    123  139  155  171  187  203  219  235  251
           Lt. Red     124  140  156  172  188  204  220  236  252
           Lt. Magenta 125  141  157  173  189  205  221  237  253
           Yellow      126  142  158  174  190  206  222  238  254
           White       127  143  159  175  191  207  223  239  255


          The following example sets the display color of prompt titles
     (in the PromptOK dialogs) to yellow on red:

          GoldSetColor(PromptTitle,78);

          The GoldATTR unit includes a couple of features which help you
     assign new colors without having to look up values in Table 3.2.
     The unit includes 256 constants which correspond with all the
     possible color combinations. For example, the constant YellowOnRed
     has the value 78 ($4E in hex), and so by including GoldATTR in the
     uses clause, the above example could be simplified to the
     following:

          GoldSetColor(PromptTitle,YellowOnRed);

          The GoldATTR unit also includes the following procedures and
     functions to assist in handling foreground and background display
     attributes:

          CAttr(F,B:byte):byte;

          Accepts separate foreground and background attributes, and
     returns the combined attribute byte.

     FAttr(A:byte): byte;

          Accepts a combined attribute byte, and returns the foreground
     color.

          BAttr(A:byte): byte;

          Accepts a combined attribute byte, and returns the background
     color.

Blinking Colors

          On VGA systems, you can use the SetBlinking procedure to
     control whether light background colors are displayed with a
     normal, bright background, or as blinking characters on a dark
     color background. When SetBlinking is passed a TRUE value,
     bright/light background colors will cause the foreground colors to
     blink.

          Note that there is a hardware limitation; the blinking state
     applies to the entire display, not to an individual write
     statement. In other words, you cannot have some text with blinking
     characters in one portion of the display, and some other text with
     bright background colors in a different part of the display.

Using Custom Characters

          On VGA (or better) display systems, Gold uses a technique for
     drawing custom characters to give check boxes, radio buttons and
     windows a special graphical appearance.

          You can test whether the display system supports the custom
     characters by calling the function CustomCapable. The function
     returns TRUE if the custom characters are supported, otherwise
     FALSE is returned.

          By default, the normal ASCII character set is used. You can
     enable the custom drawing characters by calling the procedure
     UseCustomChars. Behind the scenes, Gold replaces the double-line
     drawing characters with a set of custom characters. So, if you are
     using the custom characters, you sacrifice the double line
     characters. Run the demo program DEMCUST1.PAS to see the character
     substitution.

          If, having called UseCustomChars, you do not get the special
     drawing characters, check that the conditional compiler directive
     NOVGACHARS (discussed earlier in this chapter) is not enabled.

          Once you have enabled the custom characters, you do not need
     to explicitly build your own boxes and buttons using these
     characters. Gold will automatically apply the new characters to
     windows, etc. provided you have selected a window style that uses
     these characters. See the demo program DEMWIN1.PAS for an example
     of these styles.

          You can write an application which takes full advantage of
     custom characters (such as the Gold installation program), and not
     have to worry about how the application will behave on systems
     which do not support these characters. Gold automatically changes
     the display characters so that the application looks professional
     on non-custom character capable systems.

          In addition to the standard custom drawing characters, Gold
     offers a special character set for drawing the 12 functions keys.
     Call the procedure UseCustomFunctionKeys to activate these custom
     characters.

          Call the procedure RemoveCustomChars to remove the custom
     character set and reinstate the double-line characters.
