





























                                     ALLCLIP.TEM (c)

                                     Version 5.6


                     Database system template for UI2 Programmer







                                      Preface

          Okay, kids, here we go again.  Another brand new (well, only used
          by a little old lady programmer from  Pasadena who took it out on
          Sundays  to   write  her  grandson's  Cost   Accounting  reports)
          template,  fresh  from the  shrink  wrap.   Never  mind  that the
          retailers have unwrapped the merchandise and played with it until
          they were tired, and then used their shrink wrap machines to make
          you think  it was factory  fresh.  Pretend  you don't know  these
          things about the world, or you'll go mad.

          This one corrects most all the problems  reported, including some
          bugs that have been  present even from the beginning.   Yes, I DO
          hear  your  requests (from  as  far  away as  Singapore),  and as
          always,  attempt  to be  responsive to  them.   In  particular, I
          advise  those  of you  working with  multiple  WWs to  reread the
          chapter on Large  Scale Systems, as  the rules have been  changed
          slightly to  protect the  innocent.   Also, READ  THE CHAPTER  ON
          INSTALLATION!  Things are a little different.

          The  most  exciting  news,  however, is  the  eminent  release of
          version  6.0!   That's right, with  over TWICE  the documentation
          (even  easier to  read  with lots  of  crosswords and  pictures),
          Microsoft mouse support, On-Line help within UI, more features in
          the Query by Example engine, a self-check template for ALLCLIP (a
          debugging tool), lots  more example WWs  and other goodies.   You
          can read all about this in the REGISTRATION chapter.

          As  always,  I  welcome your  suggestions,  criticisms, comments,
          winning  lotto tickets, and  support.  This  template wouldn't be
          where  it is today (and WHERE exactly IS it, today?) without your
          help.





















                                          i







                                  TABLE OF CONTENTS

          Preface . . . . . . . . . . . . . . . . . . . . . . . . . . .   i

          SYSTEM OVERVIEW . . . . . . . . . . . . . . . . . . . . . . .   1

          INSTALLATION OF SYSTEM  . . . . . . . . . . . . . . . . . . .   3

          USING THE SYSTEM/QUICK START  . . . . . . . . . . . . . . . .   4

          COMMAND LINE COMPILING  . . . . . . . . . . . . . . . . . . .   7

          TUTORIAL  . . . . . . . . . . . . . . . . . . . . . . . . . .   9

          REGISTRATION  . . . . . . . . . . . . . . . . . . . . . . . .  13

          BOX TYPES . . . . . . . . . . . . . . . . . . . . . . . . . .  15
               MENU BOXES . . . . . . . . . . . . . . . . . . . . . . .  15
                    MENU PICK BOXES:  . . . . . . . . . . . . . . . . .  17
               PLAIN BOXES  . . . . . . . . . . . . . . . . . . . . . .  18
               MEMOEDIT . . . . . . . . . . . . . . . . . . . . . . . .  19
               ENTRY BOXES  . . . . . . . . . . . . . . . . . . . . . .  20
               BROWSE BOXES . . . . . . . . . . . . . . . . . . . . . .  23
                    DISPLAY ONLY BOXES  . . . . . . . . . . . . . . . .  23
                    PICK BOXES  . . . . . . . . . . . . . . . . . . . .  24
                    FULL SCREEN BROWSE ENTRY  . . . . . . . . . . . . .  24
                    ACHOICE BROWSE BOXES  . . . . . . . . . . . . . . .  26

          INDEXES AND FIELDS  . . . . . . . . . . . . . . . . . . . . .  28
               FIELDS . . . . . . . . . . . . . . . . . . . . . . . . .  28
                    Field Replaces  . . . . . . . . . . . . . . . . . .  28
                    Calculated Fields . . . . . . . . . . . . . . . . .  28
                    Automatic VALIDS  . . . . . . . . . . . . . . . . .  29
               INDEXES  . . . . . . . . . . . . . . . . . . . . . . . .  30
                    Indexed Seeks . . . . . . . . . . . . . . . . . . .  30
                    Exclusive Keys  . . . . . . . . . . . . . . . . . .  31

          DEFAULT HELP SYSTEM . . . . . . . . . . . . . . . . . . . . .  32

          SYSTEM WIDE FUNCTIONS . . . . . . . . . . . . . . . . . . . .  34
               MESSAGING  . . . . . . . . . . . . . . . . . . . . . . .  34
               ERROR SYSTEM . . . . . . . . . . . . . . . . . . . . . .  34

          RELATIONSHIPS . . . . . . . . . . . . . . . . . . . . . . . .  35

          CODE INSERTION  . . . . . . . . . . . . . . . . . . . . . . .  36
               THE ATTACHED OPTION BOX  . . . . . . . . . . . . . . . .  36

          LARGE SCALE SYSTEMS . . . . . . . . . . . . . . . . . . . . .  39

          QBE - Query by Example  . . . . . . . . . . . . . . . . . . .  42


                                          ii







          ERRORS AND TROUBLESHOOTING  . . . . . . . . . . . . . . . . .  45

          QUICK GUIDE . . . . . . . . . . . . . . . . . . . . . . . . .  47

          INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . .  49
















































                                         iii








          SYSTEM OVERVIEW

          Welcome  to the  wonderful  world  of  Clipper Templates!    More
          specifically, welcome  to ALLCLIP.TEM,  the ONLY  template you'll
          ever need.

          ALLCLIP.TEM is  a Clipper  specific template  for UI2  Programmer
          that will  enable  anyone to  generate  a full  database  system,
          complete  with  popup  and  pull  down menus,  automatic  context
          sensitive  help,  and all  of the  other  bells and  whistles now
          common  in  every application.   It  will  allow the  beginner to
          program applications that  skilled programmers would  take months
          to  write,  and  enable the  experienced  programmer  to generate
          nearly any kind of database design.   It supports multiuser code,
          and contains a wide variety of  special goodies built-in (many of
          which I attempt to provide documentation for).

          It is also free.

          The basic  theory of  the system  is that,  by following  certain
          rules, the template will recognize boxes drawn on the screen, and
          generate the  appropriate code  for those  boxes, writing  menus,
          entry and browse type code.  All a beginner need to is to  define
          his or her fields and draw the  screens, and the template will do
          all the rest  (including generating  the databases and  indexes).
          Additionally,  the  system allows  the  experience programmer  to
          insert  any  additional code  he  or  she  desires,  all  without
          touching  the source code  produced by this system.   In this way
          changes can easily be made without trouble (and we don't want any
          trouble, do we, particularly from YOUR kind).

          There are many excellent templates out  there on the market.  Why
          should you use ALLCLIP.TEM?  

          The  principle  differences between  most  of  the  Brand X  type
          templates and mine are:

           1) Mine  is Clipper  specific.   Not having  to worry  about the
          crummy  programming languages,  I can take  advantage of  all the
          really neat  things about Clipper,  making the system  code tight
          and solid and keen.

           2) Mine is free

          Yes, There is No Such Thing As  A Free Lunch (TANSAFFL), but this
          comes pretty close (see Registration, below).

          If  there is a better system out  there (one that does everything
          mine does and more),  I want to know about  it.  I'll either  buy
          and  use  it,  or  (more likely)  rip  off  the  best  things and
          incorporate them here.  I know a good idea when I steal it.

                                          1








          The system will generate a .PRG file designed to be compiled with
          the Summer 87 version  of Clipper.   It should work with  Clipper
          5.0, when and if it ships (I TOLD you I  would have my QBE before
          they shipped), and I can guarantee that if it doesn't work I will
          make it.  It will not  run under anything else properly (although
          parts of it may). If you set  the multiuser generation (in UI) to
          on, it will generate multiuser code (brilliant, right?).

          If you have never  used templates before, are new to  UI, or just
          want to  do things right,  you should  work your way  through the
          tutorial  chapter.    If,  however,  you  are like  me,  you  can
          impetuously ignore this  chapter and charge  right into to  using
          the system (actually, if you are like me, you've never even  read
          THIS far).

          In  either case,  you  should read  the chapter  on installation.
          Well, it  actually  isn't a  whole  chapter (yes,  it  physically
          occupies the same space as a chapter, but this is  a metaphysical
          point to be discussed with New Agers, and far beyond the scope of
          this document), more a page or two of easy to follow  stuff.  And
          then read up on registration, where I tell you how to get all the
          updates and help you might need with this thing.

          Enjoy.




























                                          2








          INSTALLATION OF SYSTEM -- PLEASE READ!

          Since  we  assume you  have  already  unzipped all  of  the files
          necessary for  this system (otherwise,  how would you  be reading
          this?), the next step  is to install the appropriate  programs in
          the appropriate directories.

          Yes, I  know, most  programs of  this  type have  batch files  to
          install  the appropriate  stuff in  the appropriate  directories.
          But most programs of this type cost an arm an a leg.

          This template, as I said earlier, is absolutely free.

          Okay, so we need to do a little work.  Roll up your sleeves, take
          the phone off  the hook,  and prepare to  spend about 10  minutes
          getting everything in the right places.  Believe me, it's no more
          complicated than your  average brain surgery  (It's a JOKE!   I'm
          just KIDDING!).

          The  first  step is  to put  ALLCLIP.TEM  wherever you  have your
          templates stored.   As it  is the  only template you're  going to
          need, you can  go ahead and erase all the other *.TEM files there
          first.

          The  next  step  is  to  install  the  .CTL   (compiled  template
          libraries).   These need  to reside  whether you  have your  .TLB
          files.  There are two of these, ALLCLIP.CTL, and VARFUNSC.CTL.

          Finally,  (will these installation  instructions never end?), you
          should  put  ALLCLIP.LIB  where  you   have  your  other  Clipper
          libraries stored (usually with the Clipper program itself).  

          ALLCLIP.LIB contains  various  library  functions  that  will  be
          linked  into your program when needed,  just like other libraries
          such  as the  Grumpfish library.    For those  of you  that don't
          understand the previous sentence, let me repeat the wisdom of the
          ages:  DON'T PANIC!  You have to  link your Clipper object module
          with the Clipper library  (at least) anyway, and this  little guy
          will just  be invoked  too,  causing no  problems whatsoever  (he
          doesn't  want  any  trouble, either).    I'll  give  you complete
          instructions on how to handle it in the next section, QUICK START
          (for all of you  to whom this is old hat, have some patience with
          your fellow men and women.  We all have to start somewhere.

          Believe it or  not, you're finished  with the installation!   You
          can fire up UI, and begin using the system.






                                          3








          USING THE SYSTEM/QUICK START

          Okay, we assume that you  followed the installation instructions,
          above.  Now you're ready to use the system.

          All you need to do  is fire up UI, load a .WW  file, and generate
          away.  BUT...

          The .WW file  needs to  follow certain conventions.   After  all,
          that is the  whole point of this template.   By following certain
          rules,  the  template will  know what  code to  write.   But what
          rules?  Ah, that's the key, isn't it?  Well, you can read all the
          rest of the  documentation that  follows, including the  in-depth
          tutorial.  As a matter of fact, I'm so sure that you  will all do
          that, that I will pause here and wait for you while you  read and
          absorb everything (and there will be a test, later).

          Okay, now while the suckers have gone  off, let's you and me play
          with the system.   We don't have to read everything,  do we?  No,
          we're  smarter  than that  -- after  all,  Life didn't  come with
          instructions, did it?  Wellll, maybe the game did, but...

          Let's see, we have that DEMO.WW and DEMO2.WW files that came with
          the  system.  Let's load  one of those in  and see how this thing
          works.  Let's start with DEMO.

          Okay, we load it in,  and see a whole bunch of boxes.   Gee, that
          looks a lot  like some of the other .WWs.  Nothing spectacular so
          far.  Okay, we press F9 and then G, and select ALLCLIP.TEM (the
          only template left in our directory), and go.

          The first thing  that happens is that  ALLCLIP.TEM gets compiled.
          Okay, nothing extraordinary there.  Now it's generating code, and
          then it's  done already.   Isn't that  486 machine  nice?   Let's
          compile and run this thing.

          We  have  to compile,  so we  issue  the usual  Clipper commands,
          CLIPPER DEMO, and it compiles perfectly.   If it doesn't, you did
          something wrong (you were probably born under the  wrong sign.  I
          guess you'll have to go back and read the chapter on Installation
          after all).  
          Now we need to  link it.  If  we're using PLINK86, you can  issue
          the command:

          PLINK86 FI DEMO LIB ALLCLIP LIB clipper, extend

          Tlinkers use the following syntax:

          TLINK FI DEMO LIB CLIPPER, EXTEND, ALLCLIP 



                                          4







          Note that you  have to include ALLCLIP  as a library so  that the
          linker can  find all the  functions my template invokes.   If you
          have your libraries  in a different  directory, you will have  to
          include the path also.

          If you have  a batch file  that compiles and links  automatically
          (and  who  doesn't,  nowadays?),  you   should  modify  the  link
          statement so  that  it  does  the above  thing,  namely  includes
          ALLCLIP as a  LIB to search in each time during linking.  As this
          is the only system you'll ever use for developing, you are surely
          going to  want to include  this library.   For those of  you with
          other libraries, such as Grumpfish, include ALLCLIP  first.  This
          is because it's so much more important  than any of the others we
          want to continually remind ourselves of that fact (well, that's a
          much more interesting explanation than  saying we want the Linker
          to always check ALLCLIP first in case of name conflicts).

          During  the  link,  you  may  notice  some  Warnings  about  some
          functions being redefined.  Ignore them.  This is a  good general
          rule.  I  ignore all warnings,  particularly those silly ones  by
          the  Surgeon general.  How are you going  to believe a guy with a
          beard  as  strange as  that one,  anyway?   No,  seriously, these
          linker warnings are nothing to worry  about, I am just redefining
          some error handling routines  and the linker is letting  you know
          that.

          Okay, it's  compiled, linked, and we have an  .EXE file.  Now all
          we have  to do  is fire  it up.  If we  run this  program from  a
          directory that  doesn't have  all the  demo databases,  the first
          thing we notice  is that the  system is pausing and  building the
          appropriate  databases.  The next  thing we notice  is that it is
          automatically building  the indexes.   That's  one  of the  great
          features of  the system.  Another is how  it looks on the screen.
          If you're using a monochrome monitor, it will appear in black and
          white  (if  it  appears  in  color,  you probably  don't  have  a
          monochrome  monitor, or  you've been  ingesting  some interesting
          things).   The system will  automatically adjust itself for color
          or monochrome, so you  can develop in color  even if those  other
          poor slobs are still using the $49 K-Mart special.

          Now we're in the menus, and if we press F1, we get the first hint
          of how powerful the system is.  F1 works everywhere, and  you can
          add and edit the help (press CONTROL-RETURN to see how it works).
          Help can  be  as many  pages as  you wish  (up  to Clipper's  64K
          limit), and the  PgUp and  PgDn and  arrow keys  work to  display
          more.  Try adding  a page or two of help  with the Control-Return
          combo (press  F7  to exit  and  save your  changes  -- just  like
          WordPerfect) and then recall the help  with F1 and scroll through
          it.  Pretty neat, huh?

          Okay, by examining  DEMO.WW (and DEMO2.WW),  we can see a  little
          how the system is put together.   There are menus made by placing

                                          5







          options in boxes, and there are browse  boxes made by placing all
          the fields or variables on one line in a box, and there are entry
          boxes made by placing variables and fields in a box on  more than
          one row.  There are also strange things like PICK boxes which are
          neat but we can't quite figure out how they are generated.

          As we look at the boxes, you might want to note these things.

          In general, the following are true of all boxes:

          1.  They must be popup.   If not, they are  assumed to be part of
          the  screen  display at  startup time  and  will be  written once
          accordingly.

          2. Boxes  with frames will be  "shadowed".  This  means that they
          will be drawn with a transparent shadow box offset by two columns
          and one row.  This also means you cannot draw your boxes so close
          to the edge of the screen that there isn't any room for this.  If
          you do, these  boxes will not  be shadowed (brilliant, eh?),  but
          will behave okay otherwise.  

          3. The Box.Description will be used as a title line in the border
          of the box.   Leave it blank if you don't  want a title.  You can
          use single and double quotes in it (but not brackets).

          5. Box slot 2 will, in  general, contain the name of the  routine
          that calls  it.  This is not necessary in the case of some boxes,
          and some boxes use this slot for other purposes.

          6. Box slot 1  will, in general, contain the name of the key that
          calls it.  Once again, this  may not be necessary in the  case of
          certain boxes, and will be used for other things sometimes.

          7. Box slot  3 will,  in general,  contain the name  of the  help
          topic that  will be searched  for when the  F1 key is  pressed at
          that box.

          8. Esc or Spacebar exits from any box you are within.
             (Exception: They stop the softseek if active)

          5. You  can "include" outside files at  certain points in the box
          routines.  You programmers out there  can include as many outside
          functions and routines  as you want.   You can append  an outside
          file containing all  these routines automatically via  the SYSTEM
          box.

          Armed with this  knowledge, you can start using  the template.  I
          would advise you  to start with each  box type, adding them  to a
          test .WW file, and use them until you understand each thoroughly.
          Believe me, there  ain't anything you  can't do with this  system
          (and if there is, we'll just ADD it).


                                          6







          Well, I guess it's time for the rest of the documentation.  




















































                                          7







          COMMAND LINE COMPILING

          (Thanks to Marty Rinehart for starting me on this)

          UI  can  be  run  from  the  command line,  rather  than  invoked
          interactively.  What  does this mean?  It means  that rather than
          firing up UI, pressing  F2 to load the .WW, pressing  F9 and then
          selecting the template  and giving an  output file name, you  can
          pass all the parameters on the DOS command line at once.

          What will this do for you?  It won't make  you rich, or even grow
          hair on  your head (now that the FCC  has outlawed all those hour
          long commercials with Robert Vaughn), but it will save you memory
          on some of those big  .WW files you guys have been creating.   It
          will also save you hunks of time (at times).

          Typing UI  ?  at  the  DOS  prompt will  give  you  most  of  the
          parameters, but here is a summary:

          UI command line arguments

          l[ww file]               load [ww file]

          o[ww file]               overlay [ww file]

          g[template]              generate using [template] into
                                   [ww.name].PRG  

          g[template],[program]    generate using [template] into [program]

          i[config.ui file]        use [config.ui] as your config file

          x                        exit after executing command line

          Here's  how you would work it.   Let's say you're generating from
          DEMO.WW, into a file  called TEST.PRG (of course, we  KNOW you'll
          be using ALLCLIP.TEM).

          UI lDEMO gALLCLIP,TEST.PRG x

          Note:  Don't leave  any  spaces  after  the  comma  for  program.
          Also,it isn't case sensitive (but I put it in for readability).

          Some  of you will  make up  a batch  file like  this (I  know you
          will,I just can't stop you no matter how hard I try):

          1: UI l%1 gALLCLIP,%2 X

          and call it U.BAT.  Then you will just invoke it by typing:

          U [ww.file] [name of finished program]


                                          8







          Don't try to deny  it, I know  you'll do this.   There's just  no
          satisfying some people.



















































                                          9








          TUTORIAL (for those new to templates)

          Oh no, we're back in school.  It's the last  day and I'm facing a
          test and I  haven't studied  the entire semester.   I don't  even
          know this subject, I didn't even take this class I...

          Thank goodness, it's just a nightmare.  But this is learning, and
          so let's get down to it.  Remember, there WILL be a test later.

          Okay, the first  thing we need to do is start  UI.  Now we have a
          blank screen in front  of us.  What do we do?  If you're like me,
          you probably have fallen asleep already.  Wake up,  and let's get
          to work.

          Okay, all our systems need a main menu box.  Let's create one. We
          press F6, and  select a no border box (we could generate a border
          box if we wanted to, but  we don't want to right now,  so there).
          We can make  it any  color we  want, so let's  make it  something
          nice, like Magenta on red.  Those of you that can still see after
          this, follow along.

          We size  the box, using  the arrow keys,  until it's the  size we
          want.   I usually  make my main  menu boxes  stretch all  the way
          across the screen, and about three or  four lines tall at the top
          of the screen.   You, however, are under no obligation to do what
          I do, unless I  decide to jump off a cliff.  It is a free country
          (much like this software).

          As soon as the box is defined, we press F6 again and go to revise
          the box.   What, we just  made it and  now we want to  revise it?
          What's going on here?  Nothing  really, it's just that you  can't
          name a box during the actual creation of it (hey, I  didn't write
          THIS program).   Now that we are  in revise box, we  press N (for
          NAME) and enter MAINMENU as the name.  This is a requirement. You
          can't call it SALLY, or BOBBY, or LOANSHARK.   You can call a lot
          of boxes a lot of things (some  not polite in mixed company), but
          this one has to be called MAINMENU.  This is because the .PRG has
          to have somewhere to start, and this is where it's going to.

          There's one other thing we have to do in the Revise box area.  We
          need  to change it  from No Popup  (the default) to  Popup.  Just
          press P and it  will do it.   This is also  a requirement of  the
          system, that  all boxes  be popup.   Why,  I don't  know, it's  a
          complicated world.

          We haven't exactly accomplished a lot, but we're on our way.  Now
          we need to tell the template (basically) that this is a menu.  To
          do this, we need to put options inside it.




                                          10







          Options are just boxes with options attached to them (kind of
          like a  car becomes a home when you attach a trailer to it).  You
          can either create  them with the box menu  (and attach the option
          option -- I  always wanted  to say  that) or create  them in  the
          option menu.  Let's try the latter (that means the last one).

          We press F7, and it  asks us for colors (it doesn't ask  us for a
          border because the  default of options  are no border --  this is
          fine  for us,  because my  template  assumes options  are without
          borders  -- 1  line high).    We select  the  colors, (make  sure
          they're  different  enough  from the  menu  so  you  can see  the
          options) and then  adjust the size  using the  arrow keys.   Menu
          options are limited (using my template) to 1 line,  so don't make
          them any taller.  We make one option, and then we are asked about
          the trigger character. This  will be the letter (or  number) that
          we press to trigger it. Let's put an "i" there (don't worry about
          why -- do it because I said so).  Directly below the triggers are
          the option action slots.  Here  is where the action is.   This is
          where you put the various commands that will be executed when the
          option is executed.

          Right for now put  the word "First" in the first  line (because I
          said so).   The message line down below is what is displayed when
          the option  is highlighted.   Put the  words "This  is the  first
          pulldown menu" or  words to that effect  on that line.   Now that
          we're done,  press CONTROL-W (or  Control-End) to end  the option
          and save it (you could press Esc to stop without saving it).

          Let's copy this option (so that  we have another one).  We  press
          F6 while the cursor is on the option, and then C (for copy).  Now
          we move the copied option over so we can see both of them.  Press
          F7 (to modify the option part of the box) and press R for revise.
          Change  the trigger  on  this option  to "S",  and  put the  word
          "Secnd"  in  the first  line,  and something  appropriate  in the
          message line.

          The other thing we should do is put some text in the option.  Put
          the  cursor in  option box  1 and  type "First"  (with  upper and
          lowercase).  Put the cursor in box 2 and type "Secnd".

          Make sure  that both options  are completely within  the mainmenu
          box.  If they aren't, UI won't know  they are suppose to be in it
          (makes sense,  huh?)   We could go  ahead and generate  a program
          now, but it wouldn't do much.  Let's do a few more things first.

          Make another box  (make it a  border box this  time -- good,  you
          didn't ask  why.  You're  learning).  Go  to revise, and  name it
          "FIRST".   Make sure  you make it  a popup  box.   Type something
          clever in the box (put some text in  the box).  Make another box,
          call it "SECND" (and make sure it's a popup).



                                          11







          Okay,  NOW  we're  ready to  generate.    Press  F9,  then G  for
          generate, and  select ALLCLIP.   Type in a  program name  when it
          asks you for a name.  Let it do its thing.

          Before we exit UI, you should  save this .WW.  Call it  test1.WW.
          Now exit.

          Compile  and link the program (following  the instructions in the
          installation procedures).  Now run it.  You should see your menu,
          and when you press  RETURN on one of  the options it will  pop up
          one of the boxes.  Press the spacebar to return to the menu.  Now
          press  either  "i"  or  "S" (they  should  both  be highlighted).
          Notice how they trigger the options also.  Press F1.

          Whoa!  Where  did that box come  from?  We didn't  define it, did
          we?    No, it's  part  of the  automatic  help system.    You can
          override it if  you want to with  your own boxes and  colors, but
          it's nice to have it there if you need it.

          Press  the spacebar (or esc)  to exit the  help system, and press
          either  one  again  to  exit  the  system.   Bravo,  you've  just
          generated your first program with the template system.

          Let's go back into  UI and do some more.  Load  the test1 ww file
          (by pressing  F2 and L  for load).  We  could do a  lot of things
          now.  If we put  menu options in the first  box, we would have  a
          pull-down  menu with  further options.    You should  have enough
          knowledge now to  do that, so go  ahead and try  it.  If you  get
          stuck, save your  work and load in  DEMO.WW to see how  it should
          go.

          Okay, let's try  a data entry box.   Take the second  box (called
          SECND) and let's modify it so that  the system sees it as a entry
          box.  How do we do that?  By adding fields from a database to it.

          First we need a database.  We can  either use an existing one, or
          make a new one.   Let's make a new one.  We can  do that right in
          UI.  Press F5, and then N for new data dictionary.

          The  data dictionary  is  where  the  information about  all  the
          databases used by this system (and others that use the  same data
          dictionary)  is  stored.    It  also  allows you  to  define  new
          databases, so you  really don't need  anything other than UI  and
          Clipper for your systems.

          Press N for  new data dictionary, and  enter Test for name.   Now
          you can press  M for modify the dictionary you just created.  You
          will  notice  that you  could import  the  DBF structure  from an
          existing database here  [explain how  to do that  later].   Right
          now, we want to create our own fields.

          [Here's where you explain how to do that]

                                          12







          Now that we have a database, we need to add the fields to the
          box.   Press F4.   We can either  add one field  at a time,  or a
          bunch  of them.   Try  one  first.   Press f,  and then  pick the
          database (you only have one) and the  fields from it.  Let's pick
          firstname.  Note that  it gets dropped right where the cursor was
          before you  pressed F4.  That may not  always be where you wanted
          it, but it's a simple matter to move  it with F4, M for move, and
          use the arrow keys to position it exactly.

          Okay, we have name right where we want it, in the box.  Let's add
          a  couple  more.   [Show  how  to  add these  properly]    We add
          lastname, phone.   Make sure that all your  fields are not on one
          row (in a  horizonal line).  If  they are, the system  will think
          it's a browse box (more on this later).

          Fields are on different rows?  Okay, let's Generate it.  After we
          do (and save  our new .WW again),  exit and compile and  link and
          run it,  we find that  the system will pop  up an entry  box.  It
          will ask if  we want  to add  records to the  database, as  there
          aren't any to begin with (makes sense, since we just created it).
          Answer yes, and add a record.  Now, if you press return, you will
          be placed in  the edit mode for  this record.  Pressing  Ins will
          add a new  record, and  Del will ask  if you want  to delete  the
          record.  The arrow keys will move you from record to record.

          Press F1 while  you're editing  the record, and  each field  will
          give  you specific  help for it.  Great, huh?  Add a few records,
          say ten or so.

          [At this point in the tutorial, the teacher goes on to explain at
          great length  and easy  to follow  detail, just  how to  generate
          browse  boxes, automatic  pick  boxes, set  relationships,  field
          replaces,  and  everything   you  wanted   to  know  about   sex.
          Unfortunately, as we all know, education  has a price these days,
          and the remaining  lessons will  only exist in  Version 6.0  (see
          Registration below)]

















                                          13








          REGISTRATION

          TANSAFFL and "Free Software"

          Yes, there's no such thing as a free lunch, but this comes pretty
          close.  This isn't "Freeware" (I still retain  the rights) but it
          will only  cost you the price of a phone  call to get and use it.
          The  time has  come, the  Walrus said however,  to speak  of many
          things.  First,  and foremost among those  is the eminent  (as of
          this date, January  15, 1990) release of ALLCLIP 6.0.   With this
          release, we will actually be asking  (gasp!) hard earned cash for
          the first time.  What does this mean?

          The first thing it  means is that I'm not going  to post 6.0 free
          to this  board.  Version 5.6 is the LAST  version you can get for
          nothing.  In  order to get version  6.0, you'll have to  order it
          either direct from me or the software company that sells it.

          But more importantly, as  a paid-up user of ALLCLIP,  you'll reap
          all  the benefits that  you rightfully  expect when  you purchase
          software: namely, excellent support and an enhanced product.

          Those  of you who have communicated  with me and helped mold this
          product to its  present specifications already  know, I hope,  of
          just how responsive the support I've  provided for free has been.
          That will only improve for those of you who purchase the product.
          I  usually  correct  most  problems  within  a day  or  two,  and
          incorporate  most  suggestions within  a  week  or two.    I also
          provide expert advice on  how to use the system.  If you have any
          problems or questions with  it, I will do my best  to answer them
          (either leave a message for me on this board, or call me at (702)
          882-1017 (it's  a message phone, and  I'll answer it if  you talk
          long enough and I'm around, or I'll get back to you).

          The enhanced version  of ALLCLIP will  have its own on-line  help
          system (within UI), Microsoft mouse  support, an enhanced version
          of  the  QBE,  and  (perhaps   most  importantly)  MUCH  improved
          documentation and example  .WWs.   The docs alone  are worth  the
          price of admission, with  a nearly 50 page tutorial  section that
          walks you through almost every feature.

          The price of admission is $99.95 (you notice how they always make
          the price  about 5 cents  less than the  dollar, to make  it seem
          like a great  deal?), which we  believe is MORE than  reasonable.
          In  return  you get  the  latest  version of  ALLCLIP,  all minor
          upgrades  free for six  months, a copy  of the printed  docs, and
          free  telephone support  (you pay for  the call --  I'll talk for
          free).

          I will  continue to  support version  5.6, even  including fixing
          most problems with  it (is this nice,  or what?), but I  will NOT

                                          14







          add any more new features to it.  Frankly, I believe you can do a
          great many things  with this particular version  of the template,
          with  or without paying  for it.   I also believe,  however, that
          most  of you  are honest programmers  who know a  good thing when
          they see it, and  have responded very favorably to  this template
          approach  and are willing to  pay a small fee just  to keep me in
          peanuts (just like Dumbo,  that's what I work for) so  that I can
          continue cranking out excellent products for you.

          If you send  your order in for  ALLCLIP 6.0 today, not  only will
          you be the first on your block to get the new release, but  we'll
          send it out to  you for the special introductory price  of $79.95
          (What  a Country!).   After we  start officially  advertising and
          shipping the product, the price will go up.  Hey, twenty  dollars
          nowadays will buy you a good cup of coffee!

          If you're interested, fill out the  handy dandy order form below,
          and send it in, with the loot.

          Okay, enough commercials, on with the show!

          *****************************************************************
          ORDER FORM FOR ALLCLIP 6.0

          Yes!  I want to be the first one in  my neighborhood to have this
          wonderful product, and be able to  decode all the secret messages
          Orphan Annie  gives on the radio.  Please  find my check or money
          order for $79.95 enclosed, and send ALLCLIP  6.0 to me as fast as
          the U.S. Postal service can move (in other words, sometime within
          this decade).

          NAME________________________________________

          ADDRESS_____________________________________
           
                 _____________________________________

          (Allow 4-6 weeks for delivery, even though we'll probably send it
          a lot sooner, because our lawyer told us to tell you that)

          Send this  form along with payment to:  Mike Kelley / The Village
          Software Co., 3108 Conte Drive, Carson City, Nevada  89701











                                          15







          BOX TYPES


          MENU BOXES

          This box  contains two or  more options  within it, which  may be
          arranged either vertically, horizontally, or both ways.  You MUST
          have more  than one option in the box.   I'm sorry, but this is a
          democracy,  and  despite what  Marty says,  a  menu box  with one
          choice is a menu box with no choice (all right, I'm aware this is
          actually  a  Republic,  but how  many  poly  sci  majors took  up
          programming?)

          Also, each option  box contained within the box  must be only one
          line  tall.   Failure to  do  this will  cause the  option  to be
          treated as an "Option attached" (which see). 

          The system requires a MAINMENU box (this is  the box name), which
          will call any submenus  from it.  The boxes can  have the options
          arranged any way  you want, but you should see the DEMO.WW to see
          how I normally do it.  The MAINMENU box will be the first
          procedure called by the program, and will not be shadowed.

          The option triggers are as normal --- that is, you put  the first
          letter  to  trigger the  option you  desire.   While  the trigger
          itself is not case sensitive, the highlighting the system puts in
          is.   The system will highlight the  option letter of each option
          that is active, and it will look for it  by case.  If one of your
          options is "Index", and  you want the "x" highlighted,  make sure
          you  place a LOWER CASE x in  the trigger.  The highlight will be
          in the color of the first letter of the  first option in the box,
          if it differs  from the rest  of the option  (so you can  use the
          paint command  in UI  to make  it stand  out --  See DEMO.WW  for
          examples).  If you don't paint a  letter, the system will use its
          own defaults.

          You might also  note that,  if you don't  otherwise specify,  the
          trigger colors  of highlighted items  are a different  color than
          the unhighlighted triggers.  Boy, if  you think this is confusing
          to read, just think what  it's like to write this stuff.   What I
          mean is that if you have the option "Index" highlighted,  and "I"
          is the trigger, the letter "I" will be in a different  color than
          the other triggers of  the other options.  Whew!   It's easier to
          see  than  to  explain  (actually,  I've  spent  about 300  words
          explaining it, and  could finish, but  a picture will save  about
          400 more  words.  Yes,  I know, a picture  USED to be  worth 1000
          words, but that was  before inflation).   Look at DEMO.WW to  see
          how this works.

          If you want to specify your  own second trigger color, just PAINT
          the SECOND letter  in the FIRST option  the color you want.   Got
          it?

                                          16




























































                                          17







          In the option  action slots you fill  in what you want  to happen
          when  that  option is  pressed.    This can  take  several forms.
          First, you can write the raw code there.  Second, you  can simply
          place the  name of  the box  you want  called (this  is the  most
          common form)  and the template will write the appropriate calling
          code.  

          In the option message line you can include a message that will be
          displayed in the  message window when the option  is highlighted.
          The message window  is a special case  window.  It should  be one
          line high, and run the length of the screen (if you want it to be
          less wide, it must be centered on the screen).  It must be called
          "MESSY", and no  other code  will be  generated for it.   If  you
          don't include such a  window, the system will generate  a default
          "MESSY"  window for  you  at  the bottom  of  the screen,  in  my
          favorite colors.

          In  option slot 3  (different from the actions  slots -- they are
          the option BOX slots), you can put the name of a help topic to be
          called.  If no  help topic is named here, the  text in the option
          will be used as a default for help.

          Esc or the  spacebar will exit from any menu back to the previous
          menu, or  you may include an option which  has EXIT as its option
          slot.




























                                          18








          MENU PICK BOXES:

          If the  word "PICK" is  in box slot 1  of the menu  box, the menu
          will be treated as a "Pick" box.  In this case, box slot 2 should
          contain the name  of the field that will invoke  this menu either
          by pressing the pick key (see  system box above) or automatically
          within a VALID  (see automatic valid,  below).  Put the  item you
          want  to replace into the field in option.action slot 1 but don't
          include any help or message information --- it won't be used.

          You can call the  same pick box from different fields  by placing
          the names of all  the fields on Box Slot 2,  separated by spaces,
          or commas.

          DEMO.WW contains an example of this,  with tennis Ranking.  Also,
          you  should  read  the discussion  below  on  the  other type  of
          pickbox, the database browse pick box.



































                                          19








          PLAIN BOXES

          Just a plain old pop-up box.  If the box slots are empty, the box
          will  pop up and  wait for  a key  press to  disappear.   You can
          include outside code  in the box  (see outside code, below),  and
          the system can execute this, and  then unpop automatically.  This
          is  good for displaying "Working..." type  messages while code is
          being performed (if you don't want to use the messaging system).

          There are  also a  couple of  generic routines  available with  a
          plain box.  If you include the  word "PACK", "INDEX", "RECALL" in
          box.slot1, the  system will  write a  routine that  will pack  or
          index or recall  records from  all the databases  in the  system,
          giving message prompts at each line.  

          It indexes by using the key expression for each index in the data
          dictionary, so make sure you  have filled that in (and make  sure
          you have INCLUDED  THE INDEX LOCALLY).   Also, if  you place  the
          word "UNIQUE" in index slot 3,  the index will be generated as  a
          UNIQUE index. (See sample in DEMO2.WW)
































                                          20







          MEMOEDIT

          This box contains only one field, a memo field of type input.  It
          will automatically invoke the  memo edit routine, with F7  as the
          exit and save feature, F2 for search, Esc to exit without saving,
          and all other memoedit keys active.  

          This box  will be called automatically during  the edit of a memo
          that is marked as input in an entry (see below) box.   Otherwise,
          you can put a function key in slot 1 to call it from wherever you
          want.










































                                          21







          ENTRY BOXES

          This box type  contains two or more input  fields (along with any
          other sort of fields you desire) that are displayed over at least
          two lines.    It is  the common  data entry  screen,  and can  be
          multiple  pages if  desired (see  calling routines).   It  allows
          reading  and  displaying of  information.   It  can  contain memo
          fields, and the  memo field(s)  can be input  and/or display  and
          will be sized to fit available space.

          If you  have memo fields of  type input, when the  input routines
          are  invoked,  the  first  letter  of  the portion  of  the  memo
          displayed will be  highlighted as  an editable field.   When  you
          position  the  cursor at  this point  and  press return,  it will
          invoke a  memoedit box  (if one has  been defined  for it  -- see
          above) or it will allow the editing of the memo in the  amount of
          space available for display.

          Key Defaults:

          ENTER or RETURN  edits the current record, Ins adds a record, Del
          deletes a record, the arrow keys  move you along the records, and
          Esc or Spacebar  exits.   F1 always calls  the context  sensitive
          help  function (see below).   During an  edit, if a  pick key has
          been specified, it will call the appropriate boxes (if any).

          Calling routines:

          Both  the browse  and the  entry boxes  support multiple  calling
          routines.  Basically,  this allows you  to call other boxes  from
          within them, by  assigning special function  keys or PgUp,  PgDn,
          etc.  
          To do this, you  put the name of the key in  Box.slot 1 that will
          call  the box, and the name of the  box that calls it in Box.slot
          2.

          You can put  multiple names in  box.slot 2, and  the box will  be
          called  from multiple  boxes (however,  they will  all be  called
          using the same key).  The keys should be specified just  like you
          think, i.e. F7, PGDN. 

          You can also leave  the calling key (box.slot 1)  blank, in which
          case the box  will be executed automatically  in the look  of the
          calling box.  See DEMO2.WW for an example of this.  









                                          22







          In order to  get multiple pages, just  have one box call  another
          with  PGDN keys.  It will  work properly (assuming both are entry
          boxes) and not become recursive (it is smart enough to avoid it).

          There is no limit to the  number of boxes you could nest  in this
          manner  (well,  no limit  in the  template).   The  only drawback
          currently is that INSERTing a record only  works on page 1 of the
          multiple pages.   Editing will work on all pages if you invoke it
          from page 1, otherwise it will only edit the page you are on.

          Attached Options

          (See discussion below in including  code for complete information
          on attached option boxes)

          In slot 3  of an option attached to  either a browse or  an entry
          box,  you can  include a  "condition" that  acts as  a filter  on
          records  displayed.   If  you  do  this, the  database  should be
          indexed on that condition to work properly.  You can also place a
          "SEEK" clause in the option.description.  This will cause a"SEEK"
          to be initiated.  The difference  between a condition and a  seek
          are the  way the parameters are  specified.  For example,  if you
          have a primary database indexed on  SSN, and a secondary database
          that has  checks for everyone,  also indexed on SSN  plus date of
          the check, you could conditionally bring up all the check records
          for a particular  SSN by putting  (m->ssn = primary->ssn) in  the
          condition  slot (slot3).  This would set  the filter to show only
          those records that  met the proper conditions.  But  in order for
          it to work quickly, you should also specify  a SEEK condition, by
          placing  (primary->ssn)  in the  option  description.   This will
          cause the secondary  database to first  seek for that  condition,
          and then set the filter accordingly.


          *****************************************************************
          DISPLAY COLORS

          The UI system is limited in that field display and get colors are
          not easily specified.   There is only one global  setting, called
          field display colors, that sets the colors for all variables.

          In  order  to increase  the  flexibility  of the  system,  I have
          instituted  a  (slightly) more  complicated  system.   The global
          setting of display colors  now affects the color of  all variable
          gets.  It  is far more  likely that you  would want these  to all
          share the same color attributes.

          In order to display the fields in different colors, you may place
          an option box in the appropriate browse or entry box.  It doesn't
          need to have any text to include (like above).  The colors of the
          option box will be the colors of the displayed fields.


                                          23







          If you don't include an option box, the system will write default
          display variable colors  for you, which vary  depending upon your
          other box colors.

          If this scheme isn't satisfactory, I will gladly entertain better
          ideas.  It works for me.

          The entry  box shares a number of  features in common with Browse
          boxes (see below).












































                                          24







          BROWSE BOXES

          A  scrolling  "look-up"  type  box,  this  box  contains  fields,
          arranged in a straight  line across the box.  It  will display as
          many  fields  as are  appropriate.   You  can have  input fields,
          display fields, or  a combination.   You can also put  calculated
          fields and memory variables here,  but all fields must be on  the
          same line.   The system will  create a browsing "window"  that is
          the  size of the  blank space in  your box beginning  at the line
          that contains the fields,  and going until it either  reaches the
          end of the box, or until it finds some text.  

          If  you want calculated fields in  this box, you must define them
          either in terms  of a function, or a user defined function.  This
          would be put in the Calc.formula.  DEMO.WW has an example of this
          showing a field  that is  either the home  phone number, or  work
          number, depending upon the results of another field.

          If you have  a return-called  box (one  in which the  box slot  1
          contains the word RETURN)  to this box, it will  execute when you
          press RETURN.   In  this case,  it should  be an  ENTRY box,  for
          fullscreen editing.   You could probably attach  other boxes, but
          it wouldn't work  very well.   Without a  RETURN called box  (and
          with  any input  type  fields in  the  browse), an  Edit will  be
          performed on that line.

          The size of the box determines how many records will be attempted
          to be displayed.

          If your field length is smaller than the picture you specify, the
          entire field will  be displayed  below in the  message line  when
          that field is highlighted.  See  DEMO.WW for an example of  this,
          on first name and address.  In this way, you can put large fields
          in a browse box without having to scroll horizontally.


          DISPLAY ONLY BOXES

          If all fields in the box are of type "Display", it will not allow
          any editing or adding  or deleting of records.  This  is good for
          just a  scrolling look-up box.  This  differs from the other kind
          of  DISPLAY  ONLY box,  which is  generated  by putting  the word
          "DISPLAY" in box  slot 1.   This  is a special  case display  box
          called from  within an entry box  with every record of  the entry
          box.   This acts  as a kind  of "window" on  a secondary database
          that might be related  to the first (i.e., you might  have a list
          of all family members  in a secondary database that  are attached
          to a primary membership database.   With each primary record, you
          want to show as  many of the secondary  members as will fit  in a
          display box).  See DEMO2.WW for an example of this.



                                          25







          PICK BOXES

          If this box is to be a "PICK"  box (comes up during an edit of  a
          variable with a scrolling list of possibilities), it should  have
          the word "PICK"  in box.slot 1).   It will behave like  a display
          only box, except that it will stuff the KEYBOARD with your choice
          of items.    Put whatever  value you  wished to  have stuffed  in
          box.slot  3.   Box  slot  3  can contain  a  mixture  of  fields,
          variables,    and   constants,    for    example:   LASTNAME    +
          substr(firstname) +chr(13).  (See also menu pick boxes).  You can
          call the same  pickbox from multiple  fields by placing the  same
          name in each variable's VALID (see valid info, below).  Note that
          the reverse is NOT true: you can't call multiple  PICK boxes from
          the same field  (even if that field is in a different master box,
          or  even on  a different .WW  within the system).   Sorry, that's
          life.

          Box slot  3 of the "SYSTEM" box (which  see) contains the key you
          wish to have call your pickboxes. Note that this is global -- all
          pick boxes are called by the same  key, and the box call is field
          sensitive.  

          You can make these  PICK boxes operate as automatic VALIDS.   See
          the discussion below on how to do this.


          FULL SCREEN BROWSE ENTRY

          There is  now a new  type of box,  called the full  screen browse
          entry box.   This basically enables you to  do batch updates on a
          file.   It operates exactly like your normal browse box, but does
          not allow inserting or deleting of a record.

          The  way  you would  use  it is  to create  a  temporary database
          containing as many blank records as you want to allow batch entry
          for.  Then invoke this box with that database.  After  they exit,
          you can update  the master  database (if they  didn't press  Esc)
          with these records.

          [Lots more on this later (in 6.0)]













                                          26







          Key Defaults

          ENTER or RETURN edits the current record (or brings up the
          attached full screen entry edit), Ins  adds a record, Del deletes
          a record, the arrow keys move  you along the records, and Esc  or
          Spacebar  exits.   F1  always calls  the  context sensitive  help
          function (see below).  

          Browse boxes also support entry features such as attached options
          (see above and below), Display colors, and calling routines.

          [These features will be much clarified in version 6.0]









































                                          27







          ACHOICE BROWSE BOXES

          Presented for your dining and dancing enjoyment...ACHOICE boxes! 

          Those  of  you  familiar with  Clipper  will  probably understand
          this,so you can move  on ahead.  The rest of you,  stay here with
          me and we can look at the dirty pictures the others will miss.

          ACHOICE boxes function much the same as regular browse boxes. The
          main difference  is that,  where a  regular browse  box uses  the
          DBEDIT function of Clipper  to operate (and thus is  designed for
          use  around  database  records), ACHOICE  boxes  use  the ACHOICE
          function (hey!) and are designed to use with arrays.

          What's arrays?  It's what I never get from my boss.  Also, it's a
          place to store  a lot  of values  all in one  variable.   ACHOICE
          allows you to scroll through these values, and select the one you
          want.

          Setting up an ACHOICE  box in my template can  be accomplished in
          two ways:  the hard way, and the harder way.  Okay, so maybe it's
          not all that  hard, but I suggest you look  carefully at QUERY.WW
          as we go along to make it clearer.

          The main problem (or  difficultly, or stumbling block) is  how to
          specify the array  elements to the ACHOICE box.  The first way is
          to create  a memory  variable in  UI, place  it in  the box,  put
          "Array" in variable slot  1 and fill in variable slot  2 with the
          number  of elements in  the array  (it can  also be  a calculated
          function that returns a number).  Slot 3 is a function  that will
          be executed (or shot  on sight) with the idea that  it is filling
          the array (given the same name as the variable) with data.  There
          is  an  automatic  array (called  on_off)  created  that controls
          whether the choice is  displayed or not.  It is  initially filled
          with  .t. but you could override  it in the function contained in
          slot3.

          The  second  way to  specify  array  elements for  ACHOICE  is to
          declare  them  explicitly.   In  this  way,  you  create all  the
          different elements for your  array as memory variables.   In this
          case, they are  all put in an  array called zvar, and  the actual
          values they carry  are in variable slot  3.  Slot 2  contains the
          values for the on_off array, or a function to control them.

          In QUERY.WW the field choices for both  the query and the display
          list are created  with an  ACHOICE box  of the first  type.   The
          conditionals (greater than, less than, etc.) are created using an
          array of the second type.  Examine these to see what's going on.

          Pressing RETURN in an  ACHOICE box returns the value  assigned to
          that array element  (normally back to  a calling function).   Esc
          returns a null string.

                                          28








          ACHOICE boxes can be used instead of regular menu boxes, in order
          to save memory in UI (takes up lots less than creating  all those
          option  boxes)  but  NOT in  the  final  program  code --  memory
          requirements would be about  the same.  You will,  however, trade
          off   ease  of   understandability,  and  some   functions  (like
          triggers).  In  general, you should  use ACHOICE boxes only  when
          you have no other choice (heh, heh).

          [Better examples and more clarity will be available in 6.0]











































                                          29








          INDEXES AND FIELDS

          FIELDS

          Field Replaces:

          If  you  want  the  field  values  to have  initial  values  when
          inserting new records,  you can  place the initial  value in  the
          initial value area.   Less obviously, if  you want the  values to
          carry over  (like CARRY  ON in  interpreter) just  put an  "R" in
          field  slot  1.    You  can  also put  a  calculated  formula  in
          calc.formula for display purposes.  Speaking of display, be  sure
          to mark those  fields as display only  that you do not  want READ
          into.   Including help in  the VALID field  is straightforward---
          just include any  validation routines.  The  system automatically
          generates field sensitive help screens (see below).

          If you want  field values to  carry over or  be substituted,  but
          those  fields  are  not  displayed on  the  screen,  include  the
          appropriate information in  the data  dictionary.  This  commonly
          occurs when you call  a nested browse box from an  entry box, and
          wish  to  have  a common  field  (perhaps  an  id lookup  number)
          substituted when  you add a new record.   In this case, you would
          place the appropriate formula (a->mbr_number, for example) in the
          field initial value.

          *****************************************************************

          Calculated Fields:

          If you place a formula for the calculation of a field, it will be
          performed before the display of that field.  If you wish  to have
          the  field  calculated DURING  a READ  (the  values of  the field
          dependent upon the READ information), place the name of the field
          in the fields or fields prior to this field upon which  the field
          would  be dependant.   For  example, if  you  wanted to  have the
          memory variable  "INITIALS" pick off  the first letter  from both
          the  first  and  last  name  fields,  you would  place  the  word
          "INITIALS" in field slot 2  of each of those fields, and  include
          the  formula   (SUBSTR(FIRST,1,1)  +  SUBSTR(LAST,1,1))   in  the
          calculation formula of INITIALS.  See  the example in DEMO.WW for
          initials that are updated automatically during the read.

          Much thanks to Phil Hill for pointing out this approach to
          variable calculation.







                                          30







          *****************************************************************

          Automatic VALIDS

          In addition to  having pick boxes come  up when a key  is pressed
          during  a  field  edit,  you  often times  want  a  pick  box  to
          automatically come up when the user enters an invalid response.In
          the past, you had to hard  code this (not too difficult, but  why
          do we have computers?).  Now you have automatic VALIDS.  

          The procedure  is simple:   go  ahead and  define a  pick box  as
          normal, with the field replaces in slot 3, and the word "PICK" in
          slot 1.   Then, in your field  you want the automatic  valid for,
          put the name of the  pick box in the VALID slot.   Just the name,
          no parens or any other parameters.  The system will do  the rest.
          DEMO.WW demonstrates this with the state code field.  You can use
          the same pick box  in more than one  field, if you want, just  by
          including the name in more than one field's VALID.

          The system writes a  function that either searches for  the field
          in the database (if a dbf pick) or in the option.action  slot (if
          a  menu pick)  and returns  a .t.  if found.    If not  found, it
          invokes the pick box for the user to  select the entry.  The user
          cannot  leave unless they choose a  VALID entry, or press Esc (to
          end the edit without saving).   If you want to allow the field to
          be blank as well as contain a  valid entry, make sure one of  the
          records  in  your PICK  database  contains  a blank  (and  thus a
          match).

          Sometimes you  want the PICK box to  pop up automatically as soon
          as the user enters  the field, when it is not a  VALID entry.  In
          this case, you need to go to the VALID of the previous field, and
          insert  a function  that KEYBOARDs  a CHR(13)  (and then  returns
          .t.).  This will cause the next PICK box to pop up automatically.

          Naturally, this kind of automatic valid won't be adequate for all
          conditions, just most.  But it can serve as a model for the  kind
          of function you need  to write to invoke other valid clauses that
          call boxes.  


          *****************************************************************
          GENERAL VALID NOTE

          If you don't use automatic valid  pick boxes (above), please note
          that any  valid you write  for a  field that  is contingent  upon
          field values MUST use m-> to precede any field references.   This
          is because only memory variables are edited during any READ, with
          the values replaced accordingly when the READ is finished.
          *****************************************************************



                                          31








          INDEXES

          Indexed Seeks

          If  your  database  has   an  index  or  two,  the   system  will
          automatically generate indexed seeks  for the data.  You  do this
          by  including  (in  the  data  dictionary definition)  the  index
          expression,  and  then   (in  index   slot1)  the  word   "ALPHA"
          or"NUMERIC"  for  alpha  or numeric  type  data.    In the  index
          description, you include the word to  be added to "SEEK " in  the
          information box, and finally  include a picture in index  slot 2.
          For example,  if your database  is indexed on last  name, you put
          "LASTNAME" in the  index expression, "Last  Name: " in the  index
          description,    "ALPHA"   in    index   slot1,    and   (perhaps)
          "!!!!!!!!!!!!!!!!" in index slot 2 (without the quotes).

          There is  a  slight trick  to  this if  you  have data  which  is
          alphanumeric in nature,  but numeric looking.   If you have,  for
          example, a phone number  which is stored as an  alphanumeric, you
          don't indicate "ALPHA" to the system.  This is because the system
          assumes with  an "ALPHA"  that you  are using  letters only,  not
          numerics.

          You can have two  separate indexes with different  seek routines,
          assuming that  one is numeric and one alpha (based -- see above).
          You can also have an index which is both --- that is, which might
          contain both numbers and alpha characters (like a licence plate).

          In  this case, put  "MISC" in slot 1.   You can  only have one of
          these, however.

          If you have an index, but put  "SOFTSEEK" in slot 1, or don't put
          anything in slot  1, a softseek will  be generated.  This  allows
          you to  type in progressive  search information, during  which it
          attempts to find the closest match.

          The final  option is to  have an indexed  file (or not),  but put
          "OTHER" in index slot1.  This generates a browse box in which the
          first touched alpha or numeric key starts an edit (and places the
          key into the first editable field).

          IMPORTANT NOTE!

          When working on your  index in the data dictionary,  don't forget
          to return to  your .WW and go  to local data definitions  and ADD
          the index to your database.  This one's easy to miss,  and if you
          forget, the system will crash spectacularly (since it assumes you
          knew what you were doing -- silly it).   I'm pointing this out in
          several  places because  it's  something I  always  forget to  do
          myself (and curse the template for it).


                                          32







          *****************************************************************

          Exclusive Keys

          Many times you  wish a database to have an exclusive key --- that
          is, you  wish each  key field to  be unique.   Setting  UNIQUE on
          insures that the index is  unique, but does not prevent you  from
          duplicating keys.

          By putting the word UNIQUE in index slot  3 of the FIRST index of
          a database, the  system will automatically prevent  duplicate key
          entries.  If you want to allow  duplicate keys, don't include the
          word UNIQUE in this slot (simple!).

          If your key field is the FIRST  field in the ENTRY screen, and is
          marked as INPUT, then a slightly  different scenario takes place.
          When inserting records, you will be allowed to  enter information
          into  this field.   If it matches  a key value, you  are taken to
          that record for editing.   If not, you are then  allowed to enter
          all the rest of the information on the ENTRY screen (see DEMO for
          an example).
































                                          33








          DEFAULT HELP SYSTEM

          In an  effort to bring some sort of uniformity to my programming,
          I have worked out what is, for me, an ideal help system.  

          The  default  context sensitive  help  system  will automatically
          sense  where  it  is, and  look  for  a help  topic  in  the help
          database.  If the topic is not there, it will ask you if you wish
          to generate help  for that  topic.   If you answer  yes, you  can
          input  the information  you want,  press F7  and save  it.   This
          allows you to either write the documentation on the fly after the
          program is  compiled, or to  allow your users to  write their own
          help screens. As this latter option is becoming more popular (not
          to mention  timesaving for  us programmers)  you will  find it  a
          welcome addition to the system.

          There is  also a  "hidden door" into  editing previously  written
          help screens.   If you press  CTRL-RETURN, you are  placed in  an
          edit mode on the help screen.   You can disable this hidden  door
          (it only exists in one function, "MFUNC"), or leave it alone.   I
          personally like it, as it is not  apt to be hit accidentally, and
          yet allows you  easy editing  of the compiled  system. (F7  exits
          with save, Esc exits without saving).

          If you want  the template to build  the help system for  you, you
          can simply leave it  alone.  It will  generate the database,  and
          all  the appropriate  calling keys  from the  various  fields and
          boxes and menu choices.  You don't need to lift a finger.

          If, however, you  want to lift  fingers (more than one,  please),
          you can override  the defaults I built  in.  It  isn't difficult,
          and this is a free country.

          The default help system consists of two parts:   the special help
          database, and the calling program code.  This template will write
          the calling code for you (assuming you follow all the rules). The
          example of the special  help database is included with  this ARC.

          Basically,  the  database  needs to  have  the  following minimum
          structure:

          FIELD TYPE       PURPOSE
          alphanumeric     Topic to be searched for (any length you want)
          memo             What is displayed in help box

          Each topic  of the help database can  have a memo as  long as you
          wish (well, actually you're limited to 64K, but as this works out
          to about 40 "pages" of information, you're  going to have to be a
          lot wordier than I am to exceed this limit). 



                                          34







          The memo field can be generated with MEMOEDIT, or with the system
          itself  (see  above).   The  database  should be  indexed  on the
          alphanumeric topic.

          The  help routine is passed the parameter  which is the topic you
          want help  on.  This  is generated  automatically in the  case of
          boxes (the system uses the name of the box itself) or you can put
          the  topic in slot 3.   You can  put the topic in  BOX slot 3 for
          each option  in a  menu box.   In  a field (during  a READ),  the
          system uses the  field name as the  search topic default,  or you
          can put the topic in field slot 3.  With a menu item, the default
          is the wording of the menu option, or you can put  (in box.slot3)
          the topic you want.

          If you  include a  box with a  READ-ONLY MEMO  field in  it (just
          one), and call it DF_HELP, the system will use it as your helpbox
          and use that  box's colors and parameters.  If you leave this box
          out, it will write my defaults.  The placement of the  MEMO field
          in  the  box  (offset  from  the  top and  side)  determines  the
          placement of the memo  when it is displayed (makes  sense, huh?).
          If you use  any other  database other than  mine (with  different
          field names), you must have your own memo help box.

          You also  must have a  HELPINDEX() box, which contains  a list of
          all  the  topics (basically,  just a  browse  box with  the topic
          field). 

          If you don't have  this, the system will automatically  write it,
          but if  you  have the  DF_HELP box  above without  this box,  the
          system will get very confused, possibly wandering  away from home
          and  not phoning  or sending  a postcard.   Either have  both, or
          none.    This  index  box  will  enable  the  user  to  get  more
          generalized  help  when  they  press  F1  twice  at  any  context
          sensitive help spot.  You can also allow them to call it directly
          (see DEMO.WW).

          The system writes a file called  WANTED.HLP, which is basically a
          listing of all the  help topics you have  specified (in the  .WW,
          from  boxes or fields).   This can  serve as a  starting point to
          write the help you need.

          All of this  sounds (to me) much  more complicated than it  is in
          practice, so I would advise you to examine DEMO.WW closely to see
          how  it  works.    Once  it  is  set  up,  it  is  a  consistent,
          informative,   easy  to  use  system  that  users  seem  to  find
          worthwhile.    The beauty  is  that  users can  page  forward and
          backward through tons of info, and you can always add help to the
          system after it has been compiled, and even allow the user  to do
          so.




                                          35








          SYSTEM WIDE FUNCTIONS

          There are a  few goodies tossed in  system wide.  I  mention them
          here  because  you  can  take  advantage  of  them  in  your  own
          procedures and functions, and  because I can't think of  a better
          place.

          MESSAGING

          There is a function  called MESSAGES which can be  used anywhere.
          Basically, it puts a  message in the MESSY box (which  you either
          defined  or used  my  system default  as the  bottom line  of the
          screen).  It as the following parameters:

          TYPE, MESSAGE, PAUSE, ANSWER, VALUE, BLINK

          TYPE -- Either 1,2,3 or 4
            
                    Type 1 pops up the message, pauses for PAUSE, and then
                    clears and returns.

                    Type 2 pops up the message, and gets the value in
                    VALUE, with a picture statement using PAUSE.  This is
                    useful for all queries.

                    Type 3 pops up the message and then returns (without
                    clearing it).

                    Type 4 pops up MESSAGE, and waits for you to press any
                    key.  Good debugging tool, among other things.

          Specifying .t. as  the BLINK parameter  will cause the system  to
          blink the message.

          The real beauty of MESSAGES  is that it is benign to  the rest of
          the system, as so far as colors and alias go.

          ERROR SYSTEM

          I incorporated the error handling system suggested by Rick Spence
          in his excellent  programming guide.   It will  handle all  major
          system errors by playing the dirge,  and putting the system error
          in MESSY.

          It also writes the system error in a file called ERRS.ERR.

          The kinds of errors this thing traps are usually not recoverable,
          except perhaps for divide by zero.




                                          36








          RELATIONSHIPS

          Just as in  real life, relationships  in database structures  are
          not always easy.  Prior versions of this template would correctly
          display related database  information in an entry  or browse box,
          for example, but  be unable  to handle  related databases  called
          from an entry to a browse.

          This version of the template should now correctly handle those
          relationships.  Specifically, the situation often occurs that you
          want to have a main database displayed in an entry box that has a
          related  database that you wish to  pop up in a  browse box.  For
          example,  you  have   a  membership   database  that,  for   each
          membership, contains a list of names attached to that membership.
          You  would  like the  main entry  box  to allow  the edit  of the
          general membership information, and  then pop up a browse  box to
          allow the entry of additional people to that membership.

          As long  as your relationships  are properly set  up in the  data
          dictionary, this template  will handle that automatically.   Just
          have  the  browse  box called  as  normal  (via  function key  or
          whatever) and it will work, showing  only those records that meet
          the related criteria to the main database.

          Additionally, you  may want to have the main entry box display as
          many of the related records as it can as you page through it.  To
          do  this, simply  make a  DISPLAY only  box by  putting the  word
          "DISPLAY" in slot1, the name of  the entry box in slot2, and  the
          field or  fields you wish displayed inside  the box (I would make
          it no border just for neatness, but  it's up to you).  As long as
          you only have fields from the  related database inside the browse
          box, it will work correctly -- (see DEMO2.WW for example).

          There is one caveat.  Most  importantly, make sure your secondary
          database  has its indexes  set in the  same order as  in the data
          dictionary. 
















                                          37








          CODE INSERTION

          Often times there is a need to call a procedure or function which
          cannot  be easily defined using the screen  system.  In the past,
          programmers would take code generated  by templates and modify it
          by  hand.  THIS  IS A NO-NO!   Modifying  your template generated
          code is  suicide.  It is the road to  ruin.  Throw away the devil
          editor and get on your hands and knees...

          Sorry, got carried away.  But  really, once you modify the source
          code, then you can  no longer simply regenerate the  program when
          changes are needed.   Yet you  often need to incorporate  outside
          stuff.  What's a programmer to do?

          This system allows  for the  inclusion of  outside functions  and
          procedures at nearly every important point.  To do this, you need
          to do  three  simple things.    First, you  should put  all  your
          outside functions and  procedures into one  file.  Let's call  it
          TEST.UDF, for example.  Now you put  the name of this file in the
          SYSTEM box and...

          Wait a minute!   What  system box?   Okay,  the SYSTEM  box is  a
          special  box you make up and  put anywhere.  The only requirement
          is that it be named SYSTEM. 

          In  slot  2  of  the  SYSTEM  box,  you  put  the  name  of  your
          Procedure/Functions file,  in this  case TEST.UDF.   This is  now
          assumed to be in the same directory into which you are generating
          your program file.

          The finally step towards calling your outside functions and procs
          is to tell the template where you want them inserted (this sounds
          painful, but  the template is used to  it).  To do  this, we take
          advantage of... (Ta Dah!) The Attached Option Box.

          THE ATTACHED OPTION BOX

          Okay, boys  and girls, this is  an important concept, and  one we
          will make great use of,  so pay attention.  To every box  you can
          "attach" an option box.  This  is a single option box, more  than
          one line "tall" (so that it won't be confused with a menu option)
          that either resides "in" the box  (directly contiguous, or on top
          of) and  wholly contained within  the box  it lives in,  or (much
          easier) bears the name of it's parent box in box slot 2.

          These  boxes  are not  marked as  popup,  and won't  be generated
          anywhere.   You  do need  to make  sure,  however, that  they ARE
          options.  If you  have any questions about this, see DEMO2, where
          there is an option box or two, along with descriptive comments.



                                          38







          Now that  we have an attached option box, what can we do with it?
          Well, we can use it to tell the system to insert our outside code
          and functions, that's  what!  (We can  do more, too, but  this is
          covered in the Entry and Browse box explanations, above).

          In this  option box, in  the option  action lines (F7  and revise
          option),  we have five  lines in which to  indicate to the system
          where  we want  our code inserted  in the  box function.   We can
          choose up to five different places.

          One example should suffice.

          A common occurrence is that during the edit process, right before
          you  REPLACE or INSERT  a record, that  you need to  perform some
          external calculations or routine not easily specified in a screen
          type box.  In this case, you could simply, in the Attached option
          box of the entry or browse  screen, include an option action line
          that read like this:

          "EDIT DO somegreatprocedure"
          (without the quotes, of course)

          The keyword EDIT  tells the system to insert the rest of the line
          (DO somegreatprocedure) into  the EDIT process, right  before the
          record  is  REPLACEd.   Then  it  will call  the  procedure which
          resides in your outside procedure file.   Functions can be called
          the   same  way,  even  with  passed  parameters.    The  outside
          procedure/function file  will be  included in  the .PRG file,  so
          everything is in one place.

          Right now there are nine places supported by keywords:

          EDIT           Inserts  line  immediately   before  a  record  is
                         replaced

          READ           Inserts line immediately before a  READ on edit or
                         insert

          INSERT         Inserts line immediately before record is inserted

          CHANGE         Inserts line  immediately after record  is changed
                         (edited or inserted)

          RETURN         Inserts line immediately after box is  erased from
                         screen.

          BEGIN          Inserts line right after box is drawn on screen.

          END            Inserts  line  right  before  box is  erased  from
                         screen.



                                          39







          LOOP           Inserts  line before  each record  advances  in an
                         entry box, or during the record change of a browse
                         box.

          DELETE         Inserts  line  immediately before  record deleting
                         procedure.  If you want  to skip the normal delete
                         procedure, have your code initiate a BREAK.

          In addition, you can have the  special function keys call outside
          procedures you have written during the box call.  To do this, you
          simply  put  the  key  you  want,  along  with  the  function  or
          procedure.

          F(2-10)        Inserts code called by the Special function key
                         specified.  For example, you could say F5 Do
                         something clever, and it would be executed within
                         that box with the special function key.

          More places will be added as demand occurs.  You can include more
          than one place in  an option box, up to  the total of five.   You
          can also  have more than one thing happen  at the place by simply
          calling the word twice or more (see QUERY.WW for example).

          You can also attach an option to the SYSTEM box, so that the code
          will be executed prior or after MAINMENU().  Look at DEMO2.WW  to
          see an  example of code insertion  in MAINMENU that  calls a LOGO
          box before the system begins.

          [Lots more examples  and explanations  to be added  here in  6.0.
          You're probably getting  sick of reading  this by now, so  go and
          send your form in.]






















                                          40








          LARGE SCALE SYSTEMS

          UI is a  strange beast, with  its memory allocation problems  and
          all, and there will be times when you can't put all the boxes for
          one  system on the screen at one time.  Also, there will be times
          when  you  just  don't  want to  (for  ease  of  eye  strain, for
          example).

          The template supports  multiple .WW files.  The calling procedure
          is simple:  just put  the name  of the  NEXT .WW  file (with  .WW
          extension) in box slot 1 of the SYSTEM box.  Every .WW that calls
          another .WW has its own SYSTEM box.  The LAST BOX in the line has
          a system box which has the word "END" in box slot 1.

          You  might read the above again to  note the change from previous
          versions (I'll  give you a  hint: it's  the last sentence  in the
          paragraph).

          You  can chain  as  many screens  as  you'd like,  but  there are
          several caveats involved.   First,  you must make  sure that  all
          boxes which call  other boxes  are called properly.   That  means
          that any boxes that call other boxes must be on the screen at the
          same time together (particularly PICK boxes).  If your menus call
          boxes which  aren't  on the  screen  at the  time,  you must  put
          parenthesis  following  the boxname  (i.e.  test()), so  that the
          system will call the  box properly (but this won't work with PICK
          boxes  --- attend  my  seminar  for details  on  how  to do  this
          properly or wait until I finish these docs).

          If you need to  include a function or procedure file  at the end,
          the  name must be in a  system box slot 2  of the LAST called .WW
          file.

          All of  your .WW  files should  share the  same data  dictionary.
          This is because all files  are open at the start of  the .PRG (in
          the first .WW).   The system will look for your  .WW files in the
          .WW directory (right, I know, but some people HAVE to be told).

          The FIRST BOX in the line should contain MAINMENU.  This is so it
          will  clear  out the  temporary  files, "PICK.ME"  and "MEMVALID"
          properly.  (Don't worry if you  don't understand that sentence --
          it isn't one of my favorites, either).

          Finally,  because the template writes the message line first, you
          must have  "MESSY" in your  first .WW, otherwise  it will  use my
          defaults.  The "DF_HELP"  and "HELPINDEX" boxes should be  in the
          FIRST .WW  (or the system will use my  defaults and then tell you
          during the link that those functions are defined twice).




                                          41








          UI behaves  strangely with  memory.   In order  to compile  large
          systems,  you  must  usually  start  from scratch,  memory  wise.
          Merely Zapping the system, or loading in your first screen is not
          enough if you have been  doing other things in  UI.  In order  to
          play it safe (or when you get a memory error), reboot UI from the
          beginning before compiling a large system,  and make it the first
          thing you  do.   Or run  it from  the command  line (see  earlier
          discussion so many chapters ago I've lost count).

          OUT OF MEMORY

          For  those of  you suffering from  Altzenheimer's, or  just still
          having  problems  with  large systems,  we  now  present  --- the
          subsystem!

          You  can  now  generate  subsystems  from  ALLCLIP.     What's  a
          subsystem?  It's  any system which  does not contain the  startup
          code and system functions.  These  subsystems can then be chained
          together as part of a larger system.

          Generating a subsystem is easy (some might say TOO easy), but not
          as easy as it once was (isn't that  true of most things in life?)
          First of all,  you must ERASE  the temporary files "PICK.ME"  and
          "MEMVALID" -- they  usually live in your UI  directory.  Then you
          generate your programs from the .WWs one at a time.  The last .WW
          you generate should be the one  containing MAINMENU, but this has
          to have a SYSTEM  box also which contains the word  "END" in slot
          1.  That way, the "PICK.ME" and "MEMVALID"  files will be written
          properly  to it.  If you have  ANY SYSTEM boxes in any other .WWs
          than the last  one, you must put  the word "ALONE" in  SYSTEM box
          slot 1.

          Thus you could generate a mainmenu  system with function calls to
          all of your subsystems, and then  compile the mainmenu system and
          all the associated subsystems, and link them all together.

          The same warnings given above in chaining .WW files apply to this
          subprogram process: namely, make sure  all programs use the  same
          Data Dictionary, make sure all called boxes are  on the screen or
          explicitly specified, and make  sure all PICK boxes are  there to
          be called by the right entry boxes.  There is one  other warning:
          make sure your  explicit exits (option  called exits) from  menus
          use the word  "EXIT" rather  than "RETURN", or  the screen  won't
          redraw properly.

          Following these instructions carefully, you  can compile as large
          a system as you'd like.





                                          42








          OPEN FILES?

          One more  problem you might encounter  if you make  a system that
          has a lot of open files is the "OPEN FILE ERROR".

          Most of you Clipper programmers are old  hat at this, but for the
          benefits of the newcomers,  let me state that Clipper  allows you
          virtually unlimited amounts  of files open  at one time (this  is
          one reason  why  more  dentists prefer  Clipper  than  the  other
          leading compiler -- the F word  (Foxbase) -- among those dentists
          expressing a preference).   More files open at once allow  you to
          do all those  wonderful things like  PICK boxes and help  screens
          that show up (practically) instantly even on a Leading Edge.

          Okay, but there's a catch.  Isn't there always?  You have to make
          sure you  have enough  file handles  in order  to grab  all those
          files you want open (so that you can shake them severely and give
          them a good thrashing).  You do this in two different areas.

          In your  CONFIG.SYS file (this is a file  that lives in your root
          directory and only works for about 1 second out of each day, much
          like a worker  for the State of  Nevada), you need to  change the
          FILES= line to reflect a large number of files, say 60 or more.

          FILES=60

          What if you don't  have this line in your CONFIG.SYS  file?  What
          if you don't have a CONFIG.SYS file?  Boy, you ARE a mess, aren't
          you?   Okay, if  you don't have  a file,  or don't have  a FILES=
          line, just create one.  Use your favorite line editor and add it.

          Next, you  need to  wake up  your AUTOEXEC.BAT  file.   Yep, this
          guy's just like CONFIG.SYS, he works about as little (but they're
          nice files, and you shouldn't leave BIOS without them).  You need
          to set your Clipper parameter to reflect the number of files  you
          want open.  A line like:

          SET CLIPPER=F60

          would do the  trick.  Then just  reboot, and you'll find  you can
          use LOTS of files.











                                          43







          QBE - Query by Example

          Here   it  is,  the   latest  buzz  word   implemented  for  your
          edification.   Actually, QBE is not  a very recent  buzzword.  As
          b-words go, it's  almost passe',  and even your  Aunt Grundy  has
          used a QBE nowadays.

          Still, it's all  here for you to enjoy, use, and generally make a
          bloody nuisance of yourself with.  Perhaps the biggest difference
          between this QBE  and the dozens of others available both as part
          of Clipper libraries  and public domain  offerings is that it  is
          written as a .WW file.

          Why is this important?   Well, because it is a .WW file,  you can
          modify it, examine it,  add to it, get it to  stop working --- in
          short, all the wonderful things you  got into programming for are
          available  to  you  with this  system.    It  embodies the  basic
          philosophy of templates  in general, which  is don't set it  into
          concrete (having said  that, I will  note in passing  that it  is
          ALSO set  in concrete in  the form of  ALLCLIP.LIB, but only  for
          those of you without access to LIB.EXE.  Read on).

          As a template compilable system, QUERY.WW allows the same ease in
          modification you  have with your  own .WW files.   One example of
          this is that I  am going to continue to work,  modify, and expand
          this  system, and  make  such changes  available  to everyone  by
          simply posting the .WW.   I would hope that any of you  out there
          who play  around with this  and make  it better will  follow this
          example.  

          Okay,  enough PR, on  with the meat.   In order to  get the QUERY
          system up  and running,  you have two  choices.  First,  the easy
          way.  Select it from DEMO.WW, in the MISC menu section.  

          Okay, now the hard way.  This way you're going to have to compile
          it by yourself.   To do this, you  will have to do  three things.
          First  of all,  you need to  generate from QUERY.WW.   Okay, that
          seems  simple enough, but you need to  make sure that FILT.UDF is
          in the  directory that  you are  going to  generate QUERY.PRG  to
          (FILT.UDF contains the functions I wrote that will be inserted in
          the QUERY.PRG).

          Now what?  Now  you need to compile another .WW  that will invoke
          it.  Take DEMO2.WW (please), and go to the Misc. menu box.  Go to
          the option marked  Query By Example.   Note the asterisks in  the
          option  action slots.  Remove the  asterisks (not the rest of the
          stuff).  Compile this template.

          Okay, now comes the third part.  We need to compile both of these
          .PRGs (separately  or by using  a Clip  file), and then  link the
          .OBJs together.  Linking them together with Plink86 is simple:


                                          44







          Plink86 FI DEMO FI QUERY FI STD [etc. etc.]

          Those  of you  with other  linkers  will have  to look  into your
          manual to find the explicit directions to link more than one file
          together.

          Were there any  of you who did  the second way?   Why bother with
          it?  Well, as I started this chapter out by saying, the advantage
          of having a QBE  in the form of a  .WW is that you can  modify it
          yourself.    When you  took  the  first way  out  (the easy  way,
          suckers), you invoked MY version of  the QBE that is contained in
          the ALLCLIP.LIB.  This may or may not be the one YOU want.

          If  you want  all the  convience  of the  first method,  with the
          flexiblity of the second,  maybe you need to see  a psychiatrist.
          No,  actually, you need to see a  computer retailer where you can
          pick up  a Library  manager.   This isn't  some old  spinster who
          manages the  books  in your  local  repository.   No, this  is  a
          software program  that allows you to shuttle  .OBJs in and out of
          Libraries faster  than you  can say  "that's two  weeks overdue!"
          Library managers are so easy to  use they make ALLCLIP look  like
          rocket science.  For anyone who  thinks they might want to modify
          QUERY.WW (or indeed,  who has a number  of routines they want  to
          manage) a library utility is practically a must.

          It  comes free with the Microsoft  "C" compiler (the professional
          version -- I can't speak for Quick C), so that's why I have one.

          Anyway, let's assume you did  one of the above methods to  invoke
          this QBE.  Now let's try out the QBE action.  The QBE consists of
          two basic parts  (which are, themselves,  divided into two  basic
          parts, and so  on and so on,  neverending, in a  fractal universe
          gone wild.  No, just kidding).

          The first part of the QBE is building  a Report.  Then you can do
          something with the  report (watch your  mouth), like using it  to
          count records, or displaying  or printing those records.   Or you
          can save your  report, and load in another.  God, this is getting
          boring just writing this!

          Anyway, let's  work through  one example,  and I'm  out of  here.
          Pick  Report from the  menu.  Then  pick Query.   You're going to
          build a filter (and those of you familiar with R&R will recognize
          the process.  I  TOLD you I knew a  good idea when I steal  it --
          just let them come at me with their Look and Feel lawsuits).  You
          select the field  from the field  list, select the  conditionals,
          and then enter values (as appropriate) and a connector (or DONE).

          Once  you've built your query, you can  go ahead and do something
          with it.  Exit the Report section, and go to Actions.  Try Count.
          Try Display.  Try Print.  Look at my thumb.


                                          45








          Okay, if  you tried Display  you noticed that  it used  the first
          several fields from the file (all those that would fit).   If you
          want to  look at specific fields,  you can specify  a field list.
          Go back to Report and go  to Fields.  Choose the fields  you want
          to see.  Go back to Actions and try it out.

          You can  also select an  Index (if more  than one exists  for the
          file).   You can  also save  the  Query, Display  List and  Index
          settings in a Report (it will also  save the name of the database
          used to generate it), and call up those settings for later use.

          You can  call the QBE  from your own systems  by simply including
          the Q_START() function call and linking  as above.  The currently
          selected database will be the one queried (you can select the one
          you want right before the call, or try selecting area 0 first. Go
          on, try  it).   Also, make  sure you  have the  Q_REPORT database
          added to  your data dictionary (you can add  it by adding it from
          DEMO.DIC).

          I could talk more about this, but I think you get the idea.  This
          is  just  the first  pass  at this,  and  it will  get  ever more
          sophisticated (particularly in the version you pay money for).






























                                          46








          ERRORS AND TROUBLESHOOTING 

          You need to be careful about how you name your boxes.  This isn't
          a  system problem -- more of a  programming problem.  Because the
          system uses  the box names  both to  generate a function  call as
          well as the  variable used to  store the screen for  restoration,
          you need  to be careful about name  conflicts.  In particular, if
          you name a box with the  same name as a variable, you are  asking
          for  trouble.   You  will notice  this  phenomenon mostly  by the
          strange garbage drawn on the screen when a screen is restored.
            
          I  have attempted to make the  system as idiot proof as possible,
          but box naming  is a good candidate for disaster.  Your entry and
          browse box names need to be unique as to the first  five letters,
          due to the  automatic function  generation, so for  those of  you
          that like fancy common prefixes to all your boxes, watch it.

          When  defining  picture statements  for  fields in  browse boxes,
          don't use  "@!".  "@R"  type pictures WILL  work, however.   Date
          pictures ("@D") also won't work properly (just leave it alone and
          it  will  generate the  proper  picture  for a  date  without you
          messing with it).  The symptom  for these kinds of problems is  a
          browse  box where  the  fields don't  line  up.   Note that  this
          doesn't stop you from entering a  picture clause shorter than the
          length  of your  field  (see browse  box  discussions above,  and
          DEMO.WW for examples).

          The  automatic  file creation  routines  work beautifully  -- but
          they're  not omniscient.   In particular, be  careful of changing
          your data  dictionary by  adding a  field or  changing its  type,
          recompiling the system, and running it  again.  You will probably
          get  a  "undefined  identifier   error",  because  your  original
          database  does  not contain  that field.   Erase  it so  that the
          system  will regenerate  the  database for  you  with the  proper
          fields.

          Other places this system won't stop you from shooting yourself in
          the foot  is if you create  weird boxes (like one  space errors),
          boxes that don't fit into ANY of the above categories, failing to
          include the index files in your local definition, indexes without
          index  expressions.    Let's face  it  guys,  if  this was  truly
          idiotproof,  they wouldn't  need you  to set  it up in  the first
          place.  









                                          47








          I  am  working on  another  template  which will  perform  system
          integrity  checks on your  .WW for the  use of this  template, as
          well as provide  documentation for  your program for  you.   This
          will be available for purchasers of 6.0.

          The system will  attempt to perform  relational integrity to  the
          first level only --- this may be increased if I can get  UI to be
          recursive. Also, make  sure your indexes in your  data dictionary
          are in the proper order (see relational information, above).

          Finally, remember the warnings about system memory  (given in the
          large scale  database systems above).   If you  get a  "Unable to
          create  box"  error, you  can always  break  your system  up into
          smaller pieces to compile.






































                                          48








          QUICK GUIDE


          YOU MUST HAVE: MAINMENU (some kind of box not necessarily a menu)
                         DF_HELP (help box with memo field only)
                         HELPINDEX (browse box with topic only)
                         MESSY (no border 1 line box for messages)

          or system will write defaults (except in the case of MAINMENU
          where it will assume you are compiling a subsystem).

          BOXES:

          Must be popup
          Name of Box is name of function or procedure generated
          Box Description becomes title line
          Box Slots:
               Box Slot 1 = Key which calls this box (F5, RETURN, etc.)/or
                            word invoking certain specific function calls. 

                           Calls currently supported:

                 DISPLAY =  Makes the box a browse once box
                    PICK =  Makes the box a pick type box (if a browse)
                    PACK =  Writes pack routines for all databases
                   INDEX =  Writes indexing routine for all databases
                  NOEDIT =  Writes a no edit browse box

               Box Slot 2 =   Box which  calls  this box,  or  field  which
                              invokes  it  if it  is a  pick  box.   Can be
                              multiple boxes or fields.

               Box Slot 3 =   If not a pick  box, the topic for help.  If a
                              pick  box,  the  value  to be  replaced  when
                              selected.


          OPTION BOX (single in box)

          Color of box will be displayed fields color.

          Box Slot 2 =   Name of parent box (if  absent, position of option
                         to parent box will be used.

          Box Slot 3 =   Conditional expression for display of data in box

          Box Description = Seek condition





                                          49







          Option Actions [5] = Lines which are parsed for keywords and then
          placed into appropriate places in the entry or browse boxes they
          reside in.  Current keywords available are:

          LOOP =    During loop of called box
          EDIT =    Right before REPLACE record
          INSERT =  Right before INSERT record
          READ =    Right before a READ
          CHANGE =  Right after REPLACE in record
          RETURN =  Right after return from box
          BEGIN =   In the function, right after box is drawn but before
                    any thing else
          END =     In the function, right before box is erased
          F(2-10) = During box execution if key is pressed

          MENU OPTIONS
          Option Actions = Code to be done when option is selected (could
          be name of a box)

          Option Message = Line displayed as option is highlighted

          Box Slots:
               Box Slot 1 = Not used
               Box Slot 2 = Not used
               Box Slot 3 = Help topic to be called

          FIELDS
          Field Slots:
               Field Slot 1 = R for replace field  with current value  (SET
                              CARRY) during inserting new records. 

               Field Slot 2 = Name of field to replace value into (see
                              calculated fields). 

               Field Slot 3 = Unused

          INDEX
          Slot 1 =  ALPHA, NUMERIC, SOFTSEEK or MISC depending upon SEEK
                    desired.  If blank then SOFTSEEK will be generated.

          Slot 2 =  Picture for Seek (leave blank if softseek desired)

          Slot 3 =  UNIQUE if index is UNIQUE, or duplicate keys not
                    allowed

          SYSTEM box     (Named "SYSTEM")
          Box slot 1 =   If large scale system, the name of the .WW file to
                         be loaded next. 
          Box slot 2 =   Name of outside file to be included at end of .PRG
                         (if large scale system, must be in the LAST system
                         box that's called)
          Box slot 3 =   Name of KEY to call PICK boxes. 

                                          50







                                        INDEX
          Arrays  . . . . . . . . . . . . . . . . . . . . . . . . . . .  26
          Automatic VALIDS  . . . . . . . . . . . . . . . . . . . . . .  24
          Box.Description . . . . . . . . . . . . . . . . . . . . . . . . 6
          Browse Boxes
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  23
               Calculated fields in . . . . . . . . . . . . . . . . . .  23
               fullscreen editing of  . . . . . . . . . . . . . . . . .  23
               Key Defaults . . . . . . . . . . . . . . . . . . . . . .  25
               large fields in  . . . . . . . . . . . . . . . . . . . .  23
          Color or monochrome . . . . . . . . . . . . . . . . . . . . . . 5
          Command Line Compiling
                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
          Compiled template libraries
               Installation of  . . . . . . . . . . . . . . . . . . . . . 3
          Data dictionary . . . . . . . . . . . . . . . . . . . . . . .  11
          Demo Files
               Using  . . . . . . . . . . . . . . . . . . . . . . . . . . 4
          Display Only Boxes
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  23
          Entry Boxes
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  20
               Attached Options . . . . . . . . . . . . . . . . . . . .  21
               Calling routines . . . . . . . . . . . . . . . . . . . .  20
               Display Colors . . . . . . . . . . . . . . . . . . . . .  21
               Key Defaults . . . . . . . . . . . . . . . . . . . . . .  20
               multiple pages . . . . . . . . . . . . . . . . . . . . .  21
          Exclusive Keys  . . . . . . . . . . . . . . . . . . . . . . .  31
          Full screen browse entry  . . . . . . . . . . . . . . . . . .  24
          Growing hair on your head
               you can't  . . . . . . . . . . . . . . . . . . . . . . . . 7
          Help  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
               Automatic generation . . . . . . . . . . . . . . . . . .  28
               Calling key  . . . . . . . . . . . . . . . . . . . . . .  25
               Specifying in menus  . . . . . . . . . . . . . . . . . .  16
          Including outside routines
                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
          Indexed seeks . . . . . . . . . . . . . . . . . . . . . . . .  30
          Installing the system
                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
          Linking
                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
               Warnings . . . . . . . . . . . . . . . . . . . . . . . . . 5
          Mainmenu Box
               Creating . . . . . . . . . . . . . . . . . . . . . . . . . 9
          Memoedit Boxes
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  19
          Memory Variables
               Use in VALIDs  . . . . . . . . . . . . . . . . . . . . .  29
          Menu Boxes
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  15
          Menu Pick Boxes

                                          51







                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  17
          Message window  . . . . . . . . . . . . . . . . . . . . . . .  16
          Multiuser code
                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
               NETWORK.PRG  . . . . . . . . . . . . . . . . . . . . . . . 3
          Option action slots
               in menus . . . . . . . . . . . . . . . . . . . . . . . .  16
          Option attached box
               Creating accidentally  . . . . . . . . . . . . . . . . .  15
          Option message line . . . . . . . . . . . . . . . . . . . . .  16
          Pick Box
               Global Calling key . . . . . . . . . . . . . . . . . . .  24
          Pick Boxes
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  24
               Calling from multiple fields . . . . . . . . . . . . . .  24
          Plain Boxes
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  18
          Popup
               All boxes tagged as  . . . . . . . . . . . . . . . . . . . 6
          Popup Boxes
               All boxes required to be . . . . . . . . . . . . . . . . . 9
          Seek Conditions
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  21
          Set Carry On
               Emulating  . . . . . . . . . . . . . . . . . . . . . . .  28
          Softseek
               Stopping . . . . . . . . . . . . . . . . . . . . . . . . . 6
          Softseeks
                  . . . . . . . . . . . . . . . . . . . . . . . . . . .  30
          TANSAFFL  . . . . . . . . . . . . . . . . . . . . . . . . . 1, 13
          Things To Come  . . . . . . . . . . . . . . . . . . . . . . . . i
          Transparent shadow box  . . . . . . . . . . . . . . . . . . . . 6
          Triggers  . . . . . . . . . . . . . . . . . . . . . . . . . .  10
               Specifying colors  . . . . . . . . . . . . . . . . . . .  15
          Tutorial
                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

















                                          52
