Guidelines Technical Note 001.           Guidelines Tech Support  27nov93


              Interfacing to External Code from Guidelines
              --------------------------------------------


Whilst many applications may be completely written in the JOT language, many 
developers prefer to write the bulk of their code in C or C++, especially the 
'engines' behind the user interface.

This note demonstrates how external code may be interfaced to Guidelines 
generated code.

In the examples, a simple C++ class (DirList) is used which creates a list of 
the filenames in a specified directory. The directory path is to be specified 
in an entry field, and the list of names is then displayed in a listbox. The
'Refresh' button causes the list to be updated with the current filespec. 

Note that a filespec (including wildcards) is required in the entry field, not 
just a path. The object beeps when the filespec is invalid, or thare are no 
files in the directory. The sample itself is trivial, and does the minimum 
required to demonstrate the interfacing techniques.

----------------------------------------------------------------------------
The first approach (EXTLIST1) uses embedded C++ to create the interface. 
Guidelines is not made aware of any external functions.

1. The DIRLIST.OBJ and DIRLIST.HPP files containing the directory list object 
code and interface definitions are 'registered' with Guidelines, by adding 
them as an external file group. (Edit Menu, External Files... option).

When this is done, Guidelines emits a 

 #include "DIRLIST.HPP"

line in the generated code (.CPP), and places a reference to the DIRLIST.OBJ 
in the makefile (.MAK). 

The LIB and INCLUDE variables in the "Paths" section of the Environments 
dialog can be set to point to these files if they are not in the standard 
Guidelines directories (GUIDE\SYS).


2.  The interface code is placed in one code module, called RefreshList. This 
is a mixture of JOT and C++. The C: at the start of a line causes Guidelines 
to pass the following code straight through into the generated output, and no 
syntax checking is performed.


VOID RefreshList()

    STRING Item
    SHORT  ItemCount

    Frame1.Listbox1.ClearItems ()

C:  DirList *List = new DirList(DirPath);
C:  ItemCount = List->GetCount();
    Frame1.Msg.Text = Str(ItemCount)

C:  for (int i = 0; i < ItemCount; i++)
C:      {
C:      Item = *List->ReadItem(i);
        Frame1.Listbox1.AppendItem (Item)
C:      }

end


Notes:

The function creates a local instance of the DirList object, queries how many 
entries it contains, then appends these seqentially to the list in the 
list box. Note:

 - The directory path is held in a global variable called DirPath.

 - The DirList class uses the Guidelines String class, making the interfacing 
   easier.

 - The DirList object is destroyed when it goes out of scope at the end of 
   the function.


The files for this example are:

 EXTLIST1.GUI    - Guidelines User Interface definition
 DIRLIST.CPP     - C++ Directory list class code
 DIRLIST.HPP     - C++ Directory list class definition
 EXTIF.MAK       - Nmake Makefile to create external obj file

DIRLIST.OBJ is created from the CPP files, externally to Guidelines, but 
using the same compiler switches as defined in the Guidelines environment.

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

The second approach (EXTLIST2) requires no embedded C/C++, but uses instead 
the "External Functions" facility of Guidelines.

1. C wrapper functions for the member functions to be called are written. 
This is necessary because Guidelines/JOT doesn't currently support 
definitions of objects, so the interface must use a C syntax.

In the example, these are placed in the DIRINT.CPP file. This is then 
compiled into DIRINT.OBJ, and registered (along with the corresponding 
DIRINT.HPP file) as an external file.

 String ReadList (ULONG List, short Item);
 short  ListLen(ULONG List);
 short  UpdateList (ULONG List, String DirName);
 void   DestroyList(ULONG List);
 ULONG  InitList (String DirName);


2. External Function definitions are added to the External Functions module 
within the Action Editor. This makes Guidelines aware of then, and they 
become usable within JOT.

 functions
    LONG   InitList(STRING)
    VOID   DestroyList(LONG)
    SHORT  UpdateList(LONG, STRING)
    SHORT  ListLen(LONG)
    STRING ReadList(LONG, SHORT) 
 end


3. The RefreshList() function, written in JOT, calls the functions in an 
appropriate order whenever the list is to be refreshed:

        
VOID RefreshList()

    STRING Item
    SHORT Counter

    Frame1.Listbox1.ClearItems ()
    UpdateList(List, DirPath)
    
    Counter = ListLen(List)
    Frame1.Msg.Text = Str (Counter)    

    while Counter > 0
        Counter = Counter - 1
        Item = ReadList (List, Counter)
        Frame1.Listbox1.AppendItem (Item)
    endwhile
end


Notes:

Because pointers cannot currently be declared within Guidelines as
global variables, the List variable is declared as a LONG in "Global
Variables". The InitList function in DIRINT.CPP returns the new
instance of the DirList class cast as a ULONG. The access functions
address the object via this LONG value passed to them (it acts as a handle
for the object).

In this example, only one instance of the DirList class is created (at 
application startup), and the same instance refreshes its list each time. 
This contrasts with the previous example, where a new instance is created and 
destroyed each time (which could also be done).

The files for this example are:

 EXTLIST2.GUI    - Guidelines User Interface definition
 DIRLIST.CPP     - C++ Directory list class code
 DIRLIST.HPP     - C++ Directory list class definition
 DIRINT.CPP      - C Wrapper functions
 DIRINT.HPP      - C Wrapper function prototypes
 EXTIF.MAK       - Nmake Makefile to create external obj files

DIRLIST.OBJ and DIRINT.OBJ are created from the CPP files, externally to 
Guidelines, but using the same compiler switches as defined in the Guidelines 
environment. Use NMAKE -f EXTIF.MAK  and ensure that your INCLUDE environment
variable includes the GUIDE\SYS directory (for guirun.h).
